Skip to content

Commit

Permalink
b/316247020 Convert data classes to records (#218)
Browse files Browse the repository at this point in the history
* Convert DeviceInfo
* Convert ProjectId
* Convert ProjectRole
* Convert RoleBinding
* Convert Topic
  • Loading branch information
jpassing authored Dec 14, 2023
1 parent 93bfcc7 commit e3ecde1
Show file tree
Hide file tree
Showing 16 changed files with 130 additions and 192 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -123,9 +123,9 @@ private LogEntry(
if (principal != null) {
this.labels.put("user", principal.getId().email);
this.labels.put("user_id", principal.getId().id);
this.labels.put("device_id", principal.getDevice().getDeviceId());
this.labels.put("device_id", principal.getDevice().deviceId());
this.labels.put("device_access_levels",
String.join(", ", principal.getDevice().getAccessLevels()));
String.join(", ", principal.getDevice().accessLevels()));
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ public void addProjectIamBinding(
var policy = service
.projects()
.getIamPolicy(
String.format("projects/%s", projectId.id),
String.format("projects/%s", projectId.id()),
new GetIamPolicyRequest()
.setOptions(new GetPolicyOptions().setRequestedPolicyVersion(3)))
.execute();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,33 +24,16 @@
import com.google.common.base.Preconditions;

import java.util.List;
import java.util.Objects;

/**
* Information about the device of a user.
*/
public class DeviceInfo {
public record DeviceInfo(String deviceId, List<String> accessLevels) {
public static final DeviceInfo UNKNOWN = new DeviceInfo("unknown", List.of());
private final String deviceId;
private final List<String> accessLevels;

public DeviceInfo(
String deviceId,
List<String> accessLevels
) {
public DeviceInfo {
Preconditions.checkNotNull(deviceId, "deviceId");
Preconditions.checkNotNull(accessLevels, "accessLevels");

this.deviceId = deviceId;
this.accessLevels = accessLevels;
}

public String getDeviceId() {
return this.deviceId;
}

public List<String> getAccessLevels() {
return accessLevels;
}

@Override
Expand All @@ -69,9 +52,4 @@ public boolean equals(Object o) {
var that = (DeviceInfo) o;
return deviceId.equals(that.deviceId) && accessLevels.equals(that.accessLevels);
}

@Override
public int hashCode() {
return Objects.hash(deviceId, accessLevels);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,21 +23,16 @@

import com.google.common.base.Preconditions;

import java.util.Objects;

/**
* Project ID for a Google Cloud project.
*/
public class ProjectId implements Comparable<ProjectId> {
public record ProjectId(String id) implements Comparable<ProjectId> {
private static final String PROJECT_RESOURCE_NAME_PREFIX = "//cloudresourcemanager.googleapis.com/projects/";

public final String id;

public ProjectId(String id) {
public ProjectId {
Preconditions.checkNotNull(id, "id");
assert !id.startsWith("//");

this.id = id;
}

@Override
Expand Down Expand Up @@ -73,28 +68,9 @@ public static boolean isProjectFullResourceName(String fullResourceName) {
}

// -------------------------------------------------------------------------
// Equality.
// Comparable.
// -------------------------------------------------------------------------

@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}

if (o == null || getClass() != o.getClass()) {
return false;
}

ProjectId projectId = (ProjectId) o;
return this.id.equals(projectId.id);
}

@Override
public int hashCode() {
return Objects.hash(this.id);
}

@Override
public int compareTo(ProjectId o) {
return this.id.compareTo(o.id);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,22 +23,18 @@

import com.google.common.base.Preconditions;

import java.util.Objects;

/**
* Represents an eligible role on a project.
*/
public class ProjectRole implements Comparable<ProjectRole> {
public final RoleBinding roleBinding;
public final Status status;
public record ProjectRole(
RoleBinding roleBinding,
ProjectRole.Status status
) implements Comparable<ProjectRole> {

public ProjectRole(RoleBinding roleBinding, Status status) {
public ProjectRole {
Preconditions.checkNotNull(roleBinding);
Preconditions.checkNotNull(status);
Preconditions.checkArgument(ProjectId.isProjectFullResourceName(roleBinding.fullResourceName));

this.roleBinding = roleBinding;
this.status = status;
Preconditions.checkArgument(ProjectId.isProjectFullResourceName(roleBinding.fullResourceName()));
}

@Override
Expand All @@ -50,7 +46,7 @@ public String toString() {
* Return the unqualified project ID.
*/
public ProjectId getProjectId() {
return ProjectId.fromFullResourceName(this.roleBinding.fullResourceName);
return ProjectId.fromFullResourceName(this.roleBinding.fullResourceName());
}

// -------------------------------------------------------------------------
Expand All @@ -71,11 +67,6 @@ public boolean equals(Object o) {
return this.roleBinding.equals(that.roleBinding) && this.status.equals(that.status);
}

@Override
public int hashCode() {
return Objects.hash(this.roleBinding, this.status);
}

@Override
public int compareTo(ProjectRole o) {
return this.roleBinding.compareTo(o.roleBinding);
Expand All @@ -86,16 +77,24 @@ public int compareTo(ProjectRole o) {
// -------------------------------------------------------------------------

public enum Status {
/** Role binding can be activated using self-approval ("JIT approval") */
/**
* Role binding can be activated using self-approval ("JIT approval")
*/
ELIGIBLE_FOR_JIT,

/** Role binding can be activated using multi party-approval ("MPA approval") */
/**
* Role binding can be activated using multi party-approval ("MPA approval")
*/
ELIGIBLE_FOR_MPA,

/** Eligible role binding has been activated */
/**
* Eligible role binding has been activated
*/
ACTIVATED,

/** Approval pending */
/**
* Approval pending
*/
ACTIVATION_PENDING
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,23 +24,19 @@
import com.google.common.base.Preconditions;

import java.util.Comparator;
import java.util.Objects;

/**
* Represents a role that has been granted on a resource.
*/
public class RoleBinding implements Comparable<RoleBinding> {
public final String fullResourceName;
public final String role;

public RoleBinding(String fullResourceName, String role) {
Preconditions.checkNotNull(fullResourceName);
Preconditions.checkNotNull(role);

this.fullResourceName = fullResourceName;
this.role = role;
public record RoleBinding (
String fullResourceName,
String role
) implements Comparable<RoleBinding> {

public RoleBinding {
Preconditions.checkNotNull(fullResourceName, "fullResourceName");
Preconditions.checkNotNull(role, "role");
}

public RoleBinding(ProjectId project, String role) {
this(project.getFullResourceName(), role);
}
Expand All @@ -51,28 +47,9 @@ public String toString() {
}

// -------------------------------------------------------------------------
// Equality.
// Comparable.
// -------------------------------------------------------------------------

@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}

if (o == null || getClass() != o.getClass()) {
return false;
}

var that = (RoleBinding) o;
return this.fullResourceName.equals(that.fullResourceName) && this.role.equals(that.role);
}

@Override
public int hashCode() {
return Objects.hash(this.fullResourceName, this.role);
}

@Override
public int compareTo(RoleBinding o) {
return Comparator.comparing((RoleBinding r) -> r.fullResourceName)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,15 @@

package com.google.solutions.jitaccess.core.data;

import com.google.common.base.Preconditions;

public record Topic(String projectId, String topicName) {

public Topic {
Preconditions.checkNotNull(projectId, "projectId");
Preconditions.checkNotNull(topicName, "topicName");
}

@Override
public String toString() {
return getFullResourceName();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,8 @@ private static boolean canActivateProjectRole(
ActivationType activationType
) {
switch (activationType) {
case JIT: return projectRole.status == ProjectRole.Status.ELIGIBLE_FOR_JIT;
case MPA: return projectRole.status == ProjectRole.Status.ELIGIBLE_FOR_MPA;
case JIT: return projectRole.status() == ProjectRole.Status.ELIGIBLE_FOR_JIT;
case MPA: return projectRole.status() == ProjectRole.Status.ELIGIBLE_FOR_MPA;
default: return false;
}
}
Expand All @@ -94,21 +94,21 @@ private void checkUserCanActivateProjectRole(
//
if (this.roleDiscoveryService.listEligibleProjectRoles(
user,
ProjectId.fromFullResourceName(roleBinding.fullResourceName),
ProjectId.fromFullResourceName(roleBinding.fullResourceName()),
EnumSet.of(
ProjectRole.Status.ELIGIBLE_FOR_JIT,
ProjectRole.Status.ELIGIBLE_FOR_MPA))
.getItems()
.stream()
.filter(pr -> pr.roleBinding.equals(roleBinding))
.filter(pr -> pr.roleBinding().equals(roleBinding))
.filter(pr -> canActivateProjectRole(pr, activationType))
.findAny()
.isEmpty()) {
throw new AccessDeniedException(
String.format(
"The user %s is not allowed to activate the role %s",
user,
roleBinding.role));
roleBinding.role()));
}
}

Expand Down Expand Up @@ -139,7 +139,7 @@ public Activation activateProjectRoleForSelf(
Preconditions.checkNotNull(caller, "caller");
Preconditions.checkNotNull(roleBinding, "roleBinding");
Preconditions.checkNotNull(justification, "justification");
Preconditions.checkArgument(ProjectId.isProjectFullResourceName(roleBinding.fullResourceName));
Preconditions.checkArgument(ProjectId.isProjectFullResourceName(roleBinding.fullResourceName()));
Preconditions.checkArgument(activationTimeout.toMinutes() >= Options.MIN_ACTIVATION_TIMEOUT_MINUTES,
"The activation timeout is too short");
Preconditions.checkArgument(activationTimeout.toMinutes() <= this.options.maxActivationTimeout.toMinutes(),
Expand Down Expand Up @@ -179,14 +179,14 @@ public Activation activateProjectRoleForSelf(

var binding = new Binding()
.setMembers(List.of("user:" + caller))
.setRole(roleBinding.role)
.setRole(roleBinding.role())
.setCondition(new com.google.api.services.cloudresourcemanager.v3.model.Expr()
.setTitle(JitConstraints.ACTIVATION_CONDITION_TITLE)
.setDescription(bindingDescription)
.setExpression(IamTemporaryAccessConditions.createExpression(activationTime, expiryTime)));

this.resourceManagerAdapter.addProjectIamBinding(
ProjectId.fromFullResourceName(roleBinding.fullResourceName),
ProjectId.fromFullResourceName(roleBinding.fullResourceName()),
binding,
EnumSet.of(ResourceManagerAdapter.IamBindingOptions.PURGE_EXISTING_TEMPORARY_BINDINGS),
justification);
Expand Down Expand Up @@ -253,7 +253,7 @@ public Activation activateProjectRoleForPeer(

var binding = new Binding()
.setMembers(List.of("user:" + request.beneficiary.email))
.setRole(request.roleBinding.role)
.setRole(request.roleBinding.role())
.setCondition(new com.google.api.services.cloudresourcemanager.v3.model.Expr()
.setTitle(JitConstraints.ACTIVATION_CONDITION_TITLE)
.setDescription(bindingDescription)
Expand All @@ -262,7 +262,7 @@ public Activation activateProjectRoleForPeer(
request.endTime)));

this.resourceManagerAdapter.addProjectIamBinding(
ProjectId.fromFullResourceName(request.roleBinding.fullResourceName),
ProjectId.fromFullResourceName(request.roleBinding.fullResourceName()),
binding,
EnumSet.of(
ResourceManagerAdapter.IamBindingOptions.PURGE_EXISTING_TEMPORARY_BINDINGS,
Expand Down Expand Up @@ -291,7 +291,7 @@ public ActivationRequest createActivationRequestForPeer(
Preconditions.checkNotNull(roleBinding, "roleBinding");
Preconditions.checkNotNull(justification, "justification");

Preconditions.checkArgument(ProjectId.isProjectFullResourceName(roleBinding.fullResourceName));
Preconditions.checkArgument(ProjectId.isProjectFullResourceName(roleBinding.fullResourceName()));
Preconditions.checkArgument(reviewers != null && reviewers.size() >= this.options.minNumberOfReviewersPerActivationRequest,
"At least " + this.options.minNumberOfReviewersPerActivationRequest + " reviewers must be specified");
Preconditions.checkArgument(reviewers.size() <= this.options.maxNumberOfReviewersPerActivationRequest,
Expand Down Expand Up @@ -478,8 +478,8 @@ protected JsonWebToken.Payload toJsonWebTokenPayload() {
.setJwtId(this.id.toString())
.set("beneficiary", this.beneficiary.email)
.set("reviewers", this.reviewers.stream().map(id -> id.email).collect(Collectors.toList()))
.set("resource", this.roleBinding.fullResourceName)
.set("role", this.roleBinding.role)
.set("resource", this.roleBinding.fullResourceName())
.set("role", this.roleBinding.role())
.set("justification", this.justification)
.set("start", this.startTime.getEpochSecond())
.set("end", this.endTime.getEpochSecond());
Expand Down
Loading

0 comments on commit e3ecde1

Please sign in to comment.