status page creation for onboarding
This commit is contained in:
parent
1bd167d0ec
commit
22ff1a2efb
@ -10,7 +10,8 @@ import lombok.*;
|
||||
@RequiredArgsConstructor @Getter @ToString
|
||||
public enum Feature {
|
||||
USER_REGISTRATION_ENABLED("user-registration"),
|
||||
ORG_CREATION_ENABLED("org-creation");
|
||||
ORG_CREATION_ENABLED("org-creation"),
|
||||
STATUS_PAGE_CREATION_ENABLED("status-page-creation");
|
||||
|
||||
public static final Feature[] VALUES = values();
|
||||
|
||||
|
@ -0,0 +1,20 @@
|
||||
package cc.pulseapp.api.repository;
|
||||
|
||||
import cc.pulseapp.api.model.page.StatusPage;
|
||||
import lombok.NonNull;
|
||||
import org.springframework.data.mongodb.repository.MongoRepository;
|
||||
|
||||
/**
|
||||
* The repository for interacting with {@link StatusPage}'s.
|
||||
*
|
||||
* @author Braydon
|
||||
*/
|
||||
public interface StatusPageRepository extends MongoRepository<StatusPage, Long> {
|
||||
/**
|
||||
* Find a status page by its name.
|
||||
*
|
||||
* @param name the name of the status page
|
||||
* @return the status page with the name
|
||||
*/
|
||||
StatusPage findByNameIgnoreCase(@NonNull String name);
|
||||
}
|
@ -84,7 +84,7 @@ public final class AuthService {
|
||||
byte[] salt = HashUtils.generateSalt();
|
||||
Date now = new Date();
|
||||
return generateSession(request, userRepository.save(new User(
|
||||
snowflakeService.generateSnowflake(), input.getEmail(), input.getUsername(),
|
||||
snowflakeService.generateSnowflake(), input.getEmail(), input.getUsername().toLowerCase(),
|
||||
HashUtils.hash(salt, input.getPassword()), Base64.getEncoder().encodeToString(salt),
|
||||
null, UserTier.FREE, 0, now
|
||||
)));
|
||||
|
@ -8,6 +8,7 @@ import cc.pulseapp.api.model.user.User;
|
||||
import cc.pulseapp.api.repository.OrganizationRepository;
|
||||
import jakarta.annotation.Nonnull;
|
||||
import lombok.NonNull;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
@ -25,7 +26,8 @@ public final class OrganizationService {
|
||||
*/
|
||||
@NonNull private final OrganizationRepository orgRepository;
|
||||
|
||||
private OrganizationService(@NonNull SnowflakeService snowflakeService, @NonNull OrganizationRepository orgRepository) {
|
||||
@Autowired
|
||||
public OrganizationService(@NonNull SnowflakeService snowflakeService, @NonNull OrganizationRepository orgRepository) {
|
||||
this.snowflakeService = snowflakeService;
|
||||
this.orgRepository = orgRepository;
|
||||
}
|
||||
|
72
src/main/java/cc/pulseapp/api/service/StatusPageService.java
Normal file
72
src/main/java/cc/pulseapp/api/service/StatusPageService.java
Normal file
@ -0,0 +1,72 @@
|
||||
package cc.pulseapp.api.service;
|
||||
|
||||
import cc.pulseapp.api.exception.impl.BadRequestException;
|
||||
import cc.pulseapp.api.model.Feature;
|
||||
import cc.pulseapp.api.model.IGenericResponse;
|
||||
import cc.pulseapp.api.model.org.Organization;
|
||||
import cc.pulseapp.api.model.page.StatusPage;
|
||||
import cc.pulseapp.api.model.page.StatusPageTheme;
|
||||
import cc.pulseapp.api.repository.StatusPageRepository;
|
||||
import jakarta.annotation.Nonnull;
|
||||
import lombok.NonNull;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
|
||||
/**
|
||||
* @author Braydon
|
||||
*/
|
||||
@Service
|
||||
public final class StatusPageService {
|
||||
/**
|
||||
* The service to use for snowflake generation.
|
||||
*/
|
||||
@NonNull private final SnowflakeService snowflakeService;
|
||||
|
||||
/**
|
||||
* The repository to store and retrieve status pages.
|
||||
*/
|
||||
@NonNull private final StatusPageRepository pageRepository;
|
||||
|
||||
@Autowired
|
||||
public StatusPageService(@NonNull SnowflakeService snowflakeService, @NonNull StatusPageRepository pageRepository) {
|
||||
this.snowflakeService = snowflakeService;
|
||||
this.pageRepository = pageRepository;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new status page.
|
||||
*
|
||||
* @param name the status page name
|
||||
* @param owner the owner of the status page
|
||||
* @return the created status page
|
||||
* @throws BadRequestException if the status page creation fails
|
||||
*/
|
||||
@NonNull
|
||||
public StatusPage createStatusPage(@Nonnull String name, @NonNull Organization owner) throws BadRequestException {
|
||||
// Ensure status page creation is enabled
|
||||
if (!Feature.STATUS_PAGE_CREATION_ENABLED.isEnabled()) {
|
||||
throw new BadRequestException(Error.STATUS_PAGE_CREATION_DISABLED);
|
||||
}
|
||||
// Ensure the status page name isn't taken
|
||||
if (pageRepository.findByNameIgnoreCase(name) != null) {
|
||||
throw new BadRequestException(Error.STATUS_PAGE_NAME_TAKEN);
|
||||
}
|
||||
// Create the status page and return it
|
||||
String slug = name.replace(" ", "-") +
|
||||
"-" + ThreadLocalRandom.current().nextInt(10000, 99999);
|
||||
return pageRepository.save(new StatusPage(
|
||||
snowflakeService.generateSnowflake(), name, null, slug, null,
|
||||
null, StatusPageTheme.AUTO, true, owner.getSnowflake())
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Organization errors.
|
||||
*/
|
||||
private enum Error implements IGenericResponse {
|
||||
STATUS_PAGE_CREATION_DISABLED,
|
||||
STATUS_PAGE_NAME_TAKEN
|
||||
}
|
||||
}
|
@ -3,6 +3,7 @@ package cc.pulseapp.api.service;
|
||||
import cc.pulseapp.api.common.StringUtils;
|
||||
import cc.pulseapp.api.exception.impl.BadRequestException;
|
||||
import cc.pulseapp.api.model.IGenericResponse;
|
||||
import cc.pulseapp.api.model.org.Organization;
|
||||
import cc.pulseapp.api.model.user.User;
|
||||
import cc.pulseapp.api.model.user.UserDTO;
|
||||
import cc.pulseapp.api.model.user.UserFlag;
|
||||
@ -34,6 +35,11 @@ public final class UserService {
|
||||
*/
|
||||
@NonNull private final OrganizationService orgService;
|
||||
|
||||
/**
|
||||
* The status page service to use.
|
||||
*/
|
||||
@NonNull private final StatusPageService statusPageService;
|
||||
|
||||
/**
|
||||
* The user repository to use.
|
||||
*/
|
||||
@ -41,10 +47,12 @@ public final class UserService {
|
||||
|
||||
@Autowired
|
||||
public UserService(@NonNull AuthService authService, @NonNull SnowflakeService snowflakeService,
|
||||
@NonNull OrganizationService orgService, @NonNull UserRepository userRepository) {
|
||||
@NonNull OrganizationService orgService, @NonNull StatusPageService statusPageService,
|
||||
@NonNull UserRepository userRepository) {
|
||||
this.authService = authService;
|
||||
this.snowflakeService = snowflakeService;
|
||||
this.orgService = orgService;
|
||||
this.statusPageService = statusPageService;
|
||||
this.userRepository = userRepository;
|
||||
}
|
||||
|
||||
@ -78,7 +86,8 @@ public final class UserService {
|
||||
if (user.hasFlag(UserFlag.COMPLETED_ONBOARDING)) { // Already completed
|
||||
throw new BadRequestException(Error.ALREADY_ONBOARDED);
|
||||
}
|
||||
orgService.createOrganization(input.getOrganizationName(), user); // Create the org
|
||||
Organization org = orgService.createOrganization(input.getOrganizationName(), user); // Create the org
|
||||
statusPageService.createStatusPage(input.getStatusPageName(), org); // Create the status page
|
||||
user.addFlag(UserFlag.COMPLETED_ONBOARDING); // Flag completed onboarding
|
||||
userRepository.save(user);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user