diff --git a/sources/src/main/java/com/google/solutions/jitaccess/core/UserEmail.java b/sources/src/main/java/com/google/solutions/jitaccess/core/UserEmail.java new file mode 100644 index 000000000..f1c388d15 --- /dev/null +++ b/sources/src/main/java/com/google/solutions/jitaccess/core/UserEmail.java @@ -0,0 +1,71 @@ +// +// Copyright 2021 Google LLC +// +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you 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.solutions.jitaccess.core; + +import com.google.common.base.Preconditions; + +import java.util.Objects; + +/** + * Primary email address of a user. + */ +public class UserEmail implements Comparable { + public final String email; + + public UserEmail(String email) { + Preconditions.checkNotNull(email, "email"); + this.email = email; + } + + @Override + public String toString() { + return this.email; + } + + // ------------------------------------------------------------------------- + // Equality. + // ------------------------------------------------------------------------- + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + + if (o == null || getClass() != o.getClass()) { + return false; + } + + UserEmail userEmail = (UserEmail) o; + return email.equals(userEmail.email); + } + + @Override + public int hashCode() { + return Objects.hash(email); + } + + @Override + public int compareTo(UserEmail o) { + return this.email.compareTo(o.email); + } +} diff --git a/sources/src/main/java/com/google/solutions/jitaccess/core/UserId.java b/sources/src/main/java/com/google/solutions/jitaccess/core/UserId.java index 0982ff61e..e8c6658b6 100644 --- a/sources/src/main/java/com/google/solutions/jitaccess/core/UserId.java +++ b/sources/src/main/java/com/google/solutions/jitaccess/core/UserId.java @@ -1,5 +1,5 @@ // -// Copyright 2021 Google LLC +// Copyright 2024 Google LLC // // Licensed to the Apache Software Foundation (ASF) under one // or more contributor license agreements. See the NOTICE file @@ -25,30 +25,20 @@ import java.util.Objects; -public class UserId implements Comparable { +/** + * Primary email address and unique ID of a user. + */ +public class UserId extends UserEmail { public final transient String id; - public final String email; public UserId(String id, String email) { - Preconditions.checkNotNull(email, "email"); + super(email); - this.id = id; - this.email = email; - } - - public UserId(String email) { - this(null, email); - } + Preconditions.checkNotNull(id, "id"); - @Override - public String toString() { - return this.email; + this.id = id; } - // ------------------------------------------------------------------------- - // Equality. - // ------------------------------------------------------------------------- - @Override public boolean equals(Object o) { if (this == o) { @@ -59,17 +49,16 @@ public boolean equals(Object o) { return false; } + if (!super.equals(o)) { + return false; + } + UserId userId = (UserId) o; - return email.equals(userId.email); + return this.id.equals(userId.id); } @Override public int hashCode() { - return Objects.hash(email); - } - - @Override - public int compareTo(UserId o) { - return this.email.compareTo(o.email); + return Objects.hash(super.hashCode(), id); } } diff --git a/sources/src/main/java/com/google/solutions/jitaccess/core/catalog/ActivationRequest.java b/sources/src/main/java/com/google/solutions/jitaccess/core/catalog/ActivationRequest.java index 0d2ebaf51..ca6367977 100644 --- a/sources/src/main/java/com/google/solutions/jitaccess/core/catalog/ActivationRequest.java +++ b/sources/src/main/java/com/google/solutions/jitaccess/core/catalog/ActivationRequest.java @@ -22,7 +22,7 @@ package com.google.solutions.jitaccess.core.catalog; import com.google.common.base.Preconditions; -import com.google.solutions.jitaccess.core.UserId; +import com.google.solutions.jitaccess.core.UserEmail; import java.time.Duration; import java.time.Instant; @@ -37,13 +37,13 @@ public abstract class ActivationRequest { private final ActivationId id; private final Instant startTime; private final Duration duration; - private final UserId requestingUser; + private final UserEmail requestingUser; private final Set entitlements; private final String justification; protected ActivationRequest( ActivationId id, - UserId requestingUser, + UserEmail requestingUser, Set entitlements, String justification, Instant startTime, @@ -104,7 +104,7 @@ public Instant endTime() { /** * @return user that requested access. */ - public UserId requestingUser() { + public UserEmail requestingUser() { return this.requestingUser; } diff --git a/sources/src/main/java/com/google/solutions/jitaccess/core/catalog/EntitlementActivator.java b/sources/src/main/java/com/google/solutions/jitaccess/core/catalog/EntitlementActivator.java index edc7252d8..c3e8c606e 100644 --- a/sources/src/main/java/com/google/solutions/jitaccess/core/catalog/EntitlementActivator.java +++ b/sources/src/main/java/com/google/solutions/jitaccess/core/catalog/EntitlementActivator.java @@ -25,7 +25,7 @@ import com.google.solutions.jitaccess.core.AccessDeniedException; import com.google.solutions.jitaccess.core.AccessException; import com.google.solutions.jitaccess.core.AlreadyExistsException; -import com.google.solutions.jitaccess.core.UserId; +import com.google.solutions.jitaccess.core.UserEmail; import java.io.IOException; import java.time.Duration; @@ -54,7 +54,7 @@ protected EntitlementActivator( * Create a new request to activate an entitlement that permits self-approval. */ public final JitActivationRequest createJitRequest( - UserId requestingUser, + UserEmail requestingUser, Set entitlements, String justification, Instant startTime, @@ -81,9 +81,9 @@ public final JitActivationRequest createJitRequest( * multi-party approval. */ public MpaActivationRequest createMpaRequest( - UserId requestingUser, + UserEmail requestingUser, Set entitlements, - Set reviewers, + Set reviewers, String justification, Instant startTime, Duration duration @@ -142,7 +142,7 @@ public final Activation activate( * Approve another user's request. */ public final Activation approve( - UserId approvingUser, + UserEmail approvingUser, MpaActivationRequest request ) throws AccessException, AlreadyExistsException, IOException { @@ -193,7 +193,7 @@ protected abstract void provisionAccess( * Apply a request. */ protected abstract void provisionAccess( - UserId approvingUser, + UserEmail approvingUser, MpaActivationRequest request ) throws AccessException, AlreadyExistsException, IOException; @@ -211,7 +211,7 @@ protected static class JitRequest extends JitActivationRequest { public JitRequest( ActivationId id, - UserId requestingUser, + UserEmail requestingUser, Set entitlements, String justification, Instant startTime, @@ -225,9 +225,9 @@ protected static class MpaRequest extends MpaActivationRequest { public MpaRequest( ActivationId id, - UserId requestingUser, + UserEmail requestingUser, Set entitlements, - Set reviewers, + Set reviewers, String justification, Instant startTime, Duration duration diff --git a/sources/src/main/java/com/google/solutions/jitaccess/core/catalog/EntitlementCatalog.java b/sources/src/main/java/com/google/solutions/jitaccess/core/catalog/EntitlementCatalog.java index 35742f780..42f7c1d74 100644 --- a/sources/src/main/java/com/google/solutions/jitaccess/core/catalog/EntitlementCatalog.java +++ b/sources/src/main/java/com/google/solutions/jitaccess/core/catalog/EntitlementCatalog.java @@ -22,7 +22,7 @@ package com.google.solutions.jitaccess.core.catalog; import com.google.solutions.jitaccess.core.AccessException; -import com.google.solutions.jitaccess.core.UserId; +import com.google.solutions.jitaccess.core.UserEmail; import java.io.IOException; @@ -41,7 +41,7 @@ void verifyUserCanRequest( * Verify if a user is allowed to approve a given request. */ void verifyUserCanApprove( - UserId approvingUser, + UserEmail approvingUser, MpaActivationRequest request ) throws AccessException, IOException; } diff --git a/sources/src/main/java/com/google/solutions/jitaccess/core/catalog/JitActivationRequest.java b/sources/src/main/java/com/google/solutions/jitaccess/core/catalog/JitActivationRequest.java index 1ec2e02a3..b0f2e6ea0 100644 --- a/sources/src/main/java/com/google/solutions/jitaccess/core/catalog/JitActivationRequest.java +++ b/sources/src/main/java/com/google/solutions/jitaccess/core/catalog/JitActivationRequest.java @@ -21,7 +21,7 @@ package com.google.solutions.jitaccess.core.catalog; -import com.google.solutions.jitaccess.core.UserId; +import com.google.solutions.jitaccess.core.UserEmail; import java.time.Duration; import java.time.Instant; @@ -34,7 +34,7 @@ public abstract class JitActivationRequest extends ActivationRequest { protected JitActivationRequest( ActivationId id, - UserId requestingUser, + UserEmail requestingUser, Set entitlements, String justification, Instant startTime, diff --git a/sources/src/main/java/com/google/solutions/jitaccess/core/catalog/JustificationPolicy.java b/sources/src/main/java/com/google/solutions/jitaccess/core/catalog/JustificationPolicy.java index 59bf38002..4a40da504 100644 --- a/sources/src/main/java/com/google/solutions/jitaccess/core/catalog/JustificationPolicy.java +++ b/sources/src/main/java/com/google/solutions/jitaccess/core/catalog/JustificationPolicy.java @@ -21,7 +21,7 @@ package com.google.solutions.jitaccess.core.catalog; -import com.google.solutions.jitaccess.core.UserId; +import com.google.solutions.jitaccess.core.UserEmail; /** * Policy for verifying justification messages. @@ -31,7 +31,7 @@ public interface JustificationPolicy { * Check that a justification meets criteria. */ void checkJustification( - UserId user, + UserEmail user, String justification ) throws InvalidJustificationException; diff --git a/sources/src/main/java/com/google/solutions/jitaccess/core/catalog/MpaActivationRequest.java b/sources/src/main/java/com/google/solutions/jitaccess/core/catalog/MpaActivationRequest.java index 1b8b48549..0bd0f26a3 100644 --- a/sources/src/main/java/com/google/solutions/jitaccess/core/catalog/MpaActivationRequest.java +++ b/sources/src/main/java/com/google/solutions/jitaccess/core/catalog/MpaActivationRequest.java @@ -22,7 +22,7 @@ package com.google.solutions.jitaccess.core.catalog; import com.google.common.base.Preconditions; -import com.google.solutions.jitaccess.core.UserId; +import com.google.solutions.jitaccess.core.UserEmail; import java.time.Duration; import java.time.Instant; @@ -34,13 +34,13 @@ */ public abstract class MpaActivationRequest extends ActivationRequest { - private final Collection reviewers; + private final Collection reviewers; protected MpaActivationRequest( ActivationId id, - UserId requestingUser, + UserEmail requestingUser, Set entitlements, - Set reviewers, + Set reviewers, String justification, Instant startTime, Duration duration) { @@ -57,7 +57,7 @@ protected MpaActivationRequest( this.reviewers = reviewers; } - public Collection reviewers() { + public Collection reviewers() { return this.reviewers; } diff --git a/sources/src/main/java/com/google/solutions/jitaccess/core/catalog/RegexJustificationPolicy.java b/sources/src/main/java/com/google/solutions/jitaccess/core/catalog/RegexJustificationPolicy.java index f2a5ab0fa..aa230be38 100644 --- a/sources/src/main/java/com/google/solutions/jitaccess/core/catalog/RegexJustificationPolicy.java +++ b/sources/src/main/java/com/google/solutions/jitaccess/core/catalog/RegexJustificationPolicy.java @@ -23,7 +23,7 @@ import com.google.common.base.Preconditions; import com.google.common.base.Strings; -import com.google.solutions.jitaccess.core.UserId; +import com.google.solutions.jitaccess.core.UserEmail; import jakarta.inject.Singleton; import java.util.regex.Pattern; @@ -42,7 +42,7 @@ public RegexJustificationPolicy(Options options) { @Override public void checkJustification( - UserId user, + UserEmail user, String justification ) throws InvalidJustificationException { if ( diff --git a/sources/src/main/java/com/google/solutions/jitaccess/core/catalog/TokenSigner.java b/sources/src/main/java/com/google/solutions/jitaccess/core/catalog/TokenSigner.java index f5f847db8..d8e324685 100644 --- a/sources/src/main/java/com/google/solutions/jitaccess/core/catalog/TokenSigner.java +++ b/sources/src/main/java/com/google/solutions/jitaccess/core/catalog/TokenSigner.java @@ -24,7 +24,7 @@ import com.google.auth.oauth2.TokenVerifier; import com.google.common.base.Preconditions; import com.google.solutions.jitaccess.core.AccessException; -import com.google.solutions.jitaccess.core.UserId; +import com.google.solutions.jitaccess.core.UserEmail; import com.google.solutions.jitaccess.core.clients.IamCredentialsClient; import jakarta.inject.Singleton; @@ -128,7 +128,7 @@ public record TokenWithExpiry( } } - public record Options(UserId serviceAccount, Duration tokenValidity) { + public record Options(UserEmail serviceAccount, Duration tokenValidity) { public Options { Preconditions.checkNotNull(serviceAccount); Preconditions.checkArgument(!tokenValidity.isNegative()); diff --git a/sources/src/main/java/com/google/solutions/jitaccess/core/catalog/project/AssetInventoryRepository.java b/sources/src/main/java/com/google/solutions/jitaccess/core/catalog/project/AssetInventoryRepository.java index 6a29c4591..dff3a934f 100644 --- a/sources/src/main/java/com/google/solutions/jitaccess/core/catalog/project/AssetInventoryRepository.java +++ b/sources/src/main/java/com/google/solutions/jitaccess/core/catalog/project/AssetInventoryRepository.java @@ -93,7 +93,7 @@ static T awaitAndRethrow(CompletableFuture future) throws AccessException } List findProjectBindings( - UserId user, + UserEmail user, ProjectId projectId ) throws AccessException, IOException { // @@ -132,7 +132,7 @@ List findProjectBindings( @Override public SortedSet findProjectsWithEntitlements( - UserId user + UserEmail user ) { // // Not supported. @@ -143,7 +143,7 @@ public SortedSet findProjectsWithEntitlements( @Override public EntitlementSet findEntitlements( - UserId user, + UserEmail user, ProjectId projectId, EnumSet typesToInclude, EnumSet statusesToInclude @@ -246,7 +246,7 @@ public EntitlementSet findEntitlements( } @Override - public Set findEntitlementHolders( + public Set findEntitlementHolders( ProjectRoleBinding roleBinding, ActivationType activationType ) throws AccessException, IOException { @@ -276,7 +276,7 @@ public Set findEntitlementHolders( .filter(p -> p.startsWith(USER_PREFIX)) .map(p -> p.substring(USER_PREFIX.length())) .distinct() - .map(email -> new UserId(email)) + .map(email -> new UserEmail(email)) .collect(Collectors.toSet()); // @@ -307,7 +307,7 @@ public Set findEntitlementHolders( for (var listMembersFuture : listMembersFutures) { var members = awaitAndRethrow(listMembersFuture) .stream() - .map(m -> new UserId(m.getEmail())) + .map(m -> new UserEmail(m.getEmail())) .collect(Collectors.toList()); allMembers.addAll(members); } @@ -323,7 +323,7 @@ class PrincipalSet { private final Set principalIdentifiers; public PrincipalSet( - UserId user, + UserEmail user, Collection groups ) { this.principalIdentifiers = groups diff --git a/sources/src/main/java/com/google/solutions/jitaccess/core/catalog/project/MpaProjectRoleCatalog.java b/sources/src/main/java/com/google/solutions/jitaccess/core/catalog/project/MpaProjectRoleCatalog.java index 3101a5011..49e39b58e 100644 --- a/sources/src/main/java/com/google/solutions/jitaccess/core/catalog/project/MpaProjectRoleCatalog.java +++ b/sources/src/main/java/com/google/solutions/jitaccess/core/catalog/project/MpaProjectRoleCatalog.java @@ -26,7 +26,7 @@ import com.google.solutions.jitaccess.core.AccessDeniedException; import com.google.solutions.jitaccess.core.AccessException; import com.google.solutions.jitaccess.core.ProjectId; -import com.google.solutions.jitaccess.core.UserId; +import com.google.solutions.jitaccess.core.UserEmail; import com.google.solutions.jitaccess.core.catalog.*; import com.google.solutions.jitaccess.core.clients.ResourceManagerClient; import jakarta.inject.Singleton; @@ -89,7 +89,7 @@ void validateRequest(ActivationRequest request) { } void verifyUserCanActivateEntitlements( - UserId user, + UserEmail user, ProjectId projectId, ActivationType activationType, Collection entitlements @@ -137,7 +137,7 @@ public Options options() { @Override public SortedSet listProjects( - UserId user + UserEmail user ) throws AccessException, IOException { if (Strings.isNullOrEmpty(this.options.availableProjectsQuery)) { // @@ -161,7 +161,7 @@ public SortedSet listProjects( @Override public EntitlementSet listEntitlements( - UserId user, + UserEmail user, ProjectId projectId ) throws AccessException, IOException { return this.repository.findEntitlements( @@ -172,8 +172,8 @@ public EntitlementSet listEntitlements( } @Override - public SortedSet listReviewers( - UserId requestingUser, + public SortedSet listReviewers( + UserEmail requestingUser, ProjectRoleBinding entitlement ) throws AccessException, IOException { @@ -220,7 +220,7 @@ public void verifyUserCanRequest( @Override public void verifyUserCanApprove( - UserId approvingUser, + UserEmail approvingUser, MpaActivationRequest request ) throws AccessException, IOException { diff --git a/sources/src/main/java/com/google/solutions/jitaccess/core/catalog/project/PolicyAnalyzerRepository.java b/sources/src/main/java/com/google/solutions/jitaccess/core/catalog/project/PolicyAnalyzerRepository.java index 9e7468924..4ae66c6da 100644 --- a/sources/src/main/java/com/google/solutions/jitaccess/core/catalog/project/PolicyAnalyzerRepository.java +++ b/sources/src/main/java/com/google/solutions/jitaccess/core/catalog/project/PolicyAnalyzerRepository.java @@ -29,7 +29,7 @@ import com.google.solutions.jitaccess.core.AccessException; import com.google.solutions.jitaccess.core.ProjectId; import com.google.solutions.jitaccess.core.RoleBinding; -import com.google.solutions.jitaccess.core.UserId; +import com.google.solutions.jitaccess.core.UserEmail; import com.google.solutions.jitaccess.core.catalog.ActivationType; import com.google.solutions.jitaccess.core.catalog.Entitlement; import com.google.solutions.jitaccess.core.catalog.EntitlementSet; @@ -111,7 +111,7 @@ static List findRoleBindings( @Override public SortedSet findProjectsWithEntitlements( - UserId user + UserEmail user ) throws AccessException, IOException { Preconditions.checkNotNull(user, "user"); @@ -156,7 +156,7 @@ public SortedSet findProjectsWithEntitlements( @Override public EntitlementSet findEntitlements( - UserId user, + UserEmail user, ProjectId projectId, EnumSet typesToInclude, EnumSet statusesToInclude @@ -295,7 +295,7 @@ public EntitlementSet findEntitlements( } @Override - public Set findEntitlementHolders( + public Set findEntitlementHolders( ProjectRoleBinding roleBinding, ActivationType activationType ) throws AccessException, IOException { @@ -319,7 +319,7 @@ public Set findEntitlementHolders( .filter(result -> result.getIdentityList() != null) .flatMap(result -> result.getIdentityList().getIdentities().stream() .filter(id -> id.getName().startsWith("user:")) - .map(id -> new UserId(id.getName().substring("user:".length())))) + .map(id -> new UserEmail(id.getName().substring("user:".length())))) .collect(Collectors.toCollection(TreeSet::new)); } diff --git a/sources/src/main/java/com/google/solutions/jitaccess/core/catalog/project/ProjectRoleActivator.java b/sources/src/main/java/com/google/solutions/jitaccess/core/catalog/project/ProjectRoleActivator.java index 2db0e40f8..288bcf12f 100644 --- a/sources/src/main/java/com/google/solutions/jitaccess/core/catalog/project/ProjectRoleActivator.java +++ b/sources/src/main/java/com/google/solutions/jitaccess/core/catalog/project/ProjectRoleActivator.java @@ -60,7 +60,7 @@ public ProjectRoleActivator( private void provisionTemporaryBinding( String bindingDescription, ProjectId projectId, - UserId user, + UserEmail user, Set roles, Instant startTime, Duration duration @@ -121,7 +121,7 @@ protected void provisionAccess( @Override protected void provisionAccess( - UserId approvingUser, + UserEmail approvingUser, MpaActivationRequest request ) throws AccessException, AlreadyExistsException, IOException { @@ -188,11 +188,11 @@ public MpaActivationRequest convert(JsonWebToken.Payload pay return new MpaRequest<>( new ActivationId(payload.getJwtId()), - new UserId(payload.get("beneficiary").toString()), + new UserEmail(payload.get("beneficiary").toString()), Set.of(new ProjectRoleBinding(roleBinding)), ((List)payload.get("reviewers")) .stream() - .map(email -> new UserId(email)) + .map(email -> new UserEmail(email)) .collect(Collectors.toSet()), payload.get("justification").toString(), Instant.ofEpochSecond(startTime), diff --git a/sources/src/main/java/com/google/solutions/jitaccess/core/catalog/project/ProjectRoleCatalog.java b/sources/src/main/java/com/google/solutions/jitaccess/core/catalog/project/ProjectRoleCatalog.java index 1a5692f4e..42d742ff6 100644 --- a/sources/src/main/java/com/google/solutions/jitaccess/core/catalog/project/ProjectRoleCatalog.java +++ b/sources/src/main/java/com/google/solutions/jitaccess/core/catalog/project/ProjectRoleCatalog.java @@ -23,7 +23,7 @@ import com.google.solutions.jitaccess.core.AccessException; import com.google.solutions.jitaccess.core.ProjectId; -import com.google.solutions.jitaccess.core.UserId; +import com.google.solutions.jitaccess.core.UserEmail; import com.google.solutions.jitaccess.core.catalog.EntitlementCatalog; import com.google.solutions.jitaccess.core.catalog.EntitlementSet; @@ -38,22 +38,22 @@ public abstract class ProjectRoleCatalog implements EntitlementCatalog listProjects( - UserId user + UserEmail user ) throws AccessException, IOException; /** * List available entitlements. */ public abstract EntitlementSet listEntitlements( - UserId user, + UserEmail user, ProjectId projectId ) throws AccessException, IOException; /** * List available reviewers for (MPA-) activating an entitlement. */ - public abstract SortedSet listReviewers( - UserId requestingUser, + public abstract SortedSet listReviewers( + UserEmail requestingUser, ProjectRoleBinding entitlement ) throws AccessException, IOException; } diff --git a/sources/src/main/java/com/google/solutions/jitaccess/core/catalog/project/ProjectRoleRepository.java b/sources/src/main/java/com/google/solutions/jitaccess/core/catalog/project/ProjectRoleRepository.java index 1fcb2a7be..3528a994b 100644 --- a/sources/src/main/java/com/google/solutions/jitaccess/core/catalog/project/ProjectRoleRepository.java +++ b/sources/src/main/java/com/google/solutions/jitaccess/core/catalog/project/ProjectRoleRepository.java @@ -2,7 +2,7 @@ import com.google.solutions.jitaccess.core.AccessException; import com.google.solutions.jitaccess.core.ProjectId; -import com.google.solutions.jitaccess.core.UserId; +import com.google.solutions.jitaccess.core.UserEmail; import com.google.solutions.jitaccess.core.catalog.ActivationType; import com.google.solutions.jitaccess.core.catalog.Entitlement; import com.google.solutions.jitaccess.core.catalog.EntitlementSet; @@ -21,14 +21,14 @@ public interface ProjectRoleRepository { * Find projects that a user has standing, JIT-, or MPA-eligible access to. */ SortedSet findProjectsWithEntitlements( - UserId user + UserEmail user ) throws AccessException, IOException; /** * List entitlements for the given user. */ EntitlementSet findEntitlements( - UserId user, + UserEmail user, ProjectId projectId, EnumSet typesToInclude, EnumSet statusesToInclude @@ -37,7 +37,7 @@ EntitlementSet findEntitlements( /** * List users that hold an eligible role binding. */ - Set findEntitlementHolders( + Set findEntitlementHolders( ProjectRoleBinding roleBinding, ActivationType activationType ) throws AccessException, IOException; diff --git a/sources/src/main/java/com/google/solutions/jitaccess/core/clients/DirectoryGroupsClient.java b/sources/src/main/java/com/google/solutions/jitaccess/core/clients/DirectoryGroupsClient.java index 5b1e22ce3..7936ef87b 100644 --- a/sources/src/main/java/com/google/solutions/jitaccess/core/clients/DirectoryGroupsClient.java +++ b/sources/src/main/java/com/google/solutions/jitaccess/core/clients/DirectoryGroupsClient.java @@ -80,7 +80,7 @@ private Directory createClient() throws IOException { * List all groups a given user is a direct member of. */ public Collection listDirectGroupMemberships( - UserId user + UserEmail user ) throws AccessException, IOException { try { // diff --git a/sources/src/main/java/com/google/solutions/jitaccess/core/clients/IamCredentialsClient.java b/sources/src/main/java/com/google/solutions/jitaccess/core/clients/IamCredentialsClient.java index c5532a1c7..f13178b35 100644 --- a/sources/src/main/java/com/google/solutions/jitaccess/core/clients/IamCredentialsClient.java +++ b/sources/src/main/java/com/google/solutions/jitaccess/core/clients/IamCredentialsClient.java @@ -75,7 +75,7 @@ public IamCredentialsClient( * Sign a JWT using the Google-managed service account key. */ public String signJwt( - UserId serviceAccount, + UserEmail serviceAccount, JsonWebToken.Payload payload ) throws AccessException, IOException { Preconditions.checkNotNull(serviceAccount, "serviceAccount"); @@ -118,7 +118,7 @@ public String signJwt( /** * Get JWKS location for service account key set. */ - public static String getJwksUrl(UserId serviceAccount) { + public static String getJwksUrl(UserEmail serviceAccount) { return String.format("https://www.googleapis.com/service_accounts/v1/metadata/jwk/%s", serviceAccount.email); } } diff --git a/sources/src/main/java/com/google/solutions/jitaccess/core/clients/PolicyAnalyzerClient.java b/sources/src/main/java/com/google/solutions/jitaccess/core/clients/PolicyAnalyzerClient.java index e96cf8ff0..5e9400935 100644 --- a/sources/src/main/java/com/google/solutions/jitaccess/core/clients/PolicyAnalyzerClient.java +++ b/sources/src/main/java/com/google/solutions/jitaccess/core/clients/PolicyAnalyzerClient.java @@ -57,7 +57,7 @@ public PolicyAnalyzerClient( */ public IamPolicyAnalysis findAccessibleResourcesByUser( String scope, - UserId user, + UserEmail user, Optional permission, Optional fullResourceName, boolean expandResources diff --git a/sources/src/main/java/com/google/solutions/jitaccess/core/clients/SmtpClient.java b/sources/src/main/java/com/google/solutions/jitaccess/core/clients/SmtpClient.java index 3f7ceaa43..64edb7d84 100644 --- a/sources/src/main/java/com/google/solutions/jitaccess/core/clients/SmtpClient.java +++ b/sources/src/main/java/com/google/solutions/jitaccess/core/clients/SmtpClient.java @@ -23,7 +23,7 @@ import com.google.common.base.Preconditions; import com.google.solutions.jitaccess.core.AccessException; -import com.google.solutions.jitaccess.core.UserId; +import com.google.solutions.jitaccess.core.UserEmail; import jakarta.mail.*; import jakarta.mail.internet.InternetAddress; import jakarta.mail.internet.MimeBodyPart; @@ -57,8 +57,8 @@ public SmtpClient( } public void sendMail( - Collection toRecipients, - Collection ccRecipients, + Collection toRecipients, + Collection ccRecipients, String subject, Multipart content, EnumSet flags @@ -125,8 +125,8 @@ protected PasswordAuthentication getPasswordAuthentication() { } public void sendMail( - Collection toRecipients, - Collection ccRecipients, + Collection toRecipients, + Collection ccRecipients, String subject, String htmlContent, EnumSet flags diff --git a/sources/src/main/java/com/google/solutions/jitaccess/core/notifications/NotificationService.java b/sources/src/main/java/com/google/solutions/jitaccess/core/notifications/NotificationService.java index ccaeae5cf..e8b84a8ea 100644 --- a/sources/src/main/java/com/google/solutions/jitaccess/core/notifications/NotificationService.java +++ b/sources/src/main/java/com/google/solutions/jitaccess/core/notifications/NotificationService.java @@ -22,7 +22,7 @@ package com.google.solutions.jitaccess.core.notifications; import com.google.common.base.Preconditions; -import com.google.solutions.jitaccess.core.UserId; +import com.google.solutions.jitaccess.core.UserEmail; import jakarta.inject.Singleton; import java.util.Collection; @@ -75,8 +75,8 @@ public void sendNotification(Notification notification) { * but doesn't define its format. */ public static abstract class Notification { - private final Collection toRecipients; - private final Collection ccRecipients; + private final Collection toRecipients; + private final Collection ccRecipients; private final String subject; protected final Map properties = new HashMap<>(); @@ -85,11 +85,11 @@ protected boolean isReply() { return false; } - public Collection getToRecipients() { + public Collection getToRecipients() { return toRecipients; } - public Collection getCcRecipients() { + public Collection getCcRecipients() { return ccRecipients; } @@ -103,8 +103,8 @@ public String getSubject() { public abstract String getType(); protected Notification( - Collection toRecipients, - Collection ccRecipients, + Collection toRecipients, + Collection ccRecipients, String subject ) { Preconditions.checkNotNull(toRecipients, "toRecipients"); diff --git a/sources/src/main/java/com/google/solutions/jitaccess/web/RuntimeEnvironment.java b/sources/src/main/java/com/google/solutions/jitaccess/web/RuntimeEnvironment.java index 293d9ab0b..962552645 100644 --- a/sources/src/main/java/com/google/solutions/jitaccess/web/RuntimeEnvironment.java +++ b/sources/src/main/java/com/google/solutions/jitaccess/web/RuntimeEnvironment.java @@ -28,13 +28,12 @@ import com.google.api.client.json.JsonObjectParser; import com.google.api.client.json.gson.GsonFactory; import com.google.api.client.util.GenericData; -import com.google.api.services.cloudasset.v1.model.Asset; import com.google.auth.oauth2.ComputeEngineCredentials; import com.google.auth.oauth2.GoogleCredentials; import com.google.auth.oauth2.ImpersonatedCredentials; import com.google.auth.oauth2.ServiceAccountCredentials; import com.google.solutions.jitaccess.core.ApplicationVersion; -import com.google.solutions.jitaccess.core.UserId; +import com.google.solutions.jitaccess.core.UserEmail; import com.google.solutions.jitaccess.core.catalog.RegexJustificationPolicy; import com.google.solutions.jitaccess.core.catalog.TokenSigner; import com.google.solutions.jitaccess.core.catalog.project.AssetInventoryRepository; @@ -55,11 +54,8 @@ import java.io.IOException; import java.net.UnknownHostException; import java.time.Duration; -import java.util.List; import java.util.concurrent.Executor; import java.util.regex.Pattern; -import java.util.stream.Collectors; -import java.util.stream.Stream; /** * Provides access to runtime configuration (AppEngine, local). To be injected using CDI. @@ -72,7 +68,7 @@ public class RuntimeEnvironment { private final String projectId; private final String projectNumber; - private final UserId applicationPrincipal; + private final UserEmail applicationPrincipal; private final GoogleCredentials applicationCredentials; /** @@ -145,7 +141,7 @@ public RuntimeEnvironment() { this.projectNumber = projectMetadata.get("numericProjectId").toString(); var defaultCredentials = (ComputeEngineCredentials)GoogleCredentials.getApplicationDefault(); - this.applicationPrincipal = new UserId(defaultCredentials.getAccount()); + this.applicationPrincipal = new UserEmail(defaultCredentials.getAccount()); if (defaultCredentials.getScopes().containsAll(this.configuration.getRequiredOauthScopes())) { // @@ -220,14 +216,14 @@ else if (isDebugModeEnabled()) { // refresh fails, fail application startup. // this.applicationCredentials.refresh(); - this.applicationPrincipal = new UserId(impersonateServiceAccount); + this.applicationPrincipal = new UserEmail(impersonateServiceAccount); } else if (defaultCredentials instanceof ServiceAccountCredentials) { // // Use ADC as-is. // this.applicationCredentials = defaultCredentials; - this.applicationPrincipal = new UserId( + this.applicationPrincipal = new UserEmail( ((ServiceAccountCredentials) this.applicationCredentials).getServiceAccountUser()); } else { @@ -272,7 +268,7 @@ public String getProjectNumber() { return projectNumber; } - public UserId getApplicationPrincipal() { + public UserEmail getApplicationPrincipal() { return applicationPrincipal; } diff --git a/sources/src/main/java/com/google/solutions/jitaccess/web/auth/IapAssertion.java b/sources/src/main/java/com/google/solutions/jitaccess/web/auth/IapAssertion.java index 7178d2d69..7227e1689 100644 --- a/sources/src/main/java/com/google/solutions/jitaccess/web/auth/IapAssertion.java +++ b/sources/src/main/java/com/google/solutions/jitaccess/web/auth/IapAssertion.java @@ -23,6 +23,7 @@ import com.google.api.client.json.webtoken.JsonWebSignature; import com.google.api.client.json.webtoken.JsonWebToken; +import com.google.solutions.jitaccess.core.UserEmail; import com.google.solutions.jitaccess.core.UserId; import java.util.Collection; diff --git a/sources/src/main/java/com/google/solutions/jitaccess/web/auth/IapRequestFilter.java b/sources/src/main/java/com/google/solutions/jitaccess/web/auth/IapRequestFilter.java index a9e22e3da..f89262b05 100644 --- a/sources/src/main/java/com/google/solutions/jitaccess/web/auth/IapRequestFilter.java +++ b/sources/src/main/java/com/google/solutions/jitaccess/web/auth/IapRequestFilter.java @@ -23,6 +23,7 @@ import com.google.auth.oauth2.TokenVerifier; import com.google.common.base.Preconditions; +import com.google.solutions.jitaccess.core.UserEmail; import com.google.solutions.jitaccess.core.UserId; import com.google.solutions.jitaccess.web.LogAdapter; import com.google.solutions.jitaccess.web.RuntimeEnvironment; @@ -157,7 +158,7 @@ public String getName() { @Override public UserId getId() { - return new UserId(debugPrincipalName); + return new UserId("debug", debugPrincipalName); } @Override diff --git a/sources/src/main/java/com/google/solutions/jitaccess/web/auth/UserPrincipal.java b/sources/src/main/java/com/google/solutions/jitaccess/web/auth/UserPrincipal.java index c74107adf..8df56fb4e 100644 --- a/sources/src/main/java/com/google/solutions/jitaccess/web/auth/UserPrincipal.java +++ b/sources/src/main/java/com/google/solutions/jitaccess/web/auth/UserPrincipal.java @@ -21,6 +21,7 @@ package com.google.solutions.jitaccess.web.auth; +import com.google.solutions.jitaccess.core.UserEmail; import com.google.solutions.jitaccess.core.UserId; import java.security.Principal; diff --git a/sources/src/main/java/com/google/solutions/jitaccess/web/rest/ApiResource.java b/sources/src/main/java/com/google/solutions/jitaccess/web/rest/ApiResource.java index 4b26d33ab..1d20d633e 100644 --- a/sources/src/main/java/com/google/solutions/jitaccess/web/rest/ApiResource.java +++ b/sources/src/main/java/com/google/solutions/jitaccess/web/rest/ApiResource.java @@ -464,7 +464,7 @@ public ActivationStatusResponse requestActivation( activationRequest = this.projectRoleActivator.createMpaRequest( iapPrincipal.getId(), Set.of(new ProjectRoleBinding(roleBinding)), - request.peers.stream().map(email -> new UserId(email)).collect(Collectors.toSet()), + request.peers.stream().map(email -> new UserEmail(email)).collect(Collectors.toSet()), request.justification, Instant.now().truncatedTo(ChronoUnit.SECONDS), requestedRoleBindingDuration); @@ -798,14 +798,14 @@ private static LogAdapter.LogEntry addLabels( public static class PolicyResponse { public final String justificationHint; - public final UserId signedInUser; + public final UserEmail signedInUser; public String applicationVersion; public final int defaultActivationTimeout; // in minutes. public final int maxActivationTimeout; // in minutes. private PolicyResponse( String justificationHint, - UserId signedInUser, + UserEmail signedInUser, String applicationVersion, int maxActivationTimeoutInMinutes, int defaultActivationTimeoutInMinutes @@ -870,9 +870,9 @@ public ProjectRole( } public static class ProjectRolePeersResponse { - public final Set peers; + public final Set peers; - private ProjectRolePeersResponse(Set peers) { + private ProjectRolePeersResponse(Set peers) { Preconditions.checkNotNull(peers); this.peers = peers; } @@ -892,15 +892,15 @@ public static class ActivationRequest { } public static class ActivationStatusResponse { - public final UserId beneficiary; - public final Collection reviewers; + public final UserEmail beneficiary; + public final Collection reviewers; public final boolean isBeneficiary; public final boolean isReviewer; public final String justification; public final List items; private ActivationStatusResponse( - UserId caller, + UserEmail caller, com.google.solutions.jitaccess.core.catalog.ActivationRequest request, Entitlement.Status status ) { @@ -1014,7 +1014,7 @@ public class ActivationApprovedNotification extends NotificationService.Notifica protected ActivationApprovedNotification( ProjectId projectId, Activation activation, - UserId approver, + UserEmail approver, URL activationRequestUrl) throws MalformedURLException { super( diff --git a/sources/src/test/java/com/google/solutions/jitaccess/core/TestUserEmail.java b/sources/src/test/java/com/google/solutions/jitaccess/core/TestUserEmail.java new file mode 100644 index 000000000..7a3010e06 --- /dev/null +++ b/sources/src/test/java/com/google/solutions/jitaccess/core/TestUserEmail.java @@ -0,0 +1,72 @@ +// +// Copyright 2021 Google LLC +// +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you 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.solutions.jitaccess.core; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +public class TestUserEmail { + + // ------------------------------------------------------------------------- + // Equality. + // ------------------------------------------------------------------------- + + @Test + public void whenObjectAreEquivalent_ThenEqualsReturnsTrue() { + UserEmail id1 = new UserEmail("bob@example.com"); + UserEmail id2 = new UserEmail("bob@example.com"); + + assertTrue(id1.equals(id2)); + assertEquals(id1.hashCode(), id2.hashCode()); + } + + @Test + public void whenObjectAreSame_ThenEqualsReturnsTrue() { + UserEmail id1 = new UserEmail("bob@example.com"); + + assertTrue(id1.equals(id1)); + } + + @Test + public void whenObjectAreMotEquivalent_ThenEqualsReturnsFalse() { + UserEmail id1 = new UserEmail("alice@example.com"); + UserEmail id2 = new UserEmail("bob@example.com"); + + assertFalse(id1.equals(id2)); + assertNotEquals(id1.hashCode(), id2.hashCode()); + } + + @Test + public void whenObjectIsNull_ThenEqualsReturnsFalse() { + UserEmail id1 = new UserEmail("bob@example.com"); + + assertFalse(id1.equals(null)); + } + + @Test + public void whenObjectIsDifferentType_ThenEqualsReturnsFalse() { + UserEmail id1 = new UserEmail("bob@example.com"); + + assertFalse(id1.equals("")); + } +} diff --git a/sources/src/test/java/com/google/solutions/jitaccess/core/TestUserId.java b/sources/src/test/java/com/google/solutions/jitaccess/core/TestUserId.java index 3bad7a729..b3236bb85 100644 --- a/sources/src/test/java/com/google/solutions/jitaccess/core/TestUserId.java +++ b/sources/src/test/java/com/google/solutions/jitaccess/core/TestUserId.java @@ -1,5 +1,5 @@ // -// Copyright 2021 Google LLC +// Copyright 2024 Google LLC // // Licensed to the Apache Software Foundation (ASF) under one // or more contributor license agreements. See the NOTICE file @@ -24,6 +24,7 @@ import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertFalse; public class TestUserId { @@ -49,8 +50,8 @@ public void whenObjectAreSame_ThenEqualsReturnsTrue() { @Test public void whenObjectAreMotEquivalent_ThenEqualsReturnsFalse() { - UserId id1 = new UserId("alice", "alice@example.com"); - UserId id2 = new UserId("bob", "bob@example.com"); + UserId id1 = new UserId("id-1", "bob@example.com"); + UserId id2 = new UserId("id-2", "bob@example.com"); assertFalse(id1.equals(id2)); assertNotEquals(id1.hashCode(), id2.hashCode()); @@ -65,8 +66,9 @@ public void whenObjectIsNull_ThenEqualsReturnsFalse() { @Test public void whenObjectIsDifferentType_ThenEqualsReturnsFalse() { - UserId id1 = new UserId("bob", "bob@example.com"); + var id = new UserId("bob", "bob@example.com"); + var email = new UserEmail("bob@example.com"); - assertFalse(id1.equals("")); + assertFalse(id.equals(email)); } } diff --git a/sources/src/test/java/com/google/solutions/jitaccess/core/catalog/TestActivationRequest.java b/sources/src/test/java/com/google/solutions/jitaccess/core/catalog/TestActivationRequest.java index 791f58a47..492d1bf82 100644 --- a/sources/src/test/java/com/google/solutions/jitaccess/core/catalog/TestActivationRequest.java +++ b/sources/src/test/java/com/google/solutions/jitaccess/core/catalog/TestActivationRequest.java @@ -21,7 +21,7 @@ package com.google.solutions.jitaccess.core.catalog; -import com.google.solutions.jitaccess.core.UserId; +import com.google.solutions.jitaccess.core.UserEmail; import org.junit.jupiter.api.Test; import java.time.Duration; @@ -54,7 +54,7 @@ private class SampleActivationRequest extends ActivationRequest entitlements, String justification, Instant startTime, @@ -76,7 +76,7 @@ public ActivationType type() { public void toStringReturnsSummary() { var request = new SampleActivationRequest( new ActivationId("sample-1"), - new UserId("user@example.com"), + new UserEmail("user@example.com"), Set.of( new SampleEntitlementId("1")), "some justification", diff --git a/sources/src/test/java/com/google/solutions/jitaccess/core/catalog/TestEntitlementActivator.java b/sources/src/test/java/com/google/solutions/jitaccess/core/catalog/TestEntitlementActivator.java index a6f55d667..e5c5861dc 100644 --- a/sources/src/test/java/com/google/solutions/jitaccess/core/catalog/TestEntitlementActivator.java +++ b/sources/src/test/java/com/google/solutions/jitaccess/core/catalog/TestEntitlementActivator.java @@ -24,7 +24,7 @@ import com.google.solutions.jitaccess.core.AccessDeniedException; import com.google.solutions.jitaccess.core.AccessException; import com.google.solutions.jitaccess.core.AlreadyExistsException; -import com.google.solutions.jitaccess.core.UserId; +import com.google.solutions.jitaccess.core.UserEmail; import org.junit.jupiter.api.Test; import org.mockito.Mockito; @@ -39,9 +39,9 @@ import static org.mockito.Mockito.verify; public class TestEntitlementActivator { - private static final UserId SAMPLE_REQUESTING_USER = new UserId("user@example.com"); - private static final UserId SAMPLE_APPROVING_USER = new UserId("peer@example.com"); - private static final UserId SAMPLE_UNKNOWN_USER = new UserId("unknown@example.com"); + private static final UserEmail SAMPLE_REQUESTING_USER = new UserEmail("user@example.com"); + private static final UserEmail SAMPLE_APPROVING_USER = new UserEmail("peer@example.com"); + private static final UserEmail SAMPLE_UNKNOWN_USER = new UserEmail("unknown@example.com"); private class SampleActivator extends EntitlementActivator { protected SampleActivator( @@ -59,7 +59,7 @@ protected void provisionAccess( @Override protected void provisionAccess( - UserId approvingUser, + UserEmail approvingUser, MpaActivationRequest request ) throws AccessException, AlreadyExistsException, IOException { } diff --git a/sources/src/test/java/com/google/solutions/jitaccess/core/catalog/TestRegexActivationPolicy.java b/sources/src/test/java/com/google/solutions/jitaccess/core/catalog/TestRegexActivationPolicy.java index e8fe85790..3750c012b 100644 --- a/sources/src/test/java/com/google/solutions/jitaccess/core/catalog/TestRegexActivationPolicy.java +++ b/sources/src/test/java/com/google/solutions/jitaccess/core/catalog/TestRegexActivationPolicy.java @@ -21,7 +21,7 @@ package com.google.solutions.jitaccess.core.catalog; -import com.google.solutions.jitaccess.core.UserId; +import com.google.solutions.jitaccess.core.UserEmail; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ValueSource; @@ -32,7 +32,7 @@ public class TestRegexActivationPolicy { - private static final UserId SAMPLE_USER = new UserId("user@example.com"); + private static final UserEmail SAMPLE_USER = new UserEmail("user@example.com"); // ------------------------------------------------------------------------- // checkJustification. diff --git a/sources/src/test/java/com/google/solutions/jitaccess/core/catalog/TestTokenSigner.java b/sources/src/test/java/com/google/solutions/jitaccess/core/catalog/TestTokenSigner.java index 2860c8387..303820350 100644 --- a/sources/src/test/java/com/google/solutions/jitaccess/core/catalog/TestTokenSigner.java +++ b/sources/src/test/java/com/google/solutions/jitaccess/core/catalog/TestTokenSigner.java @@ -23,7 +23,7 @@ import com.google.api.client.json.webtoken.JsonWebToken; import com.google.auth.oauth2.TokenVerifier; -import com.google.solutions.jitaccess.core.UserId; +import com.google.solutions.jitaccess.core.UserEmail; import com.google.solutions.jitaccess.core.clients.HttpTransport; import com.google.solutions.jitaccess.core.clients.IamCredentialsClient; import com.google.solutions.jitaccess.core.clients.IntegrationTestEnvironment; @@ -35,9 +35,9 @@ import static org.junit.jupiter.api.Assertions.*; public class TestTokenSigner { - private static final UserId SAMPLE_USER_1 = new UserId("user-1@example.com"); - private static final UserId SAMPLE_USER_2 = new UserId("user-2@example.com"); - private static final UserId SAMPLE_USER_3 = new UserId("user-3@example.com"); + private static final UserEmail SAMPLE_USER_1 = new UserEmail("user-1@example.com"); + private static final UserEmail SAMPLE_USER_2 = new UserEmail("user-2@example.com"); + private static final UserEmail SAMPLE_USER_3 = new UserEmail("user-3@example.com"); private static class PseudoJsonConverter implements JsonWebTokenConverter { @Override diff --git a/sources/src/test/java/com/google/solutions/jitaccess/core/catalog/project/TestAssetInventoryRepository.java b/sources/src/test/java/com/google/solutions/jitaccess/core/catalog/project/TestAssetInventoryRepository.java index cd518e27f..efdb20d1a 100644 --- a/sources/src/test/java/com/google/solutions/jitaccess/core/catalog/project/TestAssetInventoryRepository.java +++ b/sources/src/test/java/com/google/solutions/jitaccess/core/catalog/project/TestAssetInventoryRepository.java @@ -51,7 +51,7 @@ import static org.mockito.Mockito.when; public class TestAssetInventoryRepository { - private static final UserId SAMPLE_USER = new UserId("user-1@example.com"); + private static final UserEmail SAMPLE_USER = new UserEmail("user-1@example.com"); private static final ProjectId SAMPLE_PROJECT = new ProjectId("project-1"); private static final String JIT_CONDITION = "has({}.jitAccessConstraint)"; private static final String MPA_CONDITION = "has({}.multiPartyApprovalConstraint)"; @@ -570,7 +570,7 @@ public void whenEffectiveIamPoliciesContainUsers_ThenFindEntitlementHoldersRetur assertNotNull(holders); assertEquals( - Set.of(new UserId("user-1@example.com"), new UserId("user-2@example.com")), + Set.of(new UserEmail("user-1@example.com"), new UserEmail("user-2@example.com")), holders); } @@ -620,7 +620,7 @@ public void whenEffectiveIamPoliciesContainsGroups_ThenFindEntitlementHoldersRet assertNotNull(holders); assertEquals( - Set.of(new UserId("user-1@example.com"), new UserId("user-2@example.com")), + Set.of(new UserEmail("user-1@example.com"), new UserEmail("user-2@example.com")), holders); } } diff --git a/sources/src/test/java/com/google/solutions/jitaccess/core/catalog/project/TestMpaProjectRoleCatalog.java b/sources/src/test/java/com/google/solutions/jitaccess/core/catalog/project/TestMpaProjectRoleCatalog.java index a47171961..483201c7f 100644 --- a/sources/src/test/java/com/google/solutions/jitaccess/core/catalog/project/TestMpaProjectRoleCatalog.java +++ b/sources/src/test/java/com/google/solutions/jitaccess/core/catalog/project/TestMpaProjectRoleCatalog.java @@ -24,7 +24,7 @@ import com.google.solutions.jitaccess.core.AccessDeniedException; import com.google.solutions.jitaccess.core.ProjectId; import com.google.solutions.jitaccess.core.RoleBinding; -import com.google.solutions.jitaccess.core.UserId; +import com.google.solutions.jitaccess.core.UserEmail; import com.google.solutions.jitaccess.core.catalog.*; import com.google.solutions.jitaccess.core.clients.ResourceManagerClient; import org.junit.jupiter.api.Test; @@ -42,8 +42,8 @@ public class TestMpaProjectRoleCatalog { - private static final UserId SAMPLE_REQUESTING_USER = new UserId("user@example.com"); - private static final UserId SAMPLE_APPROVIING_USER = new UserId("approver@example.com"); + private static final UserEmail SAMPLE_REQUESTING_USER = new UserEmail("user@example.com"); + private static final UserEmail SAMPLE_APPROVIING_USER = new UserEmail("approver@example.com"); private static final ProjectId SAMPLE_PROJECT = new ProjectId("project-1"); private static final String SAMPLE_ROLE = "roles/resourcemanager.role1"; @@ -127,9 +127,9 @@ public void whenNumberOfReviewersExceedsMax_ThenValidateRequestThrowsException() var request = Mockito.mock(MpaActivationRequest.class); when(request.duration()).thenReturn(catalog.options().minActivationDuration()); when(request.reviewers()).thenReturn(Set.of( - new UserId("user-1@example.com"), - new UserId("user-2@example.com"), - new UserId("user-3@example.com"))); + new UserEmail("user-1@example.com"), + new UserEmail("user-2@example.com"), + new UserEmail("user-3@example.com"))); assertThrows( IllegalArgumentException.class, @@ -151,7 +151,7 @@ public void whenNumberOfReviewersBelowMin_ThenValidateRequestThrowsException() t var request = Mockito.mock(MpaActivationRequest.class); when(request.duration()).thenReturn(catalog.options().minActivationDuration()); when(request.reviewers()).thenReturn(Set.of( - new UserId("user-1@example.com"))); + new UserEmail("user-1@example.com"))); assertThrows( IllegalArgumentException.class, @@ -173,7 +173,7 @@ public void whenNumberOfReviewersOk_ThenValidateRequestReturns() throws Exceptio var request = Mockito.mock(MpaActivationRequest.class); when(request.duration()).thenReturn(catalog.options().minActivationDuration()); when(request.reviewers()).thenReturn(Set.of( - new UserId("user-1@example.com"))); + new UserEmail("user-1@example.com"))); catalog.validateRequest(request); } diff --git a/sources/src/test/java/com/google/solutions/jitaccess/core/catalog/project/TestPolicyAnalyzerRepository.java b/sources/src/test/java/com/google/solutions/jitaccess/core/catalog/project/TestPolicyAnalyzerRepository.java index 301e46633..17caf48f2 100644 --- a/sources/src/test/java/com/google/solutions/jitaccess/core/catalog/project/TestPolicyAnalyzerRepository.java +++ b/sources/src/test/java/com/google/solutions/jitaccess/core/catalog/project/TestPolicyAnalyzerRepository.java @@ -25,7 +25,7 @@ import com.google.solutions.jitaccess.cel.TemporaryIamCondition; import com.google.solutions.jitaccess.core.ProjectId; import com.google.solutions.jitaccess.core.RoleBinding; -import com.google.solutions.jitaccess.core.UserId; +import com.google.solutions.jitaccess.core.UserEmail; import com.google.solutions.jitaccess.core.catalog.ActivationType; import com.google.solutions.jitaccess.core.catalog.Entitlement; import com.google.solutions.jitaccess.core.clients.PolicyAnalyzerClient; @@ -45,9 +45,9 @@ import static org.mockito.Mockito.when; public class TestPolicyAnalyzerRepository { - private static final UserId SAMPLE_USER = new UserId("user-1", "user-1@example.com"); - private static final UserId SAMPLE_APPROVING_USER_1 = new UserId("approver-1", "approver-1@example.com"); - private static final UserId SAMPLE_APPROVING_USER_2 = new UserId("approver-2", "approver-2@example.com"); + private static final UserEmail SAMPLE_USER = new UserEmail("user-1@example.com"); + private static final UserEmail SAMPLE_APPROVING_USER_1 = new UserEmail("approver-1@example.com"); + private static final UserEmail SAMPLE_APPROVING_USER_2 = new UserEmail("approver-2@example.com"); private static final ProjectId SAMPLE_PROJECT_ID_1 = new ProjectId("project-1"); private static final ProjectId SAMPLE_PROJECT_ID_2 = new ProjectId("project-2"); private static final String SAMPLE_ROLE_1 = "roles/resourcemanager.role1"; @@ -62,7 +62,7 @@ public class TestPolicyAnalyzerRepository { private static IamPolicyAnalysisResult createIamPolicyAnalysisResult( String resource, String role, - UserId user + UserEmail user ) { return new IamPolicyAnalysisResult() .setAttachedResourceFullName(resource) @@ -77,7 +77,7 @@ private static IamPolicyAnalysisResult createIamPolicyAnalysisResult( private static IamPolicyAnalysisResult createConditionalIamPolicyAnalysisResult( String resource, String role, - UserId user, + UserEmail user, String condition, String conditionTitle, String evaluationResult diff --git a/sources/src/test/java/com/google/solutions/jitaccess/core/catalog/project/TestProjectRoleActivator.java b/sources/src/test/java/com/google/solutions/jitaccess/core/catalog/project/TestProjectRoleActivator.java index c00d14140..f4b014756 100644 --- a/sources/src/test/java/com/google/solutions/jitaccess/core/catalog/project/TestProjectRoleActivator.java +++ b/sources/src/test/java/com/google/solutions/jitaccess/core/catalog/project/TestProjectRoleActivator.java @@ -24,7 +24,7 @@ import com.google.solutions.jitaccess.cel.TemporaryIamCondition; import com.google.solutions.jitaccess.core.ProjectId; import com.google.solutions.jitaccess.core.RoleBinding; -import com.google.solutions.jitaccess.core.UserId; +import com.google.solutions.jitaccess.core.UserEmail; import com.google.solutions.jitaccess.core.catalog.EntitlementCatalog; import com.google.solutions.jitaccess.core.catalog.JustificationPolicy; import com.google.solutions.jitaccess.core.clients.ResourceManagerClient; @@ -44,8 +44,8 @@ public class TestProjectRoleActivator { - private static final UserId SAMPLE_REQUESTING_USER = new UserId("user@example.com"); - private static final UserId SAMPLE_APPROVING_USER = new UserId("approver@example.com"); + private static final UserEmail SAMPLE_REQUESTING_USER = new UserEmail("user@example.com"); + private static final UserEmail SAMPLE_APPROVING_USER = new UserEmail("approver@example.com"); private static final ProjectId SAMPLE_PROJECT = new ProjectId("project-1"); private static final String SAMPLE_ROLE_1 = "roles/resourcemanager.role1"; private static final String SAMPLE_ROLE_2 = "roles/resourcemanager.role2"; diff --git a/sources/src/test/java/com/google/solutions/jitaccess/core/clients/IntegrationTestEnvironment.java b/sources/src/test/java/com/google/solutions/jitaccess/core/clients/IntegrationTestEnvironment.java index 31b187218..68c491bff 100644 --- a/sources/src/test/java/com/google/solutions/jitaccess/core/clients/IntegrationTestEnvironment.java +++ b/sources/src/test/java/com/google/solutions/jitaccess/core/clients/IntegrationTestEnvironment.java @@ -26,7 +26,7 @@ import com.google.auth.oauth2.ImpersonatedCredentials; import com.google.common.base.Strings; import com.google.solutions.jitaccess.core.ProjectId; -import com.google.solutions.jitaccess.core.UserId; +import com.google.solutions.jitaccess.core.UserEmail; import java.io.File; import java.io.FileInputStream; @@ -56,12 +56,12 @@ public void refresh() { /** * Service account that tests can use to grant temporary access to. */ - public static final UserId TEMPORARY_ACCESS_USER; + public static final UserEmail TEMPORARY_ACCESS_USER; /** * Service account that doesn't have access to anything. */ - public static final UserId NO_ACCESS_USER; + public static final UserEmail NO_ACCESS_USER; public static final PubSubTopic PUBSUB_TOPIC; @@ -81,12 +81,10 @@ public void refresh() { PROJECT_ID = new ProjectId(getMandatory(settings, "test.project")); - NO_ACCESS_USER = new UserId( - "no-access", + NO_ACCESS_USER = new UserEmail( String.format("%s@%s.iam.gserviceaccount.com", "no-access", PROJECT_ID)); - TEMPORARY_ACCESS_USER = new UserId( - "temporary-access", + TEMPORARY_ACCESS_USER = new UserEmail( String.format("%s@%s.iam.gserviceaccount.com", "temporary-access", PROJECT_ID)); var defaultCredentials = GoogleCredentials diff --git a/sources/src/test/java/com/google/solutions/jitaccess/core/clients/TestPolicyAnalyzerClient.java b/sources/src/test/java/com/google/solutions/jitaccess/core/clients/TestPolicyAnalyzerClient.java index 809fb77ca..681faaee2 100644 --- a/sources/src/test/java/com/google/solutions/jitaccess/core/clients/TestPolicyAnalyzerClient.java +++ b/sources/src/test/java/com/google/solutions/jitaccess/core/clients/TestPolicyAnalyzerClient.java @@ -23,7 +23,7 @@ import com.google.solutions.jitaccess.core.AccessDeniedException; import com.google.solutions.jitaccess.core.NotAuthenticatedException; -import com.google.solutions.jitaccess.core.UserId; +import com.google.solutions.jitaccess.core.UserEmail; import org.junit.jupiter.api.Test; import java.net.SocketTimeoutException; @@ -48,7 +48,7 @@ public void whenUnauthenticated_ThenFindAccessibleResourcesByUserThrowsException NotAuthenticatedException.class, () -> adapter.findAccessibleResourcesByUser( "projects/0", - new UserId("", "bob@example.com"), + new UserEmail("bob@example.com"), Optional.empty(), Optional.empty(), true)); @@ -64,7 +64,7 @@ public void whenCallerLacksPermission_ThenFindAccessibleResourcesByUserThrowsExc AccessDeniedException.class, () -> adapter.findAccessibleResourcesByUser( "projects/0", - new UserId("", "bob@example.com"), + new UserEmail("bob@example.com"), Optional.empty(), Optional.empty(), true)); @@ -83,7 +83,7 @@ public void whenRequestTimesOut_ThenFindAccessibleResourcesByUserThrowsException SocketTimeoutException.class, () -> adapter.findAccessibleResourcesByUser( "projects/0", - new UserId("", "bob@example.com"), + new UserEmail("bob@example.com"), Optional.empty(), Optional.empty(), true)); @@ -97,7 +97,7 @@ public void whenPermissionDoesNotExist_ThenFindAccessibleResourcesByUserReturnsE var result = adapter.findAccessibleResourcesByUser( "projects/" + IntegrationTestEnvironment.PROJECT_ID, - new UserId("", "bob@example.com"), + new UserEmail("bob@example.com"), Optional.of("invalid.invalid.invalid"), Optional.empty(), true); @@ -114,7 +114,7 @@ public void whenResourceDoesNotExist_ThenFindAccessibleResourcesByUserReturnsEmp var result = adapter.findAccessibleResourcesByUser( "projects/" + IntegrationTestEnvironment.PROJECT_ID, - new UserId("", "bob@example.com"), + new UserEmail("bob@example.com"), Optional.empty(), Optional.of("//cloudresourcemanager.googleapis.com/projects/000-invalid"), true); diff --git a/sources/src/test/java/com/google/solutions/jitaccess/core/notifications/TestMailNotificationService.java b/sources/src/test/java/com/google/solutions/jitaccess/core/notifications/TestMailNotificationService.java index 1d6031ede..da36aa229 100644 --- a/sources/src/test/java/com/google/solutions/jitaccess/core/notifications/TestMailNotificationService.java +++ b/sources/src/test/java/com/google/solutions/jitaccess/core/notifications/TestMailNotificationService.java @@ -21,7 +21,7 @@ package com.google.solutions.jitaccess.core.notifications; -import com.google.solutions.jitaccess.core.UserId; +import com.google.solutions.jitaccess.core.UserEmail; import com.google.solutions.jitaccess.core.clients.SmtpClient; import org.junit.jupiter.api.Test; import org.mockito.Mockito; @@ -42,7 +42,7 @@ private static class TestNotification extends NotificationService.Notification { private final String templateId; protected TestNotification( - UserId recipient, + UserEmail recipient, String subject, Map properties, String templateId @@ -72,7 +72,7 @@ public void whenTemplateNotFound_ThenSendNotificationDoesNotSendMail() throws Ex mailAdapter, new MailNotificationService.Options(MailNotificationService.Options.DEFAULT_TIMEZONE)); - var to = new UserId("user@example.com"); + var to = new UserEmail("user@example.com"); service.sendNotification(new TestNotification( to, "Test email", @@ -94,7 +94,7 @@ public void whenTemplateFound_ThenSendNotificationSendsMail() throws Exception { mailAdapter, new MailNotificationService.Options(MailNotificationService.Options.DEFAULT_TIMEZONE)); - var to = new UserId("user@example.com"); + var to = new UserEmail("user@example.com"); service.sendNotification(new TestNotification( to, "Test email", diff --git a/sources/src/test/java/com/google/solutions/jitaccess/core/notifications/TestMessageTemplate.java b/sources/src/test/java/com/google/solutions/jitaccess/core/notifications/TestMessageTemplate.java index 1ac9fdf60..5f1dc9cef 100644 --- a/sources/src/test/java/com/google/solutions/jitaccess/core/notifications/TestMessageTemplate.java +++ b/sources/src/test/java/com/google/solutions/jitaccess/core/notifications/TestMessageTemplate.java @@ -22,7 +22,7 @@ package com.google.solutions.jitaccess.core.notifications; import com.google.common.html.HtmlEscapers; -import com.google.solutions.jitaccess.core.UserId; +import com.google.solutions.jitaccess.core.UserEmail; import org.junit.jupiter.api.Test; import java.time.Instant; @@ -39,7 +39,7 @@ private static class TestNotification extends NotificationService.Notification { private final String templateId; protected TestNotification( - UserId recipient, + UserEmail recipient, String subject, Map properties, String templateId @@ -69,7 +69,7 @@ public void whenPropertiesContainHtmlTags_ThenFormatEscapesTags() { properties.put("TEST-2", ""); var notification = new TestNotification( - new UserId("user@example.com"), + new UserEmail("user@example.com"), "Test email", properties, "ignored-templateid"); @@ -94,7 +94,7 @@ public void whenPropertiesContainDates_ThenFormatAppliesTimezone() { properties.put("TEST-1", Instant.ofEpochSecond(86400)); var notification = new TestNotification( - new UserId("user@example.com"), + new UserEmail("user@example.com"), "Test email", properties, "ignored-templateid"); diff --git a/sources/src/test/java/com/google/solutions/jitaccess/core/notifications/TestPubSubNotificationService.java b/sources/src/test/java/com/google/solutions/jitaccess/core/notifications/TestPubSubNotificationService.java index a9ee3a9c3..79868e46a 100644 --- a/sources/src/test/java/com/google/solutions/jitaccess/core/notifications/TestPubSubNotificationService.java +++ b/sources/src/test/java/com/google/solutions/jitaccess/core/notifications/TestPubSubNotificationService.java @@ -21,7 +21,7 @@ package com.google.solutions.jitaccess.core.notifications; -import com.google.solutions.jitaccess.core.UserId; +import com.google.solutions.jitaccess.core.UserEmail; import com.google.solutions.jitaccess.core.clients.PubSubClient; import com.google.solutions.jitaccess.core.clients.PubSubTopic; import org.junit.jupiter.api.Test; @@ -45,8 +45,8 @@ public class TestPubSubNotificationService { private class SampleNotification extends NotificationService.Notification { protected SampleNotification( - Collection toRecipients, - Collection ccRecipients, + Collection toRecipients, + Collection ccRecipients, String subject) { super(toRecipients, ccRecipients, subject); @@ -54,7 +54,7 @@ protected SampleNotification( this.properties.put("instant", Instant.ofEpochSecond(0)); this.properties.put( "user_list", - List.of(new UserId("alice@example.com"), new UserId("bob@example.com"))); + List.of(new UserEmail("alice@example.com"), new UserEmail("bob@example.com"))); } @Override @@ -73,8 +73,8 @@ public void sendNotificationPublishesToPubSub() throws Exception { service.sendNotification( new SampleNotification( - List.of(new UserId("to@example.com")), - List.of(new UserId("cc@example.com")), + List.of(new UserEmail("to@example.com")), + List.of(new UserEmail("cc@example.com")), "subject")); var expectedMessage = diff --git a/sources/src/test/java/com/google/solutions/jitaccess/web/TestLogAdapter.java b/sources/src/test/java/com/google/solutions/jitaccess/web/TestLogAdapter.java index d8aa7e0ee..53a6db6a1 100644 --- a/sources/src/test/java/com/google/solutions/jitaccess/web/TestLogAdapter.java +++ b/sources/src/test/java/com/google/solutions/jitaccess/web/TestLogAdapter.java @@ -21,6 +21,7 @@ package com.google.solutions.jitaccess.web; +import com.google.solutions.jitaccess.core.UserEmail; import com.google.solutions.jitaccess.core.UserId; import com.google.solutions.jitaccess.web.auth.DeviceInfo; import com.google.solutions.jitaccess.web.auth.UserPrincipal; diff --git a/sources/src/test/java/com/google/solutions/jitaccess/web/rest/RestDispatcher.java b/sources/src/test/java/com/google/solutions/jitaccess/web/rest/RestDispatcher.java index 15f69f515..f81740530 100644 --- a/sources/src/test/java/com/google/solutions/jitaccess/web/rest/RestDispatcher.java +++ b/sources/src/test/java/com/google/solutions/jitaccess/web/rest/RestDispatcher.java @@ -22,6 +22,7 @@ package com.google.solutions.jitaccess.web.rest; import com.google.gson.Gson; +import com.google.solutions.jitaccess.core.UserEmail; import com.google.solutions.jitaccess.core.UserId; import com.google.solutions.jitaccess.web.auth.DeviceInfo; import com.google.solutions.jitaccess.web.auth.UserPrincipal; diff --git a/sources/src/test/java/com/google/solutions/jitaccess/web/rest/TestApiResource.java b/sources/src/test/java/com/google/solutions/jitaccess/web/rest/TestApiResource.java index 4155199a1..f32dfaaa9 100644 --- a/sources/src/test/java/com/google/solutions/jitaccess/web/rest/TestApiResource.java +++ b/sources/src/test/java/com/google/solutions/jitaccess/web/rest/TestApiResource.java @@ -22,10 +22,7 @@ package com.google.solutions.jitaccess.web.rest; import com.google.auth.oauth2.TokenVerifier; -import com.google.solutions.jitaccess.core.AccessDeniedException; -import com.google.solutions.jitaccess.core.ProjectId; -import com.google.solutions.jitaccess.core.RoleBinding; -import com.google.solutions.jitaccess.core.UserId; +import com.google.solutions.jitaccess.core.*; import com.google.solutions.jitaccess.core.catalog.*; import com.google.solutions.jitaccess.core.catalog.project.MpaProjectRoleCatalog; import com.google.solutions.jitaccess.core.catalog.project.ProjectRoleActivator; @@ -57,8 +54,8 @@ import static org.mockito.Mockito.*; public class TestApiResource { - private static final UserId SAMPLE_USER = new UserId("user-1@example.com"); - private static final UserId SAMPLE_USER_2 = new UserId("user-2@example.com"); + private static final UserId SAMPLE_USER = new UserId("user-1", "user-1@example.com"); + private static final UserId SAMPLE_USER_2 = new UserId("user-2", "user-2@example.com"); private static final String SAMPLE_TOKEN = "eySAMPLE"; private static final Pattern DEFAULT_JUSTIFICATION_PATTERN = Pattern.compile("pattern"); @@ -306,7 +303,7 @@ public void whenPeerDiscoveryReturnsProjects_ThenListPeersReturnsList() throws E .listReviewers( eq(SAMPLE_USER), argThat(r -> r.roleBinding().role().equals("roles/browser")))) - .thenReturn(new TreeSet(Set.of(new UserId("peer-1@example.com"), new UserId("peer-2@example.com")))); + .thenReturn(new TreeSet(Set.of(new UserEmail("peer-1@example.com"), new UserEmail("peer-2@example.com")))); var response = new RestDispatcher<>(this.resource, SAMPLE_USER) .get("/api/projects/project-1/peers?role=roles/browser", ApiResource.ProjectRolePeersResponse.class); @@ -951,7 +948,9 @@ public void whenCallerNotInvolvedInRequest_ThenGetActivationRequestReturnsError( eq(SAMPLE_TOKEN))) .thenReturn(request); - var response = new RestDispatcher<>(this.resource, new UserId("other-party@example.com")) + var response = new RestDispatcher<>( + this.resource, + new UserId("other-party", "other-party@example.com")) .get( "/api/activation-request?activation=" + TokenObfuscator.encode(SAMPLE_TOKEN), ExceptionMappers.ErrorEntity.class);