diff --git a/migrations b/migrations index ef2fb9f1..73d165e8 160000 --- a/migrations +++ b/migrations @@ -1 +1 @@ -Subproject commit ef2fb9f141400e00b680a8721c72e86f1e2b9bdf +Subproject commit 73d165e880235195c2ed1ab5070b1d98ec4e5314 diff --git a/src/main/java/com/epam/reportportal/auth/commons/ReportPortalUser.java b/src/main/java/com/epam/reportportal/auth/commons/ReportPortalUser.java index 780a9828..dffc4f25 100644 --- a/src/main/java/com/epam/reportportal/auth/commons/ReportPortalUser.java +++ b/src/main/java/com/epam/reportportal/auth/commons/ReportPortalUser.java @@ -18,16 +18,25 @@ import static java.util.Optional.ofNullable; -import com.epam.reportportal.auth.entity.project.ProjectRole; -import com.epam.reportportal.auth.entity.user.UserRole; +import com.epam.reportportal.auth.commons.ReportPortalUser.OrganizationDetails.ProjectDetails; import com.epam.reportportal.auth.rules.exception.ErrorType; import com.epam.reportportal.auth.rules.exception.ReportPortalException; +import com.epam.reportportal.auth.entity.organization.OrganizationRole; +import com.epam.reportportal.auth.entity.project.ProjectRole; +import com.epam.reportportal.auth.entity.user.ProjectUser; +import com.epam.reportportal.auth.entity.user.UserRole; import com.fasterxml.jackson.annotation.JsonProperty; import java.io.Serializable; import java.util.Collection; import java.util.Collections; import java.util.Map; +import java.util.Set; import java.util.stream.Collectors; +import lombok.AllArgsConstructor; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.core.userdetails.User; @@ -38,33 +47,30 @@ * * @author Andrei Varabyeu */ +@Getter +@Setter +@EqualsAndHashCode(callSuper = false) public class ReportPortalUser extends User { private boolean active; private Long userId; - private UserRole userRole; - private String email; + private Map organizationDetails; - private Map projectDetails; private ReportPortalUser(String username, String password, Collection authorities, Long userId, - UserRole role, Map projectDetails, String email, boolean isActive) { + UserRole role, Map organizationDetails, String email, boolean isActive) { super(username, password, authorities); this.userId = userId; this.userRole = role; - this.projectDetails = projectDetails; + this.organizationDetails = organizationDetails; this.email = email; this.active = isActive; } - public static ReportPortalUserBuilder userBuilder() { - return new ReportPortalUserBuilder(); - } - @Override public boolean isEnabled() { return active; @@ -75,100 +81,138 @@ public boolean isAccountNonLocked() { return active; } - public Long getUserId() { - return userId; - } - public void setUserId(Long userId) { - this.userId = userId; - } - - public UserRole getUserRole() { - return userRole; - } - - public void setUserRole(UserRole userRole) { - this.userRole = userRole; - } - - public String getEmail() { - return email; - } - - public void setEmail(String email) { - this.email = email; - } - - public Map getProjectDetails() { - return projectDetails; + public static ReportPortalUserBuilder userBuilder() { + return new ReportPortalUserBuilder(); } - public void setProjectDetails(Map projectDetails) { - this.projectDetails = projectDetails; - } - public static class ProjectDetails implements Serializable { + @Getter + @Setter + @AllArgsConstructor + public static class OrganizationDetails implements Serializable { @JsonProperty(value = "id") - private Long projectId; + private Long orgId; @JsonProperty(value = "name") - private String projectName; + private String orgName; @JsonProperty("role") - private ProjectRole projectRole; + private OrganizationRole orgRole; - public ProjectDetails(Long projectId, String projectName, ProjectRole projectRole) { - this.projectId = projectId; - this.projectName = projectName; - this.projectRole = projectRole; - } - - public static ProjectDetailsBuilder builder() { - return new ProjectDetailsBuilder(); - } + private Map projectDetails; - public Long getProjectId() { - return projectId; + public static OrganizationDetailsBuilder builder() { + return new OrganizationDetailsBuilder(); } - public String getProjectName() { - return projectName; - } + public static class OrganizationDetailsBuilder { - public ProjectRole getProjectRole() { - return projectRole; - } + private Long orgId; + private String orgName; + private OrganizationRole orgRole; + private Map projectDetails; - public static class ProjectDetailsBuilder { - private Long projectId; - private String projectName; - private ProjectRole projectRole; + private OrganizationDetailsBuilder() { + } - private ProjectDetailsBuilder() { + public OrganizationDetailsBuilder withOrgId(Long orgId) { + this.orgId = orgId; + return this; } - public ProjectDetailsBuilder withProjectId(Long projectId) { - this.projectId = projectId; + public OrganizationDetailsBuilder withOrgName(String orgName) { + this.orgName = orgName; return this; } - public ProjectDetailsBuilder withProjectName(String projectName) { - this.projectName = projectName; + public OrganizationDetailsBuilder withOrganizationRole(String orgRole) { + this.orgRole = OrganizationRole.forName(orgRole) + .orElseThrow(() -> new ReportPortalException(ErrorType.ROLE_NOT_FOUND, orgRole)); return this; } - public ProjectDetailsBuilder withProjectRole(String projectRole) { - this.projectRole = ProjectRole.forName(projectRole) - .orElseThrow(() -> new ReportPortalException(ErrorType.ROLE_NOT_FOUND, projectRole)); + public OrganizationDetailsBuilder withProjectDetails(Map projectDetails) { + this.projectDetails = projectDetails; return this; } - public ProjectDetails build() { - return new ProjectDetails(projectId, projectName, projectRole); + public OrganizationDetails build() { + return new OrganizationDetails(orgId, orgName, orgRole, projectDetails); + } + } + + @Getter + @Setter + @NoArgsConstructor + @AllArgsConstructor + public static class ProjectDetails implements Serializable { + + @JsonProperty(value = "id") + private Long projectId; + + @JsonProperty(value = "name") + private String projectName; + + @JsonProperty(value = "key") + private String projectKey; + + @JsonProperty("role") + private ProjectRole projectRole; + + @JsonProperty("organization_id") + private Long organizationId; + + + public static ProjectDetailsBuilder builder() { + return new ProjectDetailsBuilder(); + } + + public static class ProjectDetailsBuilder { + + private Long projectId; + private String projectName; + private String projectKey; + private ProjectRole projectRole; + private Long organizationId; + + private ProjectDetailsBuilder() { + } + + public ProjectDetailsBuilder withProjectId(Long projectId) { + this.projectId = projectId; + return this; + } + + public ProjectDetailsBuilder withProjectName(String projectName) { + this.projectName = projectName; + return this; + } + + public ProjectDetailsBuilder withProjectKey(String projectKey) { + this.projectKey = projectKey; + return this; + } + + public ProjectDetailsBuilder withOrgId(Long orgId) { + this.organizationId = orgId; + return this; + } + + public ProjectDetailsBuilder withProjectRole(String projectRole) { + this.projectRole = ProjectRole.forName(projectRole) + .orElseThrow(() -> new ReportPortalException(ErrorType.ROLE_NOT_FOUND, projectRole)); + return this; + } + + public ProjectDetails build() { + return new ProjectDetails(projectId, projectName, projectKey, projectRole, organizationId); + } } } + } public static class ReportPortalUserBuilder { @@ -179,11 +223,10 @@ public static class ReportPortalUserBuilder { private Long userId; private UserRole userRole; private String email; - private Map projectDetails; + private Map organizationDetails; private Collection authorities; private ReportPortalUserBuilder() { - } public ReportPortalUserBuilder withActive(boolean active) { @@ -230,8 +273,8 @@ public ReportPortalUserBuilder withEmail(String email) { return this; } - public ReportPortalUserBuilder withProjectDetails(Map projectDetails) { - this.projectDetails = projectDetails; + public ReportPortalUserBuilder withOrganizationDetails(Map organizationDetails) { + this.organizationDetails = organizationDetails; return this; } @@ -244,20 +287,34 @@ public ReportPortalUser fromUser(com.epam.reportportal.auth.entity.user.User use this.password = ofNullable(user.getPassword()).orElse(""); this.authorities = Collections.singletonList( new SimpleGrantedAuthority(user.getRole().getAuthority())); - this.projectDetails = user.getProjects().stream().collect(Collectors.toMap( - it -> it.getProject().getName(), - it -> ProjectDetails.builder() - .withProjectId(it.getProject().getId()) - .withProjectRole(it.getProjectRole().name()) - .withProjectName(it.getProject().getName()) - .build() - )); + this.organizationDetails = user.getOrganizationUsers() + .stream() + .collect(Collectors.toMap(it -> it.getOrganization().getName(), + it -> OrganizationDetails.builder() + .withOrgId(it.getOrganization().getId()) + .withOrganizationRole(it.getOrganizationRole().name()) + .withProjectDetails(mapProjectDetails(user.getProjects(), it.getOrganization().getId())) + .withOrgName(it.getOrganization().getName()) + .build() + )); return build(); } + private Map mapProjectDetails (Set projects, Long orgId) { + return projects.stream() + .filter(projectUser -> projectUser.getProject().getOrganizationId().equals(orgId)) + .collect(Collectors.toMap(projectUser -> projectUser.getProject().getKey(), + projectUser -> ProjectDetails.builder() + .withProjectId(projectUser.getProject().getId()) + .withProjectRole(projectUser.getProjectRole().name()) + .withProjectKey(projectUser.getProject().getKey()) + .build()) + ); + } + public ReportPortalUser build() { - return new ReportPortalUser(username, password, authorities, userId, userRole, projectDetails, - email, active); + return new ReportPortalUser(username, password, authorities, userId, userRole, + organizationDetails, email, active); } } } diff --git a/src/main/java/com/epam/reportportal/auth/entity/enums/ProjectType.java b/src/main/java/com/epam/reportportal/auth/entity/enums/OrganizationType.java similarity index 66% rename from src/main/java/com/epam/reportportal/auth/entity/enums/ProjectType.java rename to src/main/java/com/epam/reportportal/auth/entity/enums/OrganizationType.java index 56cb5209..6574cb22 100644 --- a/src/main/java/com/epam/reportportal/auth/entity/enums/ProjectType.java +++ b/src/main/java/com/epam/reportportal/auth/entity/enums/OrganizationType.java @@ -1,5 +1,5 @@ /* - * Copyright 2019 EPAM Systems + * Copyright 2024 EPAM Systems * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,19 +20,19 @@ import java.util.Optional; /** - * Project Type enumeration
Used for supporting different project types processing + * Project Type enumeration
Used for supporting different organization types processing. * - * @author Andrei_Ramanchuk - * @author Andrei Varabyeu + * @author Siarhei Hrabko */ -public enum ProjectType { +public enum OrganizationType { PERSONAL, INTERNAL, - UPSA; + EXTERNAL; - public static Optional findByName(String name) { - return Arrays.stream(ProjectType.values()).filter(type -> type.name().equalsIgnoreCase(name)) + public static Optional findByName(String name) { + return Arrays.stream(OrganizationType.values()) + .filter(type -> type.name().equalsIgnoreCase(name)) .findAny(); } diff --git a/src/main/java/com/epam/reportportal/auth/entity/organization/Organization.java b/src/main/java/com/epam/reportportal/auth/entity/organization/Organization.java new file mode 100644 index 00000000..d603d61b --- /dev/null +++ b/src/main/java/com/epam/reportportal/auth/entity/organization/Organization.java @@ -0,0 +1,87 @@ +/* + * Copyright 2024 EPAM Systems + * + * 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.epam.reportportal.auth.entity.organization; + +import com.epam.reportportal.auth.dao.converters.JpaInstantConverter; +import com.epam.reportportal.auth.entity.enums.OrganizationType; +import java.io.Serializable; +import java.time.Instant; +import javax.persistence.Column; +import javax.persistence.Convert; +import javax.persistence.Entity; +import javax.persistence.EnumType; +import javax.persistence.Enumerated; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Table; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +/** + * @author Siarhei Hrabko + */ +@Entity +@Table(name = "organization", schema = "public") +@Getter +@Setter +@AllArgsConstructor +@NoArgsConstructor +public class Organization implements Serializable { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id", unique = true, nullable = false, precision = 64) + private Long id; + + @Column(name = "created_at", nullable = false) + @Convert(converter = JpaInstantConverter.class) + private Instant createdAt; + + @Column(name = "updated_at", nullable = false) + @Convert(converter = JpaInstantConverter.class) + private Instant updatedAt; + + @Column(name = "name") + private String name; + + @Column(name = "organization_type") + @Enumerated(EnumType.STRING) + private OrganizationType organizationType; + + @Column(name = "slug") + private String slug; + + @Column(name = "external_id") + private String externalId; + + + @Override + public String toString() { + return "Organization{" + + "id=" + id + + ", creationDate=" + createdAt + + ", updatedAt=" + updatedAt + + ", externalId=" + externalId + + ", name='" + name + '\'' + + ", organizationType=" + organizationType + + ", slug='" + slug + '\'' + + '}'; + } +} diff --git a/src/main/java/com/epam/reportportal/auth/entity/organization/OrganizationRole.java b/src/main/java/com/epam/reportportal/auth/entity/organization/OrganizationRole.java new file mode 100644 index 00000000..f3dde798 --- /dev/null +++ b/src/main/java/com/epam/reportportal/auth/entity/organization/OrganizationRole.java @@ -0,0 +1,63 @@ +/* + * Copyright 2024 EPAM Systems + * + * 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.epam.reportportal.auth.entity.organization; + +import java.util.Arrays; +import java.util.Optional; +import lombok.Getter; + +/** + * @author Siarhei Hrabko + */ +@Getter +public enum OrganizationRole implements Comparable { + + MEMBER(0, "Member"), + MANAGER(1, "Manager"); + + + private final int roleLevel; + private final String roleName; + + OrganizationRole(int level, String roleName) { + this.roleLevel = level; + this.roleName = roleName; + } + + public boolean higherThan(OrganizationRole other) { + return this.roleLevel > other.roleLevel; + } + + public boolean lowerThan(OrganizationRole other) { + return this.roleLevel < other.roleLevel; + } + + public boolean sameOrHigherThan(OrganizationRole other) { + return this.roleLevel >= other.roleLevel; + } + + public boolean sameOrLowerThan(OrganizationRole other) { + return this.roleLevel <= other.roleLevel; + } + + public static Optional forName(final String name) { + return Arrays.stream(OrganizationRole.values()) + .filter(role -> role.name().equalsIgnoreCase(name)) + .findAny(); + } + +} diff --git a/src/main/java/com/epam/reportportal/auth/entity/project/Project.java b/src/main/java/com/epam/reportportal/auth/entity/project/Project.java index e10c4b6f..b2475552 100644 --- a/src/main/java/com/epam/reportportal/auth/entity/project/Project.java +++ b/src/main/java/com/epam/reportportal/auth/entity/project/Project.java @@ -18,7 +18,6 @@ import com.epam.reportportal.auth.dao.converters.JpaInstantConverter; import com.epam.reportportal.auth.entity.Metadata; -import com.epam.reportportal.auth.entity.enums.ProjectType; import com.epam.reportportal.auth.entity.integration.Integration; import com.epam.reportportal.auth.entity.user.ProjectUser; import com.google.common.collect.Sets; @@ -30,8 +29,6 @@ import javax.persistence.Column; import javax.persistence.Convert; import javax.persistence.Entity; -import javax.persistence.EnumType; -import javax.persistence.Enumerated; import javax.persistence.FetchType; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; @@ -68,10 +65,6 @@ public class Project implements Serializable { @Column(name = "name") private String name; - @Column(name = "project_type") - @Enumerated(EnumType.STRING) - private ProjectType projectType; - @OneToMany(mappedBy = "project", cascade = {CascadeType.PERSIST}, fetch = FetchType.LAZY) @OrderBy("creationDate desc") private Set integrations = Sets.newHashSet(); @@ -84,22 +77,30 @@ public class Project implements Serializable { @OrderBy(value = "issue_type_id") private Set projectIssueTypes = Sets.newHashSet(); - /* Not required in service-authorization - @OneToMany(mappedBy = "project", cascade = { - CascadeType.PERSIST}, fetch = FetchType.EAGER, orphanRemoval = true) - private Set senderCases = Sets.newHashSet(); - */ - - @Column(name = "creation_date") + @Column(name = "created_at") @Convert(converter = JpaInstantConverter.class) private Instant creationDate; + @Column(name = "updated_at") + @Convert(converter = JpaInstantConverter.class) + private Instant updatedAt; + @Type(type = "json") @Column(name = "metadata") private Metadata metadata; + // TODO: rename to meaningful variable. eg. orgSlug, orgKey or else @Column(name = "organization") - private String organization; + private String org; + + @Column(name = "organization_id", nullable = false) + private Long organizationId; + + @Column(name = "key") + private String key; + + @Column(name = "slug") + private String slug; @Column(name = "allocated_storage", updatable = false) private long allocatedStorage; @@ -122,11 +123,12 @@ public boolean equals(Object o) { return false; } Project project = (Project) o; - return Objects.equals(name, project.name) && Objects.equals(allocatedStorage, - project.allocatedStorage) && Objects.equals( - creationDate, - project.creationDate - ) && Objects.equals(metadata, project.metadata); + return Objects.equals(name, project.name) + && Objects.equals(key, project.key) + && Objects.equals(organizationId, project.organizationId) + && Objects.equals(allocatedStorage, project.allocatedStorage) + && Objects.equals(creationDate, project.creationDate) + && Objects.equals(metadata, project.metadata); } @Override diff --git a/src/main/java/com/epam/reportportal/auth/entity/project/ProjectRole.java b/src/main/java/com/epam/reportportal/auth/entity/project/ProjectRole.java index 08db95b8..0da92626 100644 --- a/src/main/java/com/epam/reportportal/auth/entity/project/ProjectRole.java +++ b/src/main/java/com/epam/reportportal/auth/entity/project/ProjectRole.java @@ -24,10 +24,8 @@ */ public enum ProjectRole implements Comparable { - OPERATOR(0, "Operator"), - CUSTOMER(1, "Customer"), - MEMBER(2, "Member"), - PROJECT_MANAGER(3, "Project manager"); + VIEWER(0, "Viewer"), + EDITOR (1, "Editor"); private final int roleLevel; private final String roleName; diff --git a/src/main/java/com/epam/reportportal/auth/entity/user/OrganizationUser.java b/src/main/java/com/epam/reportportal/auth/entity/user/OrganizationUser.java new file mode 100644 index 00000000..63e2bddb --- /dev/null +++ b/src/main/java/com/epam/reportportal/auth/entity/user/OrganizationUser.java @@ -0,0 +1,113 @@ +/* + * Copyright 2024 EPAM Systems + * + * 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.epam.reportportal.auth.entity.user; + +import com.epam.reportportal.auth.entity.enums.PostgreSQLEnumType; +import com.epam.reportportal.auth.entity.organization.Organization; +import com.epam.reportportal.auth.entity.organization.OrganizationRole; +import java.io.Serializable; +import java.util.Objects; +import javax.persistence.Column; +import javax.persistence.EmbeddedId; +import javax.persistence.Entity; +import javax.persistence.EnumType; +import javax.persistence.Enumerated; +import javax.persistence.FetchType; +import javax.persistence.ManyToOne; +import javax.persistence.MapsId; +import javax.persistence.Table; +import org.hibernate.annotations.Type; +import org.hibernate.annotations.TypeDef; + +/** + * @author Siarhei Hrabko + */ +@Entity +@TypeDef(name = "pqsql_enum", typeClass = PostgreSQLEnumType.class) +@Table(name = "organization_user", schema = "public") +public class OrganizationUser implements Serializable { + + @EmbeddedId + private OrganizationUserId id = new OrganizationUserId(); + + @ManyToOne(fetch = FetchType.LAZY) + @MapsId("organizationId") + private Organization organization; + + @ManyToOne(fetch = FetchType.LAZY) + @MapsId("userId") + private User user; + + @Column(name = "organization_role") + @Enumerated(EnumType.STRING) + @Type(type = "pqsql_enum") + private OrganizationRole organizationRole; + + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof OrganizationUser)) { + return false; + } + OrganizationUser that = (OrganizationUser) o; + return organization.equals(that.organization) + && id.equals(that.id) + && user.equals(that.user) + && organizationRole == that.organizationRole; + } + + @Override + public int hashCode() { + return Objects.hash(id, organization, user, organizationRole); + } + + public OrganizationUserId getId() { + return id; + } + + public void setId(OrganizationUserId id) { + this.id = id; + } + + public Organization getOrganization() { + return organization; + } + + public void setOrganization(Organization organization) { + this.organization = organization; + } + + public User getUser() { + return user; + } + + public void setUser(User user) { + this.user = user; + } + + public OrganizationRole getOrganizationRole() { + return organizationRole; + } + + public void setOrganizationRole( + OrganizationRole organizationRole) { + this.organizationRole = organizationRole; + } +} diff --git a/src/main/java/com/epam/reportportal/auth/entity/user/OrganizationUserId.java b/src/main/java/com/epam/reportportal/auth/entity/user/OrganizationUserId.java new file mode 100644 index 00000000..6a489443 --- /dev/null +++ b/src/main/java/com/epam/reportportal/auth/entity/user/OrganizationUserId.java @@ -0,0 +1,71 @@ +/* + * Copyright 2024 EPAM Systems + * + * 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.epam.reportportal.auth.entity.user; + +import java.io.Serializable; +import java.util.Objects; +import javax.persistence.Column; +import javax.persistence.Embeddable; + +/** + * @author Siarhei Hrabko + */ +@Embeddable +public class OrganizationUserId implements Serializable { + + @Column(name = "organization_id") + private Long organizationId; + + @Column(name = "user_id") + private Long userId; + + public OrganizationUserId() {} + + public Long getOrganizationId() { + return organizationId; + } + + public void setOrganizationId(Long organizationId) { + this.organizationId = organizationId; + } + + public Long getUserId() { + return userId; + } + + public void setUserId(Long userId) { + this.userId = userId; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + OrganizationUserId that = (OrganizationUserId) o; + return Objects.equals(organizationId, that.organizationId) + && Objects.equals(userId, that.userId); + } + + @Override + public int hashCode() { + return Objects.hash(organizationId, userId); + } +} diff --git a/src/main/java/com/epam/reportportal/auth/entity/user/User.java b/src/main/java/com/epam/reportportal/auth/entity/user/User.java index 271facd7..40a362e2 100644 --- a/src/main/java/com/epam/reportportal/auth/entity/user/User.java +++ b/src/main/java/com/epam/reportportal/auth/entity/user/User.java @@ -19,6 +19,7 @@ import com.epam.reportportal.auth.entity.Metadata; import com.google.common.collect.Sets; import java.io.Serializable; +import java.time.Instant; import java.util.Objects; import java.util.Set; import java.util.UUID; @@ -36,9 +37,11 @@ import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; +import org.hibernate.annotations.CreationTimestamp; import org.hibernate.annotations.DynamicInsert; import org.hibernate.annotations.Type; import org.hibernate.annotations.TypeDef; +import org.hibernate.annotations.UpdateTimestamp; /** * @author Andrei Varabyeu @@ -84,6 +87,14 @@ public class User implements Serializable { @Column(name = "full_name") private String fullName; + @CreationTimestamp + @Column(name = "created_at") + private Instant createdAt; + + @UpdateTimestamp + @Column(name = "updated_at") + private Instant updatedAt; + @Column(name = "expired") private boolean isExpired; @@ -105,6 +116,10 @@ public class User implements Serializable { CascadeType.MERGE, CascadeType.REFRESH}) private Set projects = Sets.newHashSet(); + @OneToMany(fetch = FetchType.LAZY, mappedBy = "user", cascade = {CascadeType.PERSIST, + CascadeType.MERGE, CascadeType.REFRESH}) + private Set organizationUsers = Sets.newHashSet(); + @Override public boolean equals(Object o) { if (this == o) { @@ -114,8 +129,10 @@ public boolean equals(Object o) { return false; } User user = (User) o; - return Objects.equals(id, user.id) && Objects.equals(uuid, user.uuid) - && Objects.equals(login, user.login) && Objects.equals(email, user.email); + return Objects.equals(id, user.id) + && Objects.equals(uuid, user.uuid) + && Objects.equals(login, user.login) + && Objects.equals(email, user.email); } @Override diff --git a/src/main/java/com/epam/reportportal/auth/integration/github/GitHubUserReplicator.java b/src/main/java/com/epam/reportportal/auth/integration/github/GitHubUserReplicator.java index 62b41708..5107b68f 100644 --- a/src/main/java/com/epam/reportportal/auth/integration/github/GitHubUserReplicator.java +++ b/src/main/java/com/epam/reportportal/auth/integration/github/GitHubUserReplicator.java @@ -152,8 +152,10 @@ private User createUser(UserResource userResource, GitHubClient gitHubClient) { user.setUserType(UserType.GITHUB); user.setRole(UserRole.USER); user.setExpired(false); + /* TODO: skip generation until we have requirements final Project project = generatePersonalProject(user); user.getProjects().addAll(project.getUsers()); + */ return user; } diff --git a/src/main/java/com/epam/reportportal/auth/integration/ldap/LdapUserReplicator.java b/src/main/java/com/epam/reportportal/auth/integration/ldap/LdapUserReplicator.java index b613f595..87b222d9 100644 --- a/src/main/java/com/epam/reportportal/auth/integration/ldap/LdapUserReplicator.java +++ b/src/main/java/com/epam/reportportal/auth/integration/ldap/LdapUserReplicator.java @@ -117,9 +117,10 @@ private User createNewUser(DirContextOperations ctx, Map syncAtt user.setRole(UserRole.USER); user.setExpired(false); + /* TODO: skip generation until we have new requirements final Project project = generatePersonalProject(user); user.getProjects().add(project.getUsers().iterator().next()); - + */ return userRepository.save(user); } diff --git a/src/main/java/com/epam/reportportal/auth/integration/saml/SamlUserReplicator.java b/src/main/java/com/epam/reportportal/auth/integration/saml/SamlUserReplicator.java index e7bab690..446da8bb 100644 --- a/src/main/java/com/epam/reportportal/auth/integration/saml/SamlUserReplicator.java +++ b/src/main/java/com/epam/reportportal/auth/integration/saml/SamlUserReplicator.java @@ -117,15 +117,18 @@ public User replicateUser(ReportPortalSamlAuthentication samlAuthentication) { user.setUserType(UserType.SAML); user.setExpired(false); + /* TODO: skip generation until we have requirements Project project = generatePersonalProject(user); //TODO BUG IF PROJECT HAS NO USERS BECAUSE OF iterator().next() on empty collection user.getProjects().add(project.getUsers().iterator().next()); + */ user.setMetadata(defaultMetaData()); userRepository.save(user); - publishActivityEvents(user, project); + // TODO: waiting for requirements + // publishActivityEvents(user, project); return user; } @@ -133,9 +136,12 @@ public User replicateUser(ReportPortalSamlAuthentication samlAuthentication) { private void publishActivityEvents(User user, Project project) { publishUserCreatedEvent(user); + /* TODO: skip until we have requirements + publishProjectCreatedEvent(project); publishUserAssignToProjectEvent(user, project); + */ } private void publishUserCreatedEvent(User user) { diff --git a/src/main/java/com/epam/reportportal/auth/util/PersonalProjectService.java b/src/main/java/com/epam/reportportal/auth/util/PersonalProjectService.java index 3a16a59a..bb4e2840 100644 --- a/src/main/java/com/epam/reportportal/auth/util/PersonalProjectService.java +++ b/src/main/java/com/epam/reportportal/auth/util/PersonalProjectService.java @@ -25,7 +25,6 @@ import com.epam.reportportal.auth.dao.ProjectRepository; import com.epam.reportportal.auth.entity.Metadata; import com.epam.reportportal.auth.entity.enums.ProjectAttributeEnum; -import com.epam.reportportal.auth.entity.enums.ProjectType; import com.epam.reportportal.auth.entity.enums.TestItemIssueGroup; import com.epam.reportportal.auth.entity.project.Project; import com.epam.reportportal.auth.entity.project.ProjectRole; @@ -91,11 +90,10 @@ public Project generatePersonalProject(User user) { Project project = new Project(); project.setName(generatePersonalProjectName(user.getLogin())); project.setCreationDate(Instant.now()); - project.setProjectType(ProjectType.PERSONAL); ProjectUser projectUser = new ProjectUser() .withUser(user) - .withProjectRole(ProjectRole.PROJECT_MANAGER) + .withProjectRole(ProjectRole.EDITOR) .withProject(project); project.setUsers(Sets.newHashSet(projectUser));