Change up the org backend a bit to support members
All checks were successful
Deploy API / deploy (ubuntu-latest, 2.44.0) (push) Successful in 52s
All checks were successful
Deploy API / deploy (ubuntu-latest, 2.44.0) (push) Successful in 52s
This commit is contained in:
parent
c5841402f3
commit
58b7b69bb3
@ -21,7 +21,7 @@ public final class DetailedOrganization extends cc.pulseapp.api.model.org.Organi
|
||||
@NonNull private final List<StatusPage> statusPages;
|
||||
|
||||
public DetailedOrganization(@NonNull cc.pulseapp.api.model.org.Organization origin, @NonNull List<StatusPage> statusPages) {
|
||||
super(origin.getSnowflake(), origin.getName(), origin.getSlug(), origin.getLogo(), origin.getOwnerSnowflake());
|
||||
super(origin.getSnowflake(), origin.getName(), origin.getSlug(), origin.getLogo(), origin.getMembers(), origin.getOwnerSnowflake());
|
||||
this.statusPages = statusPages;
|
||||
}
|
||||
}
|
@ -6,6 +6,7 @@ import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.mongodb.core.index.Indexed;
|
||||
import org.springframework.data.mongodb.core.mapping.Document;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
@ -39,6 +40,11 @@ public class Organization {
|
||||
*/
|
||||
private final String logo;
|
||||
|
||||
/**
|
||||
* The members of this organization.
|
||||
*/
|
||||
@NonNull private final List<OrganizationMember> members;
|
||||
|
||||
/**
|
||||
* The snowflake of the {@link User}
|
||||
* that owns this organization.
|
||||
|
@ -0,0 +1,25 @@
|
||||
package cc.pulseapp.api.model.org;
|
||||
|
||||
import cc.pulseapp.api.model.user.User;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import lombok.ToString;
|
||||
|
||||
/**
|
||||
* A member of an {@link Organization}.
|
||||
*
|
||||
* @author Braydon
|
||||
*/
|
||||
@AllArgsConstructor @Getter @ToString
|
||||
public final class OrganizationMember {
|
||||
/**
|
||||
* The snowflake of the {@link User}
|
||||
* this member belongs to.
|
||||
*/
|
||||
private final long userSnowflake;
|
||||
|
||||
/**
|
||||
* The bitwise permissions of this member.
|
||||
*/
|
||||
private final int permissions;
|
||||
}
|
@ -0,0 +1,53 @@
|
||||
package cc.pulseapp.api.model.org;
|
||||
|
||||
import cc.pulseapp.api.model.page.StatusPage;
|
||||
|
||||
/**
|
||||
* The permissions of a {@link OrganizationMember}.
|
||||
*
|
||||
* @author Braydon
|
||||
*/
|
||||
public enum OrganizationMemberPermission {
|
||||
/**
|
||||
* The member can create, edit, and delete
|
||||
* {@link StatusPage}s for the organization.
|
||||
*/
|
||||
MANAGE_STATUS_PAGES,
|
||||
|
||||
/**
|
||||
* The member can create, edit, and
|
||||
* delete automations for the organization.
|
||||
*/
|
||||
MANAGE_AUTOMATIONS,
|
||||
|
||||
/**
|
||||
* The member can create, edit, and
|
||||
* delete incidents for the organization.
|
||||
*/
|
||||
MANAGE_INCIDENTS,
|
||||
|
||||
/**
|
||||
* The member can view insights of the organization.
|
||||
*/
|
||||
VIEW_INSIGHTS,
|
||||
|
||||
/**
|
||||
* The member can view audit logs of the organization.
|
||||
*/
|
||||
VIEW_AUDIT_LOGS,
|
||||
|
||||
/**
|
||||
* The member can edit the organization.
|
||||
*/
|
||||
MANAGE_ORGANIZATION;
|
||||
|
||||
/**
|
||||
* Get the bitwise value
|
||||
* of this permission.
|
||||
*
|
||||
* @return the bitwise value
|
||||
*/
|
||||
public int bitwise() {
|
||||
return 1 << ordinal();
|
||||
}
|
||||
}
|
@ -60,7 +60,7 @@ public final class User {
|
||||
private TFAProfile tfa;
|
||||
|
||||
/**
|
||||
* The flags for this user.
|
||||
* The bitwise flags for this user.
|
||||
*/
|
||||
private int flags;
|
||||
|
||||
|
@ -3,6 +3,7 @@ package cc.pulseapp.api.repository;
|
||||
import cc.pulseapp.api.model.org.Organization;
|
||||
import lombok.NonNull;
|
||||
import org.springframework.data.mongodb.repository.MongoRepository;
|
||||
import org.springframework.data.mongodb.repository.Query;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.List;
|
||||
@ -15,12 +16,12 @@ import java.util.List;
|
||||
@Repository
|
||||
public interface OrganizationRepository extends MongoRepository<Organization, Long> {
|
||||
/**
|
||||
* Find an organization by its name.
|
||||
* Get the organization that has the given slug.
|
||||
*
|
||||
* @param name the name of the org
|
||||
* @return the org with the name
|
||||
* @param slug the organization slug
|
||||
* @return the organization, null if none
|
||||
*/
|
||||
Organization findByNameIgnoreCase(@NonNull String name);
|
||||
Organization findBySlug(@NonNull String slug);
|
||||
|
||||
/**
|
||||
* Get the organizations that
|
||||
@ -30,4 +31,14 @@ public interface OrganizationRepository extends MongoRepository<Organization, Lo
|
||||
* @return the owned organizations
|
||||
*/
|
||||
List<Organization> findByOwnerSnowflake(long ownerSnowflake);
|
||||
|
||||
/**
|
||||
* Get the organizations that the user
|
||||
* either owns or is a member of.
|
||||
*
|
||||
* @param userSnowflake the user's snowflake
|
||||
* @return the organizations the user has access to
|
||||
*/
|
||||
@Query("{ '$or': [ { 'ownerSnowflake': ?0 }, { 'members.userSnowflake': ?0 } ] }")
|
||||
List<Organization> findByUserAccess(long userSnowflake);
|
||||
}
|
@ -19,12 +19,4 @@ public interface UserRepository extends MongoRepository<User, Long> {
|
||||
* @return the user with the email
|
||||
*/
|
||||
User findByEmailIgnoreCase(@NonNull String email);
|
||||
|
||||
/**
|
||||
* Find a user by their username.
|
||||
*
|
||||
* @param username the username of the user
|
||||
* @return the user with the username
|
||||
*/
|
||||
User findByUsernameIgnoreCase(@NonNull String username);
|
||||
}
|
@ -15,6 +15,7 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@ -66,21 +67,18 @@ public final class OrganizationService {
|
||||
if (!Feature.ORG_CREATION_ENABLED.isEnabled()) {
|
||||
throw new BadRequestException(Error.ORG_CREATION_DISABLED);
|
||||
}
|
||||
List<Organization> ownedOrgs = orgRepository.findByOwnerSnowflake(owner.getSnowflake());
|
||||
|
||||
// Ensure the org name isn't taken
|
||||
if (ownedOrgs.stream().anyMatch(org -> org.getName().equalsIgnoreCase(name))) {
|
||||
throw new BadRequestException(Error.ORG_NAME_TAKEN);
|
||||
// Ensure the org slug isn't taken
|
||||
if (orgRepository.findBySlug(slug) != null) {
|
||||
throw new BadRequestException(Error.ORG_SLUG_TAKEN);
|
||||
}
|
||||
// Handle cloud environment checks
|
||||
if (EnvironmentUtils.isCloud()) {
|
||||
if (ownedOrgs.size() >= owner.getTier().getMaxOrganizations()) {
|
||||
if (orgRepository.findByOwnerSnowflake(owner.getSnowflake()).size() >= owner.getTier().getMaxOrganizations()) {
|
||||
throw new BadRequestException(Error.MAX_ORGS_REACHED);
|
||||
}
|
||||
}
|
||||
// Create the org and return it
|
||||
slug = slug.trim().replaceAll("-+$", ""); // Trim slug trailing dashes
|
||||
return orgRepository.save(new Organization(snowflakeService.generateSnowflake(), name, slug, null, owner.getSnowflake()));
|
||||
return orgRepository.save(new Organization(snowflakeService.generateSnowflake(), name, slug, null, Collections.emptyList(), owner.getSnowflake()));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -93,7 +91,7 @@ public final class OrganizationService {
|
||||
public List<DetailedOrganization> getOrganizations() {
|
||||
User user = authService.getAuthenticatedUser();
|
||||
List<DetailedOrganization> organizations = new ArrayList<>();
|
||||
for (Organization org : orgRepository.findByOwnerSnowflake(user.getSnowflake())) {
|
||||
for (Organization org : orgRepository.findByUserAccess(user.getSnowflake())) {
|
||||
organizations.add(new DetailedOrganization(org, statusPageRepository.findByOrgSnowflake(org.getSnowflake())));
|
||||
}
|
||||
return organizations;
|
||||
@ -104,7 +102,7 @@ public final class OrganizationService {
|
||||
*/
|
||||
private enum Error implements IGenericResponse {
|
||||
ORG_CREATION_DISABLED,
|
||||
ORG_NAME_TAKEN,
|
||||
ORG_SLUG_TAKEN,
|
||||
MAX_ORGS_REACHED
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user