Merge branch 'stable-3.0'
* stable-3.0: Update NoteDb documentation for 3.0 NotificationEmail: Fix eliding project name without slash Clean up NotificationEmailTest Update links to Google individual and corporate CLA pages Bazel: Remove iteration over depset dev-bazel: Fix section title sequence Elasticsearch: Exclude types from V7 which deprecates them Print test errors by default Send an email notification when the HTTP password is deleted or changed Send email notification when SSH key or GPG key is removed StaticModule: Remove unused GERRIT_UI_COOKIE Show progress on number of users migrated during schema migration 146 Additional changes in this merge to adapt to master: - Move changes in dev-contributing.txt to dev-cla.txt Change-Id: I5b9c2e454c551ccfcbd2ecaa1653044cc9597382
This commit is contained in:
@@ -20,8 +20,10 @@ import com.google.gerrit.server.mail.send.AddKeySender;
|
||||
import com.google.gerrit.server.mail.send.AddReviewerSender;
|
||||
import com.google.gerrit.server.mail.send.CommentSender;
|
||||
import com.google.gerrit.server.mail.send.CreateChangeSender;
|
||||
import com.google.gerrit.server.mail.send.DeleteKeySender;
|
||||
import com.google.gerrit.server.mail.send.DeleteReviewerSender;
|
||||
import com.google.gerrit.server.mail.send.DeleteVoteSender;
|
||||
import com.google.gerrit.server.mail.send.HttpPasswordUpdateSender;
|
||||
import com.google.gerrit.server.mail.send.MergedSender;
|
||||
import com.google.gerrit.server.mail.send.RegisterNewEmailSender;
|
||||
import com.google.gerrit.server.mail.send.ReplacePatchSetSender;
|
||||
@@ -37,8 +39,10 @@ public class EmailModule extends FactoryModule {
|
||||
factory(AddReviewerSender.Factory.class);
|
||||
factory(CommentSender.Factory.class);
|
||||
factory(CreateChangeSender.Factory.class);
|
||||
factory(DeleteKeySender.Factory.class);
|
||||
factory(DeleteReviewerSender.Factory.class);
|
||||
factory(DeleteVoteSender.Factory.class);
|
||||
factory(HttpPasswordUpdateSender.Factory.class);
|
||||
factory(MergedSender.Factory.class);
|
||||
factory(RegisterNewEmailSender.Factory.class);
|
||||
factory(ReplacePatchSetSender.Factory.class);
|
||||
|
||||
150
java/com/google/gerrit/server/mail/send/DeleteKeySender.java
Normal file
150
java/com/google/gerrit/server/mail/send/DeleteKeySender.java
Normal file
@@ -0,0 +1,150 @@
|
||||
// Copyright (C) 2019 The Android Open Source Project
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package com.google.gerrit.server.mail.send;
|
||||
|
||||
import com.google.common.base.Joiner;
|
||||
import com.google.gerrit.exceptions.EmailException;
|
||||
import com.google.gerrit.extensions.api.changes.RecipientType;
|
||||
import com.google.gerrit.extensions.restapi.AuthException;
|
||||
import com.google.gerrit.mail.Address;
|
||||
import com.google.gerrit.server.IdentifiedUser;
|
||||
import com.google.gerrit.server.account.AccountSshKey;
|
||||
import com.google.gerrit.server.permissions.GlobalPermission;
|
||||
import com.google.gerrit.server.permissions.PermissionBackend;
|
||||
import com.google.gerrit.server.permissions.PermissionBackendException;
|
||||
import com.google.inject.assistedinject.Assisted;
|
||||
import com.google.inject.assistedinject.AssistedInject;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class DeleteKeySender extends OutgoingEmail {
|
||||
public interface Factory {
|
||||
DeleteKeySender create(IdentifiedUser user, AccountSshKey sshKey);
|
||||
|
||||
DeleteKeySender create(IdentifiedUser user, List<String> gpgKeyFingerprints);
|
||||
}
|
||||
|
||||
private final PermissionBackend permissionBackend;
|
||||
private final IdentifiedUser callingUser;
|
||||
private final IdentifiedUser user;
|
||||
private final AccountSshKey sshKey;
|
||||
private final List<String> gpgKeyFingerprints;
|
||||
|
||||
@AssistedInject
|
||||
public DeleteKeySender(
|
||||
EmailArguments ea,
|
||||
PermissionBackend permissionBackend,
|
||||
IdentifiedUser callingUser,
|
||||
@Assisted IdentifiedUser user,
|
||||
@Assisted AccountSshKey sshKey) {
|
||||
super(ea, "deletekey");
|
||||
this.permissionBackend = permissionBackend;
|
||||
this.callingUser = callingUser;
|
||||
this.user = user;
|
||||
this.gpgKeyFingerprints = Collections.emptyList();
|
||||
this.sshKey = sshKey;
|
||||
}
|
||||
|
||||
@AssistedInject
|
||||
public DeleteKeySender(
|
||||
EmailArguments ea,
|
||||
PermissionBackend permissionBackend,
|
||||
IdentifiedUser callingUser,
|
||||
@Assisted IdentifiedUser user,
|
||||
@Assisted List<String> gpgKeyFingerprints) {
|
||||
super(ea, "deletekey");
|
||||
this.permissionBackend = permissionBackend;
|
||||
this.callingUser = callingUser;
|
||||
this.user = user;
|
||||
this.gpgKeyFingerprints = gpgKeyFingerprints;
|
||||
this.sshKey = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void init() throws EmailException {
|
||||
super.init();
|
||||
setHeader("Subject", String.format("[Gerrit Code Review] %s Keys Deleted", getKeyType()));
|
||||
add(RecipientType.TO, new Address(getEmail()));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean shouldSendMessage() {
|
||||
if (user.equals(callingUser)) {
|
||||
// Send email if the user self-removed a key; this notification is necessary to alert
|
||||
// the user if their account was compromised and a key was unexpectedly deleted.
|
||||
return true;
|
||||
}
|
||||
|
||||
try {
|
||||
// Don't email if an administrator removed a key on behalf of the user.
|
||||
permissionBackend.user(callingUser).check(GlobalPermission.ADMINISTRATE_SERVER);
|
||||
return false;
|
||||
} catch (AuthException | PermissionBackendException e) {
|
||||
// Send email if a non-administrator modified the keys, e.g. by MODIFY_ACCOUNT.
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void format() throws EmailException {
|
||||
appendText(textTemplate("DeleteKey"));
|
||||
if (useHtml()) {
|
||||
appendHtml(soyHtmlTemplate("DeleteKeyHtml"));
|
||||
}
|
||||
}
|
||||
|
||||
public String getEmail() {
|
||||
return user.getAccount().getPreferredEmail();
|
||||
}
|
||||
|
||||
public String getUserNameEmail() {
|
||||
return getUserNameEmailFor(user.getAccountId());
|
||||
}
|
||||
|
||||
public String getKeyType() {
|
||||
if (sshKey != null) {
|
||||
return "SSH";
|
||||
} else if (gpgKeyFingerprints != null) {
|
||||
return "GPG";
|
||||
}
|
||||
throw new IllegalStateException("key type is not SSH or GPG");
|
||||
}
|
||||
|
||||
public String getSshKey() {
|
||||
return (sshKey != null) ? sshKey.sshPublicKey() + "\n" : null;
|
||||
}
|
||||
|
||||
public String getGpgKeyFingerprints() {
|
||||
if (!gpgKeyFingerprints.isEmpty()) {
|
||||
return Joiner.on("\n").join(gpgKeyFingerprints);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setupSoyContext() {
|
||||
super.setupSoyContext();
|
||||
soyContextEmailData.put("email", getEmail());
|
||||
soyContextEmailData.put("gpgKeyFingerprints", getGpgKeyFingerprints());
|
||||
soyContextEmailData.put("keyType", getKeyType());
|
||||
soyContextEmailData.put("sshKey", getSshKey());
|
||||
soyContextEmailData.put("userNameEmail", getUserNameEmail());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean supportsHtml() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
// Copyright (C) 2019 The Android Open Source Project
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package com.google.gerrit.server.mail.send;
|
||||
|
||||
import com.google.gerrit.exceptions.EmailException;
|
||||
import com.google.gerrit.extensions.api.changes.RecipientType;
|
||||
import com.google.gerrit.mail.Address;
|
||||
import com.google.gerrit.server.IdentifiedUser;
|
||||
import com.google.inject.assistedinject.Assisted;
|
||||
import com.google.inject.assistedinject.AssistedInject;
|
||||
|
||||
public class HttpPasswordUpdateSender extends OutgoingEmail {
|
||||
public interface Factory {
|
||||
HttpPasswordUpdateSender create(IdentifiedUser user, String operation);
|
||||
}
|
||||
|
||||
private final IdentifiedUser user;
|
||||
private final String operation;
|
||||
|
||||
@AssistedInject
|
||||
public HttpPasswordUpdateSender(
|
||||
EmailArguments ea, @Assisted IdentifiedUser user, @Assisted String operation) {
|
||||
super(ea, "HttpPasswordUpdate");
|
||||
this.user = user;
|
||||
this.operation = operation;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void init() throws EmailException {
|
||||
super.init();
|
||||
setHeader("Subject", "[Gerrit Code Review] HTTP password was " + operation);
|
||||
add(RecipientType.TO, new Address(getEmail()));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean shouldSendMessage() {
|
||||
// Always send an email if the HTTP password is updated.
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void format() throws EmailException {
|
||||
appendText(textTemplate("HttpPasswordUpdate"));
|
||||
if (useHtml()) {
|
||||
appendHtml(soyHtmlTemplate("HttpPasswordUpdateHtml"));
|
||||
}
|
||||
}
|
||||
|
||||
public String getEmail() {
|
||||
return user.getAccount().getPreferredEmail();
|
||||
}
|
||||
|
||||
public String getUserNameEmail() {
|
||||
return getUserNameEmailFor(user.getAccountId());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setupSoyContext() {
|
||||
super.setupSoyContext();
|
||||
soyContextEmailData.put("email", getEmail());
|
||||
soyContextEmailData.put("userNameEmail", getUserNameEmail());
|
||||
soyContextEmailData.put("operation", operation);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean supportsHtml() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -47,6 +47,8 @@ public class MailSoyTofuProvider implements Provider<SoyTofu> {
|
||||
"CommentHtml.soy",
|
||||
"CommentFooter.soy",
|
||||
"CommentFooterHtml.soy",
|
||||
"DeleteKey.soy",
|
||||
"DeleteKeyHtml.soy",
|
||||
"DeleteReviewer.soy",
|
||||
"DeleteReviewerHtml.soy",
|
||||
"DeleteVote.soy",
|
||||
@@ -56,6 +58,8 @@ public class MailSoyTofuProvider implements Provider<SoyTofu> {
|
||||
"Footer.soy",
|
||||
"FooterHtml.soy",
|
||||
"HeaderHtml.soy",
|
||||
"HttpPasswordUpdate.soy",
|
||||
"HttpPasswordUpdateHtml.soy",
|
||||
"Merged.soy",
|
||||
"MergedHtml.soy",
|
||||
"NewChange.soy",
|
||||
|
||||
@@ -131,6 +131,9 @@ public abstract class NotificationEmail extends OutgoingEmail {
|
||||
if (lastIndexSlash == 0) {
|
||||
return projectName.substring(1); // Remove the first slash
|
||||
}
|
||||
if (lastIndexSlash == -1) { // No slash in the project name
|
||||
return projectName;
|
||||
}
|
||||
|
||||
return "..." + projectName.substring(lastIndexSlash + 1);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user