Introduce UserInfo helper class A new helper class UserInfo is introduced that collects information about a resource or token owner. The corresponding attributes have been extracted from the AccessToken class and moved to UserInfo. This patch also adds unit tests for both classes. Change-Id: Icedd68d68fb76f00749eee0d242584afb5cb1117 Signed-off-by: Michael Ochmann <michael.ochmann@sap.com>
diff --git a/src/main/java/com/googlesource/gerrit/plugins/cfoauth/AccessToken.java b/src/main/java/com/googlesource/gerrit/plugins/cfoauth/AccessToken.java index 3e9e4f3..a9af673 100644 --- a/src/main/java/com/googlesource/gerrit/plugins/cfoauth/AccessToken.java +++ b/src/main/java/com/googlesource/gerrit/plugins/cfoauth/AccessToken.java
@@ -14,19 +14,26 @@ package com.googlesource.gerrit.plugins.cfoauth; -import com.google.gerrit.reviewdb.client.AccountExternalId; - +import java.io.Serializable; import java.util.Objects; -class AccessToken { +class AccessToken implements Serializable { + private static final long serialVersionUID = 1L; + + private final UserInfo userInfo; private final String value; - - private final String externalId; - private final String username; - private final String emailAddress; private final long expiresAt; + /** Representation of an undefined access token, which + * has no owner and no value. + */ + static final AccessToken UNDEFINED = new AccessToken(); + + private AccessToken() { + this("", "", "", 0); + } + /** * Creates an access token. * @@ -36,79 +43,58 @@ * @param expiresAt time to expiration of this tokens in seconds * since midnight January, 1st, 1970. */ - public AccessToken(String value, String username, String emailAddress, + AccessToken(String value, String username, String emailAddress, long expiresAt) { if (value == null) { throw new IllegalArgumentException("token value must not be null"); } - if (username == null) { - throw new IllegalArgumentException("username must not be null"); - } - if (emailAddress == null) { - throw new IllegalArgumentException("emailAddress must not be null"); - } + this.userInfo = new UserInfo(username, emailAddress); this.value = value; - this.username = username; - this.externalId = AccountExternalId.SCHEME_EXTERNAL + username; - this.emailAddress = emailAddress; this.expiresAt = expiresAt; } /** * Returns the value of the access token. */ - public String getValue() { + String getValue() { return value; } /** - * Returns the external id of the token owner. - */ - public String getExternalId() { - return externalId; - } - - /** - * Returns the name of the token owner. - */ - public String getUserName() { - return username; - } - - /** - * Returns the email address of the token owner. - */ - public String getEmailAddress() { - return emailAddress; - } - - /** * Returns the timestamp when this token will expire in seconds * since midnight January, 1st, 1970. */ - public long getExpiresAt() { + long getExpiresAt() { return expiresAt; } /** * Returns <code>true</code> if this token has already expired. */ - public boolean isExpired() { + boolean isExpired() { return System.currentTimeMillis() > expiresAt * 1000; } + /** + * Returns information about the token owner. + */ + UserInfo getUserInfo() { + return userInfo; + } + @Override public String toString() { return "{'value':'" + value - + "','externalId':'" + externalId - + "','userName':'" + username - + "','emailAddress':'" + emailAddress + + "','externalId':'" + userInfo.getExternalId() + + "','username':'" + userInfo.getUserName() + + "','emailAddress':'" + userInfo.getEmailAddress() + + "','displayName':'" + userInfo.getDisplayName() + "','expiresAt':" + expiresAt + "}"; } @Override public int hashCode() { - return value.hashCode(); + return Objects.hash(value, expiresAt, userInfo); } @Override @@ -119,6 +105,9 @@ if (!(obj instanceof AccessToken)) { return false; } - return Objects.equals(value, ((AccessToken) obj).value); + AccessToken accessToken = (AccessToken) obj; + return value.equals(accessToken.value) && + expiresAt == accessToken.expiresAt && + userInfo.equals(accessToken.userInfo); } }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/cfoauth/CFOAuthService.java b/src/main/java/com/googlesource/gerrit/plugins/cfoauth/CFOAuthService.java index fd4b536..cad17eb 100644 --- a/src/main/java/com/googlesource/gerrit/plugins/cfoauth/CFOAuthService.java +++ b/src/main/java/com/googlesource/gerrit/plugins/cfoauth/CFOAuthService.java
@@ -66,8 +66,9 @@ @Override public OAuthUserInfo getUserInfo(OAuthToken token) throws IOException { AccessToken accessToken = uaaClient.toAccessToken(token.getToken()); - String displayName = uaaClient.getDisplayName(token.getToken()); - return getAsOAuthUserInfo(accessToken, displayName); + UserInfo userInfo = accessToken.getUserInfo(); + userInfo.setDisplayName(uaaClient.getDisplayName(token.getToken())); + return getAsOAuthUserInfo(userInfo); } @Override @@ -80,14 +81,13 @@ return NAME; } - private OAuthToken getAsOAuthToken(AccessToken accessToken) { + private static OAuthToken getAsOAuthToken(AccessToken accessToken) { return new OAuthToken(accessToken.getValue(), null, null); } - private OAuthUserInfo getAsOAuthUserInfo(AccessToken accessToken, - String displayName) { - return new OAuthUserInfo(accessToken.getExternalId(), - accessToken.getUserName(), accessToken.getEmailAddress(), - displayName, null); + private static OAuthUserInfo getAsOAuthUserInfo(UserInfo userInfo) { + return new OAuthUserInfo(userInfo.getExternalId(), + userInfo.getUserName(), userInfo.getEmailAddress(), + userInfo.getDisplayName(), null); } }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/cfoauth/UserInfo.java b/src/main/java/com/googlesource/gerrit/plugins/cfoauth/UserInfo.java new file mode 100644 index 0000000..c9418f5 --- /dev/null +++ b/src/main/java/com/googlesource/gerrit/plugins/cfoauth/UserInfo.java
@@ -0,0 +1,128 @@ +// Copyright (C) 2015 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.googlesource.gerrit.plugins.cfoauth; + +import com.google.gerrit.reviewdb.client.AccountExternalId; + +import java.io.Serializable; +import java.util.Objects; + +class UserInfo implements Serializable { + + private static final long serialVersionUID = 1L; + + private final String externalId; + private final String username; + private final String emailAddress; + private String displayName; + + /** + * Creates a user info object. + * + * @param username the name of a resource owner. + * @param emailAddress the email address of a resource owner. + */ + UserInfo(String username, String emailAddress) { + if (username == null) { + throw new IllegalArgumentException("username must not be null"); + } + if (emailAddress == null) { + throw new IllegalArgumentException("emailAddress must not be null"); + } + this.username = username; + this.externalId = AccountExternalId.SCHEME_EXTERNAL + username; + this.emailAddress = emailAddress; + this.displayName = username; + } + + /** + * Creates a user info object. + * + * @param username the name of a resource owner. + * @param emailAddress the email address of a resource owner. + * @param displayName the display name of a resource owner or + * <code>null</code>. In that case the {@link #getUserName()} + * will be assigned. + */ + UserInfo(String username, String emailAddress, String displayName) { + this(username, emailAddress); + setDisplayName(displayName); + } + + /** + * Returns the external id of the resource owner. + */ + String getExternalId() { + return externalId; + } + + /** + * Returns the name of the resource owner. + */ + String getUserName() { + return username; + } + + /** + * Returns the email address of the resource owner. + */ + String getEmailAddress() { + return emailAddress; + } + + /** + * Returns the display name of the resource owner. + */ + String getDisplayName() { + return displayName; + } + + /** + * Sets the display name of the resource owner. + * + * @param displayName the display name of a resource owner or + * <code>null</code>. In that case {@link #getUserName()} + * will be assigned. + */ + void setDisplayName(String displayName) { + this.displayName = displayName != null? displayName : username; + } + + @Override + public String toString() { + return "{externalId':'" + externalId + + "','username':'" + username + + "','emailAddress':'" + emailAddress + + "','displayName':'" + displayName + "'}"; + } + + @Override + public int hashCode() { + return Objects.hash(username, emailAddress); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (!(obj instanceof UserInfo)) { + return false; + } + UserInfo userInfo = (UserInfo) obj; + return username.equals(userInfo.username) && + emailAddress.equals(userInfo.emailAddress); + } +}
diff --git a/src/test/java/com/googlesource/gerrit/plugins/cfoauth/AccessTokenTest.java b/src/test/java/com/googlesource/gerrit/plugins/cfoauth/AccessTokenTest.java new file mode 100644 index 0000000..a9cf635 --- /dev/null +++ b/src/test/java/com/googlesource/gerrit/plugins/cfoauth/AccessTokenTest.java
@@ -0,0 +1,85 @@ +// Copyright (C) 2015 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.googlesource.gerrit.plugins.cfoauth; + +import static com.googlesource.gerrit.plugins.cfoauth.AccessToken.UNDEFINED; +import static com.googlesource.gerrit.plugins.cfoauth.TestUtils.*; +import static org.junit.Assert.*; + +import org.junit.Test; + +public class AccessTokenTest { + + private static final String TOKEN_VALUE = "tokenvalue"; + private static final String ANOTHER_TOKEN_VALUE = "anothertokenvalue"; + private static final long EXPIRES_AT = 4711L; + + private static final AccessToken TOKEN = + new AccessToken(TOKEN_VALUE, FOO, BAR, EXPIRES_AT); + private static AccessToken TOKEN_DIFFERENT_VALUE = + new AccessToken(ANOTHER_TOKEN_VALUE, FOO, BAR, EXPIRES_AT); + private static AccessToken TOKEN_DIFFERENT_NAME = + new AccessToken(TOKEN_VALUE, ANOTHER_FOO, BAR, EXPIRES_AT); + private static AccessToken TOKEN_DIFFERENT_EMAIL = + new AccessToken(TOKEN_VALUE, FOO, ANOTHER_BAR, EXPIRES_AT); + private static final AccessToken TOKEN_DIFFERENT_EXPIRES = + new AccessToken(TOKEN_VALUE, FOO, BAR, EXPIRES_AT + 1); + + @Test + public void testCreateAccessToken() throws Exception { + assertAccessToken(TOKEN, FOO, BAR, null, TOKEN_VALUE, EXPIRES_AT); + } + + @Test + public void testUndefined() throws Exception { + assertAccessToken(UNDEFINED, "", "", "", "", 0); + assertTrue(UNDEFINED.isExpired()); + } + + @Test + public void testExpiresAt() throws Exception { + assertTrue(TOKEN.isExpired()); + assertFalse(new AccessToken(TOKEN_VALUE, FOO, BAR, + System.currentTimeMillis() + 10).isExpired()); + } + + @Test + public void testEquals() throws Exception { + assertTrue(TOKEN.equals(TOKEN)); + assertFalse(TOKEN.equals(TOKEN_DIFFERENT_VALUE)); + assertFalse(TOKEN_DIFFERENT_VALUE.equals(TOKEN)); + assertFalse(TOKEN.equals(TOKEN_DIFFERENT_NAME)); + assertFalse(TOKEN_DIFFERENT_NAME.equals(TOKEN)); + assertFalse(TOKEN.equals(TOKEN_DIFFERENT_EMAIL)); + assertFalse(TOKEN_DIFFERENT_EXPIRES.equals(TOKEN)); + assertFalse(TOKEN.equals(TOKEN_DIFFERENT_EXPIRES)); + assertFalse(TOKEN.equals(null)); + assertFalse(TOKEN.equals(MR_FOO)); + } + + @Test(expected=IllegalArgumentException.class) + public void testMissingValue() throws Exception { + new AccessToken(null, FOO, BAR, EXPIRES_AT); + } + + private void assertAccessToken(AccessToken accessToken, String username, + String emailAddress, String displayName, String value, long expiresAt) { + assertUserInfo(accessToken.getUserInfo(), username, + emailAddress, displayName); + assertEquals(value, accessToken.getValue()); + assertEquals(expiresAt, accessToken.getExpiresAt()); + assertTrue(accessToken.isExpired()); + } +}
diff --git a/src/test/java/com/googlesource/gerrit/plugins/cfoauth/TestUtils.java b/src/test/java/com/googlesource/gerrit/plugins/cfoauth/TestUtils.java new file mode 100644 index 0000000..16e9c76 --- /dev/null +++ b/src/test/java/com/googlesource/gerrit/plugins/cfoauth/TestUtils.java
@@ -0,0 +1,38 @@ +// Copyright (C) 2015 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.googlesource.gerrit.plugins.cfoauth; + +import static org.junit.Assert.assertEquals; + +public class TestUtils { + + static final String FOO = "foo"; + static final String BAR = "bar"; + static final String MR_FOO = "Mr. Foo"; + static final String ANOTHER_FOO = "anotherfoo"; + static final String ANOTHER_BAR = "anotherbar"; + + static void assertUserInfo(UserInfo userInfo, String username, + String emailAddress, String displayName) { + assertEquals(username, userInfo.getUserName()); + assertEquals(emailAddress, userInfo.getEmailAddress()); + if (displayName != null) { + assertEquals(displayName, userInfo.getDisplayName()); + } else { + assertEquals(username, userInfo.getDisplayName()); + } + } + +}
diff --git a/src/test/java/com/googlesource/gerrit/plugins/cfoauth/UAAClientTest.java b/src/test/java/com/googlesource/gerrit/plugins/cfoauth/UAAClientTest.java index 160b8ea..2616784 100644 --- a/src/test/java/com/googlesource/gerrit/plugins/cfoauth/UAAClientTest.java +++ b/src/test/java/com/googlesource/gerrit/plugins/cfoauth/UAAClientTest.java
@@ -174,8 +174,9 @@ private void assertHS266AccessToken(AccessToken accessToken) { assertEquals(HS256_TEST_TOKEN, accessToken.getValue()); assertEquals(1436232932L, accessToken.getExpiresAt()); - assertEquals("external:marissa", accessToken.getExternalId()); - assertEquals("marissa", accessToken.getUserName()); - assertEquals("marissa@test.org", accessToken.getEmailAddress()); + UserInfo userInfo = accessToken.getUserInfo(); + assertEquals("external:marissa", userInfo.getExternalId()); + assertEquals("marissa", userInfo.getUserName()); + assertEquals("marissa@test.org", userInfo.getEmailAddress()); } }
diff --git a/src/test/java/com/googlesource/gerrit/plugins/cfoauth/UserInfoTest.java b/src/test/java/com/googlesource/gerrit/plugins/cfoauth/UserInfoTest.java new file mode 100644 index 0000000..cb1eb32 --- /dev/null +++ b/src/test/java/com/googlesource/gerrit/plugins/cfoauth/UserInfoTest.java
@@ -0,0 +1,71 @@ +// Copyright (C) 2015 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.googlesource.gerrit.plugins.cfoauth; + +import static com.googlesource.gerrit.plugins.cfoauth.TestUtils.*; +import static org.junit.Assert.*; + +import org.junit.Test; + +public class UserInfoTest { + + private static final UserInfo USER = new UserInfo(FOO, BAR); + private static final UserInfo USER_DIFFERENT_NAME = + new UserInfo(ANOTHER_FOO, BAR); + private static final UserInfo USER_DIFFERENT_EMAIL = + new UserInfo(FOO, ANOTHER_BAR); + private static final UserInfo USER_DISPLAYNAME = + new UserInfo(FOO, BAR, MR_FOO); + + @Test + public void testCreateUserInfo() throws Exception { + assertUserInfo(USER, FOO, BAR, null); + assertUserInfo(USER_DISPLAYNAME, FOO, BAR, MR_FOO); + } + + @Test + public void testDisplayName() throws Exception { + UserInfo userInfo = new UserInfo(FOO, BAR); + assertUserInfo(userInfo, FOO, BAR, null); + userInfo.setDisplayName(MR_FOO); + assertUserInfo(userInfo, FOO, BAR, MR_FOO); + userInfo.setDisplayName(null); + assertUserInfo(userInfo, FOO, BAR, null); + } + + @Test + public void testEquals() throws Exception { + assertTrue(USER.equals(USER)); + assertFalse(USER.equals(USER_DIFFERENT_NAME)); + assertFalse(USER_DIFFERENT_NAME.equals(USER)); + assertFalse(USER.equals(USER_DIFFERENT_EMAIL)); + assertFalse(USER_DIFFERENT_EMAIL.equals(USER)); + assertTrue(USER.equals(USER_DISPLAYNAME)); + assertTrue(USER_DISPLAYNAME.equals(USER)); + assertFalse(USER.equals(null)); + assertFalse(USER.equals(MR_FOO)); + } + + @Test(expected=IllegalArgumentException.class) + public void testMissingUserName() throws Exception { + new UserInfo(null, BAR); + } + + @Test(expected=IllegalArgumentException.class) + public void testMissingEmailAddress() throws Exception { + new UserInfo(FOO, null); + } + +}