use of com.google.gerrit.server.CurrentUser in project gerrit by GerritCodeReview.
the class ConfirmEmail method apply.
@Override
public Response<?> apply(ConfigResource rsrc, Input input) throws AuthException, UnprocessableEntityException, IOException, ConfigInvalidException {
CurrentUser user = self.get();
if (!user.isIdentifiedUser()) {
throw new AuthException("Authentication required");
}
if (input == null) {
input = new Input();
}
if (input.token == null) {
throw new UnprocessableEntityException("missing token");
}
try {
EmailTokenVerifier.ParsedToken token = emailTokenVerifier.decode(input.token);
Account.Id accId = user.getAccountId();
if (accId.equals(token.getAccountId())) {
accountManager.link(accId, token.toAuthRequest());
return Response.none();
}
throw new UnprocessableEntityException("invalid token");
} catch (EmailTokenVerifier.InvalidTokenException e) {
throw new UnprocessableEntityException("invalid token", e);
} catch (AccountException e) {
throw new UnprocessableEntityException(e.getMessage());
}
}
use of com.google.gerrit.server.CurrentUser in project gerrit by GerritCodeReview.
the class Receive method runImpl.
@Override
protected void runImpl() throws IOException, Failure {
CurrentUser currentUser = session.getUser();
try {
permissionBackend.user(currentUser).project(project.getNameKey()).check(ProjectPermission.RUN_RECEIVE_PACK);
} catch (AuthException e) {
throw new Failure(1, "fatal: receive-pack not permitted on this server", e);
} catch (PermissionBackendException e) {
throw new Failure(1, "fatal: unable to check permissions " + e);
}
AsyncReceiveCommits arc = factory.create(projectState, currentUser.asIdentifiedUser(), repo, null);
try {
Capable r = arc.canUpload();
if (r != Capable.OK) {
throw die(r.getMessage());
}
} catch (PermissionBackendException e) {
throw die(e.getMessage());
}
ReceivePack rp = arc.getReceivePack();
try {
rp.receive(in, out, err);
session.setPeerAgent(rp.getPeerUserAgent());
} catch (UnpackException badStream) {
// we want to present this error to the user
if (badStream.getCause() instanceof TooLargeObjectInPackException) {
StringBuilder msg = new StringBuilder();
msg.append("Receive error on project \"").append(projectState.getName()).append("\"");
msg.append(" (user ");
msg.append(currentUser.getUserName().orElse(null));
msg.append(" account ");
msg.append(currentUser.getAccountId());
msg.append("): ");
msg.append(badStream.getCause().getMessage());
logger.atInfo().log(msg.toString());
throw new UnloggedFailure(128, "error: " + badStream.getCause().getMessage());
}
StringBuilder msg = new StringBuilder();
msg.append("Unpack error on project \"").append(projectState.getName()).append("\":\n");
msg.append(" AdvertiseRefsHook: ").append(rp.getAdvertiseRefsHook());
if (rp.getAdvertiseRefsHook() == AdvertiseRefsHook.DEFAULT) {
msg.append("DEFAULT");
} else {
msg.append(rp.getAdvertiseRefsHook().getClass());
}
msg.append("\n");
IOException detail = new IOException(msg.toString(), badStream);
throw new Failure(128, "fatal: Unpack error, check server log", detail);
}
}
use of com.google.gerrit.server.CurrentUser in project gerrit by GerritCodeReview.
the class OutgoingEmail method sendImpl.
private void sendImpl() throws EmailException {
if (!args.emailSender.isEnabled()) {
// Server has explicitly disabled email sending.
//
logger.atFine().log("Not sending '%s': Email sending is disabled by server config", messageClass);
return;
}
if (!notify.shouldNotify()) {
logger.atFine().log("Not sending '%s': Notify handling is NONE", messageClass);
return;
}
init();
if (messageId == null) {
throw new IllegalStateException("All emails must have a messageId");
}
format();
appendText(textTemplate("Footer"));
if (useHtml()) {
appendHtml(soyHtmlTemplate("FooterHtml"));
}
Set<Address> smtpRcptToPlaintextOnly = new HashSet<>();
if (shouldSendMessage()) {
if (fromId != null) {
Optional<AccountState> fromUser = args.accountCache.get(fromId);
if (fromUser.isPresent()) {
GeneralPreferencesInfo senderPrefs = fromUser.get().generalPreferences();
CurrentUser user = args.currentUserProvider.get();
boolean isImpersonating = user.isIdentifiedUser() && user.isImpersonating();
if (isImpersonating && user.getAccountId() != fromId) {
// set up correctly.
throw new EmailException(String.format("User %s is sending email from %s, while acting on behalf of %s", user.asIdentifiedUser().getRealUser().getAccountId(), fromId, user.getAccountId()));
}
if (senderPrefs != null && senderPrefs.getEmailStrategy() == CC_ON_OWN_COMMENTS) {
// Include the sender in email if they enabled email notifications on their own
// comments.
//
logger.atFine().log("CC email sender %s because the email strategy of this user is %s", fromUser.get().account().id(), CC_ON_OWN_COMMENTS);
add(RecipientType.CC, fromId);
} else if (isImpersonating) {
// If we are impersonating a user, make sure they receive a CC of
// this message regardless of email strategy, unless email notifications are explicitly
// disabled for this user. This way they can always review and audit what we sent
// on their behalf to others.
logger.atFine().log("CC email sender %s because the email is sent on behalf of and email notifications" + " are enabled for this user.", fromUser.get().account().id());
add(RecipientType.CC, fromId);
} else if (!notify.accounts().containsValue(fromId) && rcptTo.remove(fromId)) {
// If they don't want a copy, but we queued one up anyway,
// drop them from the recipient lists, but only if the user is not being impersonated.
//
logger.atFine().log("Not CCing email sender %s because the email strategy of this user is not %s but" + " %s", fromUser.get().account().id(), CC_ON_OWN_COMMENTS, senderPrefs != null ? senderPrefs.getEmailStrategy() : null);
removeUser(fromUser.get().account());
}
}
}
// In addition, check if users only want to receive plaintext email.
for (Account.Id id : rcptTo) {
Optional<AccountState> thisUser = args.accountCache.get(id);
if (thisUser.isPresent()) {
Account thisUserAccount = thisUser.get().account();
GeneralPreferencesInfo prefs = thisUser.get().generalPreferences();
if (prefs == null || prefs.getEmailStrategy() == DISABLED) {
logger.atFine().log("Not emailing account %s because user has set email strategy to %s", id, DISABLED);
removeUser(thisUserAccount);
} else if (useHtml() && prefs.getEmailFormat() == EmailFormat.PLAINTEXT) {
logger.atFine().log("Removing account %s from HTML email because user prefers plain text emails", id);
removeUser(thisUserAccount);
smtpRcptToPlaintextOnly.add(Address.create(thisUserAccount.fullName(), thisUserAccount.preferredEmail()));
}
}
if (smtpRcptTo.isEmpty() && smtpRcptToPlaintextOnly.isEmpty()) {
logger.atFine().log("Not sending '%s': No SMTP recipients", messageClass);
return;
}
}
// inbound email replies.
if (!headers.containsKey(FieldName.REPLY_TO)) {
StringJoiner j = new StringJoiner(", ");
if (fromId != null) {
Address address = toAddress(fromId);
if (address != null) {
j.add(address.email());
}
}
// For users who prefer plaintext, this comes at the cost of not being
// listed in the multipart To and Cc headers. We work around this by adding
// all users to the Reply-To address in both the plaintext and multipart
// email. We should exclude any BCC addresses from reply-to, because they should be
// invisible to other recipients.
Sets.difference(Sets.union(smtpRcptTo, smtpRcptToPlaintextOnly), smtpBccRcptTo).stream().forEach(a -> j.add(a.email()));
setHeader(FieldName.REPLY_TO, j.toString());
}
String textPart = textBody.toString();
OutgoingEmailValidationListener.Args va = new OutgoingEmailValidationListener.Args();
va.messageClass = messageClass;
va.smtpFromAddress = smtpFromAddress;
va.smtpRcptTo = smtpRcptTo;
va.headers = headers;
va.body = textPart;
if (useHtml()) {
va.htmlBody = htmlBody.toString();
} else {
va.htmlBody = null;
}
Set<Address> intersection = Sets.intersection(va.smtpRcptTo, smtpRcptToPlaintextOnly);
if (!intersection.isEmpty()) {
logger.atSevere().log("Email '%s' will be sent twice to %s", messageClass, intersection);
}
if (!va.smtpRcptTo.isEmpty()) {
// Send multipart message
addMessageId(va, "-HTML");
if (!validateEmail(va))
return;
logger.atFine().log("Sending multipart '%s' from %s to %s", messageClass, va.smtpFromAddress, va.smtpRcptTo);
args.emailSender.send(va.smtpFromAddress, va.smtpRcptTo, va.headers, va.body, va.htmlBody);
}
if (!smtpRcptToPlaintextOnly.isEmpty()) {
addMessageId(va, "-PLAIN");
// Send plaintext message
Map<String, EmailHeader> shallowCopy = new HashMap<>();
shallowCopy.putAll(headers);
// Remove To and Cc
shallowCopy.remove(FieldName.TO);
shallowCopy.remove(FieldName.CC);
for (Address a : smtpRcptToPlaintextOnly) {
// Add new To
EmailHeader.AddressList to = new EmailHeader.AddressList();
to.add(a);
shallowCopy.put(FieldName.TO, to);
}
if (!validateEmail(va))
return;
logger.atFine().log("Sending plaintext '%s' from %s to %s", messageClass, va.smtpFromAddress, smtpRcptToPlaintextOnly);
args.emailSender.send(va.smtpFromAddress, smtpRcptToPlaintextOnly, shallowCopy, va.body);
}
}
}
use of com.google.gerrit.server.CurrentUser in project gerrit by GerritCodeReview.
the class ProjectWatch method add.
private void add(Watchers matching, Project.NameKey projectName, NotifyConfig nc) throws QueryParseException {
logger.atFine().log("Checking watchers for notify config %s from project %s", nc, projectName);
for (GroupReference groupRef : nc.getGroups()) {
CurrentUser user = new GroupBackedUser(ImmutableSet.of(groupRef.getUUID()));
if (filterMatch(user, nc.getFilter())) {
deliverToMembers(matching.list(nc.getHeader()), groupRef.getUUID());
logger.atFine().log("Added watchers for group %s", groupRef);
} else {
logger.atFine().log("The filter did not match for group %s; skip notification", groupRef);
}
}
if (!nc.getAddresses().isEmpty()) {
if (filterMatch(null, nc.getFilter())) {
matching.list(nc.getHeader()).emails.addAll(nc.getAddresses());
logger.atFine().log("Added watchers for these addresses: %s", nc.getAddresses());
} else {
logger.atFine().log("The filter did not match; skip notification for these addresses: %s", nc.getAddresses());
}
}
}
use of com.google.gerrit.server.CurrentUser in project gerrit by GerritCodeReview.
the class DeleteDraftComments method apply.
@Override
public Response<ImmutableList<DeletedDraftCommentInfo>> apply(AccountResource rsrc, DeleteDraftCommentsInput input) throws RestApiException, UpdateException {
CurrentUser user = userProvider.get();
if (!user.isIdentifiedUser()) {
throw new AuthException("Authentication required");
}
if (!rsrc.getUser().hasSameAccountId(user)) {
// hasSameAccountId check.)
throw new AuthException("Cannot delete drafts of other user");
}
HumanCommentFormatter humanCommentFormatter = commentJsonProvider.get().newHumanCommentFormatter();
Account.Id accountId = rsrc.getUser().getAccountId();
Instant now = TimeUtil.now();
Map<Project.NameKey, BatchUpdate> updates = new LinkedHashMap<>();
List<Op> ops = new ArrayList<>();
for (ChangeData cd : queryProvider.get().enforceVisibility(true).query(predicate(accountId, input))) {
BatchUpdate update = updates.computeIfAbsent(cd.project(), p -> batchUpdateFactory.create(p, rsrc.getUser(), now));
Op op = new Op(humanCommentFormatter, accountId);
update.addOp(cd.getId(), op);
ops.add(op);
}
// Currently there's no way to let some updates succeed even if others fail. Even if there were,
// all updates from this operation only happen in All-Users and thus are fully atomic, so
// allowing partial failure would have little value.
BatchUpdate.execute(updates.values(), ImmutableList.of(), false);
return Response.ok(ops.stream().map(Op::getResult).filter(Objects::nonNull).collect(toImmutableList()));
}
Aggregations