diff options
author | David Pursehouse <dpursehouse@digital.ai> | 2020-04-23 23:00:40 +0000 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2020-04-23 23:00:40 +0000 |
commit | 4727818c8cce856f2bf55381d1f4a0f1b2251426 (patch) | |
tree | 37ea43e328498245936f193a830f1c355efa4647 | |
parent | 72875753665546ae4302da06879a71ea498c0dfe (diff) | |
parent | da2e68bc891c1fdfe646bc2a0ea7723a0a6f4ce2 (diff) |
Merge "Upgrade gwtjsonrpc to 1.12" into stable-2.16
4 files changed, 135 insertions, 10 deletions
@@ -255,9 +255,9 @@ maven_jar( maven_jar( name = "gwtjsonrpc", - artifact = "com.google.gerrit:gwtjsonrpc:1.11", - sha1 = "0990e7eec9eec3a15661edcf9232acbac4aeacec", - src_sha1 = "a682afc46284fb58197a173cb5818770a1e7834a", + artifact = "com.google.gerrit:gwtjsonrpc:1.12", + sha1 = "cade35e5628af56f687d651dd0f43d17d46b20f5", + src_sha1 = "e4c17ec9a453f4d41d5e0e55f7020e5919725b0d", ) maven_jar( diff --git a/java/com/google/gerrit/server/mail/SignedTokenEmailTokenVerifier.java b/java/com/google/gerrit/server/mail/SignedTokenEmailTokenVerifier.java index 66fe07e05f..ba9bff8520 100644 --- a/java/com/google/gerrit/server/mail/SignedTokenEmailTokenVerifier.java +++ b/java/com/google/gerrit/server/mail/SignedTokenEmailTokenVerifier.java @@ -17,9 +17,11 @@ package com.google.gerrit.server.mail; import static com.google.common.base.Preconditions.checkState; import static java.nio.charset.StandardCharsets.UTF_8; +import com.google.common.io.BaseEncoding; import com.google.gerrit.reviewdb.client.Account; import com.google.gerrit.server.config.AuthConfig; import com.google.gerrit.server.mail.send.RegisterNewEmailSender; +import com.google.gwtjsonrpc.common.CheckTokenException; import com.google.gwtjsonrpc.server.SignedToken; import com.google.gwtjsonrpc.server.ValidToken; import com.google.gwtjsonrpc.server.XsrfException; @@ -28,7 +30,6 @@ import com.google.inject.Inject; import com.google.inject.Singleton; import java.util.regex.Matcher; import java.util.regex.Pattern; -import org.eclipse.jgit.util.Base64; /** Verifies the token sent by {@link RegisterNewEmailSender}. */ @Singleton @@ -53,7 +54,7 @@ public class SignedTokenEmailTokenVerifier implements EmailTokenVerifier { try { String payload = String.format("%s:%s", accountId, emailAddress); byte[] utf8 = payload.getBytes(UTF_8); - String base64 = Base64.encodeBytes(utf8); + String base64 = BaseEncoding.base64Url().encode(utf8); return emailRegistrationToken.newToken(base64); } catch (XsrfException e) { throw new IllegalArgumentException(e); @@ -66,14 +67,14 @@ public class SignedTokenEmailTokenVerifier implements EmailTokenVerifier { ValidToken token; try { token = emailRegistrationToken.checkToken(tokenString, null); - } catch (XsrfException err) { + } catch (XsrfException | CheckTokenException err) { throw new InvalidTokenException(err); } if (token == null || token.getData() == null || token.getData().isEmpty()) { throw new InvalidTokenException(); } - String payload = new String(Base64.decode(token.getData()), UTF_8); + String payload = new String(BaseEncoding.base64Url().decode(token.getData()), UTF_8); Matcher matcher = Pattern.compile("^([0-9]+):(.+@.+)$").matcher(payload); if (!matcher.matches()) { throw new InvalidTokenException(); diff --git a/javatests/com/google/gerrit/acceptance/api/accounts/AccountIT.java b/javatests/com/google/gerrit/acceptance/api/accounts/AccountIT.java index b09135d2b7..9846b4c4a6 100644 --- a/javatests/com/google/gerrit/acceptance/api/accounts/AccountIT.java +++ b/javatests/com/google/gerrit/acceptance/api/accounts/AccountIT.java @@ -1091,7 +1091,7 @@ public class AccountIT extends AbstractDaemonTest { @Test @GerritConfig( name = "auth.registerEmailPrivateKey", - value = "HsOc6l+2lhS9G7sE/RsnS7Z6GJjdRDX14co=") + value = "HsOc6l_2lhS9G7sE_RsnS7Z6GJjdRDX14co=") public void addEmailSendsConfirmationEmail() throws Exception { String email = "new.email@example.com"; EmailInput input = newEmailInput(email, false); @@ -1105,7 +1105,7 @@ public class AccountIT extends AbstractDaemonTest { @Test @GerritConfig( name = "auth.registerEmailPrivateKey", - value = "HsOc6l+2lhS9G7sE/RsnS7Z6GJjdRDX14co=") + value = "HsOc6l_2lhS9G7sE_RsnS7Z6GJjdRDX14co=") public void addEmailToBeConfirmedToOwnAccount() throws Exception { TestAccount user = accountCreator.create(); setApiUser(user); @@ -1129,7 +1129,7 @@ public class AccountIT extends AbstractDaemonTest { @Test @GerritConfig( name = "auth.registerEmailPrivateKey", - value = "HsOc6l+2lhS9G7sE/RsnS7Z6GJjdRDX14co=") + value = "HsOc6l_2lhS9G7sE_RsnS7Z6GJjdRDX14co=") public void addEmailToBeConfirmedToOtherAccount() throws Exception { TestAccount user = accountCreator.create(); String email = "me@example.com"; diff --git a/javatests/com/google/gerrit/acceptance/server/mail/SignedTokenEmailTokenVerifierIT.java b/javatests/com/google/gerrit/acceptance/server/mail/SignedTokenEmailTokenVerifierIT.java new file mode 100644 index 0000000000..733511228f --- /dev/null +++ b/javatests/com/google/gerrit/acceptance/server/mail/SignedTokenEmailTokenVerifierIT.java @@ -0,0 +1,124 @@ +// Copyright (C) 2020 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.acceptance.server.mail; + +import static com.google.common.truth.Truth.assertThat; +import static com.google.gerrit.testing.GerritJUnit.assertThrows; + +import com.google.common.io.BaseEncoding; +import com.google.gerrit.acceptance.AbstractDaemonTest; +import com.google.gerrit.server.mail.EmailTokenVerifier; +import com.google.gerrit.server.mail.EmailTokenVerifier.InvalidTokenException; +import com.google.gerrit.server.mail.SignedTokenEmailTokenVerifier; +import com.google.gerrit.testing.ConfigSuite; +import com.google.gwtjsonrpc.server.SignedToken; +import java.nio.charset.StandardCharsets; +import org.eclipse.jgit.lib.Config; +import org.junit.Before; +import org.junit.Test; + +public class SignedTokenEmailTokenVerifierIT extends AbstractDaemonTest { + @ConfigSuite.Default + public static Config defaultConfig() { + Config cfg = new Config(); + cfg.setString("auth", null, "registerEmailPrivateKey", SignedToken.generateRandomKey()); + return cfg; + } + + private SignedTokenEmailTokenVerifier signedTokenEmailTokenVerifier; + + @Before + public void setUp() throws Exception { + signedTokenEmailTokenVerifier = + server + .getTestInjector() + .getBinding(SignedTokenEmailTokenVerifier.class) + .getProvider() + .get(); + } + + /** Test encode */ + @Test + public void encode() throws Exception { + String tokenString = signedTokenEmailTokenVerifier.encode(user.id, user.email); + int index = tokenString.indexOf("$"); + String text = tokenString.substring(index + 1); + String textDecoded = new String(BaseEncoding.base64Url().decode(text), StandardCharsets.UTF_8); + int pos = textDecoded.indexOf(":"); + assertThat(textDecoded.substring(0, pos)).isEqualTo(user.id.toString()); + assertThat(textDecoded.substring(pos + 1)).isEqualTo(user.email); + } + + /** Test decode */ + @Test + public void decode() throws Exception { + String tokenString = signedTokenEmailTokenVerifier.encode(user.id, user.email); + String tokenKey = tokenString.substring(0, tokenString.indexOf("$")); + String text = user.id + ":" + user.email; + String invalidTokenString = + tokenKey + "$" + BaseEncoding.base64Url().encode(text.getBytes(StandardCharsets.UTF_8)); + EmailTokenVerifier.ParsedToken parsedToken = + signedTokenEmailTokenVerifier.decode(invalidTokenString); + assertThat(parsedToken.getAccountId()).isEqualTo(user.id); + assertThat(parsedToken.getEmailAddress()).isEqualTo(user.email); + } + + /** Test token format is wrong(without '$' to split key and text) */ + @Test + public void invalidFormat() throws Exception { + InvalidTokenException thrown = + assertThrows( + InvalidTokenException.class, + () -> signedTokenEmailTokenVerifier.decode("Invalid token")); + assertThat(thrown) + .hasCauseThat() + .hasMessageThat() + .isEqualTo("Token does not contain character '$'"); + } + + /** Test input token string is empty or null */ + @Test + public void emptyInput() throws Exception { + InvalidTokenException thrownWithNull = + assertThrows(InvalidTokenException.class, () -> signedTokenEmailTokenVerifier.decode(null)); + InvalidTokenException thrownWithEmpty = + assertThrows(InvalidTokenException.class, () -> signedTokenEmailTokenVerifier.decode("")); + assertThat(thrownWithNull).hasCauseThat().hasMessageThat().isEqualTo("Empty token"); + assertThat(thrownWithEmpty).hasCauseThat().hasMessageThat().isEqualTo("Empty token"); + } + + /** Test token format is right but key is an illegal BASE64 string */ + @Test + public void illegalTokenKey() throws Exception { + InvalidTokenException thrown = + assertThrows( + InvalidTokenException.class, + () -> signedTokenEmailTokenVerifier.decode("Illegal token key$....")); + assertThat(thrown).hasCauseThat().hasMessageThat().isEqualTo("Token length mismatch"); + } + + /** Test token text not match the required pattern */ + @Test + public void tokenTextPatternMismatch() throws Exception { + String tokenString = signedTokenEmailTokenVerifier.encode(user.id, user.email); + String tokenKey = tokenString.substring(0, tokenString.indexOf("$")); + String pattern = user.id + ":" + user.email; + String invalidTokenTextPattern = tokenKey + "$" + pattern.replace(":", ""); + InvalidTokenException thrown = + assertThrows( + InvalidTokenException.class, + () -> signedTokenEmailTokenVerifier.decode(invalidTokenTextPattern)); + assertThat(thrown).hasCauseThat().hasMessageThat().isEqualTo("Token text mismatch"); + } +} |