Skip to content

Commit

Permalink
Add APIs for checking repo names and passwords
Browse files Browse the repository at this point in the history
This solved #73.
  • Loading branch information
Kaiser-Yang committed Oct 21, 2024
1 parent 6fb5a0e commit 93903a3
Show file tree
Hide file tree
Showing 9 changed files with 89 additions and 43 deletions.
4 changes: 4 additions & 0 deletions src/main/java/edu/cmipt/gcs/constant/ApiPathConstant.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ public class ApiPathConstant {
public static final String USER_CHECK_EMAIL_VALIDITY_API_PATH = USER_API_PREFIX + "/email";
public static final String USER_CHECK_USERNAME_VALIDITY_API_PATH =
USER_API_PREFIX + "/username";
public static final String USER_CHECK_USER_PASSWORD_VALIDITY_API_PATH =
USER_API_PREFIX + "/user-password";
public static final String USER_DELETE_USER_API_PATH = USER_API_PREFIX + "/delete";
public static final String USER_PAGE_USER_REPOSITORY_API_PATH =
USER_API_PREFIX + "/page/repository";
Expand All @@ -36,6 +38,8 @@ public class ApiPathConstant {
REPOSITORY_API_PREFIX + "/delete";
public static final String REPOSITORY_UPDATE_REPOSITORY_API_PATH =
REPOSITORY_API_PREFIX + "/update";
public static final String REPOSITORY_CHECK_REPOSITORY_NAME_VALIDITY_API_PATH =
REPOSITORY_API_PREFIX + "/repository-name";

public static final String SSH_KEY_API_PREFIX = ALL_API_PREFIX + "/ssh";
public static final String SSH_KEY_UPLOAD_SSH_KEY_API_PATH = SSH_KEY_API_PREFIX + "/upload";
Expand Down
45 changes: 45 additions & 0 deletions src/main/java/edu/cmipt/gcs/controller/RepositoryController.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

import edu.cmipt.gcs.constant.ApiPathConstant;
import edu.cmipt.gcs.constant.HeaderParameter;
import edu.cmipt.gcs.constant.ValidationConstant;
import edu.cmipt.gcs.enumeration.ErrorCodeEnum;
import edu.cmipt.gcs.exception.GenericException;
import edu.cmipt.gcs.pojo.repository.RepositoryDTO;
Expand All @@ -22,19 +23,24 @@
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Pattern;
import jakarta.validation.constraints.Size;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@Validated
@RestController
@Tag(name = "Repository", description = "Repository Related APIs")
public class RepositoryController {
Expand Down Expand Up @@ -169,4 +175,43 @@ public ResponseEntity<RepositoryVO> updateRepository(
}
return ResponseEntity.ok().body(new RepositoryVO(repositoryService.getById(id)));
}

@GetMapping(ApiPathConstant.REPOSITORY_CHECK_REPOSITORY_NAME_VALIDITY_API_PATH)
@Operation(
summary = "Check repository name validity",
description = "Check if the repository name is valid",
tags = {"Repository", "Get Method"})
@Parameters({
@Parameter(
name = "userId",
description = "User id",
required = true,
in = ParameterIn.QUERY,
schema = @Schema(implementation = Long.class)
),
@Parameter(
name = "repositoryName",
description = "Repository name",
required = true,
in = ParameterIn.QUERY,
schema = @Schema(implementation = String.class))
})
@ApiResponses({
@ApiResponse(responseCode = "200", description = "Repository name is valid"),
@ApiResponse(responseCode = "400", description = "Repository name is invalid")
})
public void checkRepositoryNameValidity(
@RequestParam("repositoryName")
@Size(min = ValidationConstant.MIN_REPOSITORY_NAME_LENGTH, max = ValidationConstant.MAX_REPOSITORY_NAME_LENGTH, message ="REPOSITORYDTO_REPOSITORYNAME_SIZE {RepositoryDTO.repositoryName.Size}")
@NotBlank(message = "REPOSITORYDTO_REPOSITORYNAME_NOTBLANK {RepositoryDTO.repositoryName.NotBlank}")
@Pattern(regexp = ValidationConstant.REPOSITORY_NAME_PATTERN, message = "REPOSITORYNAME_PATTERN_MISMATCH {REPOSITORYNAME_PATTERN_MISMATCH}")
String repositoryName,
@RequestParam("userId") Long userId) {
QueryWrapper<RepositoryPO> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("user_id", userId);
queryWrapper.eq("repository_name", repositoryName);
if (repositoryService.exists(queryWrapper)) {
throw new GenericException(ErrorCodeEnum.REPOSITORY_ALREADY_EXISTS, repositoryName);
}
}
}
32 changes: 32 additions & 0 deletions src/main/java/edu/cmipt/gcs/controller/UserController.java
Original file line number Diff line number Diff line change
Expand Up @@ -308,4 +308,36 @@ public void checkUsernameValidity(
throw new GenericException(ErrorCodeEnum.USERNAME_ALREADY_EXISTS, username);
}
}

@GetMapping(ApiPathConstant.USER_CHECK_USER_PASSWORD_VALIDITY_API_PATH)
@Operation(
summary = "Check password validity",
description = "Check if the password is valid",
tags = {"User", "Get Method"})
@Parameter(
name = "userPassword",
description = "User's Password",
example = "123456",
required = true,
in = ParameterIn.QUERY,
schema = @Schema(implementation = String.class))
@ApiResponses({
@ApiResponse(responseCode = "200", description = "Password validity checked successfully"),
@ApiResponse(
responseCode = "400",
description = "Password is not valid",
content = @Content(schema = @Schema(implementation = ErrorVO.class)))
})
public void checkPasswordValidity(
@RequestParam("userPassword")
@Size(
min = ValidationConstant.MIN_PASSWORD_LENGTH,
max = ValidationConstant.MAX_PASSWORD_LENGTH,
message = "USERDTO_PASSWORD_SIZE {UserDTO.password.Size}")
@NotBlank(message = "USERDTO_PASSWORD_NOTBLANK {UserDTO.password.NotBlank}")
@Pattern(
regexp = ValidationConstant.PASSWORD_PATTERN,
message = "PASSWORD_PATTERN_MISMATCH {PASSWORD_PATTERN_MISMATCH}")
String password) {
}
}
4 changes: 3 additions & 1 deletion src/main/java/edu/cmipt/gcs/filter/JwtFilter.java
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,9 @@ public BufferedReader getReader() {
ApiPathConstant.DEVELOPMENT_GET_API_MAP_API_PATH,
ApiPathConstant.DEVELOPMENT_GET_ERROR_MESSAGE_API_PATH,
ApiPathConstant.USER_CHECK_EMAIL_VALIDITY_API_PATH,
ApiPathConstant.USER_CHECK_USERNAME_VALIDITY_API_PATH);
ApiPathConstant.USER_CHECK_USERNAME_VALIDITY_API_PATH,
ApiPathConstant.USER_CHECK_USER_PASSWORD_VALIDITY_API_PATH,
ApiPathConstant.REPOSITORY_CHECK_REPOSITORY_NAME_VALIDITY_API_PATH);

@Override
protected void doFilterInternal(
Expand Down
30 changes: 1 addition & 29 deletions src/main/java/edu/cmipt/gcs/pojo/repository/RepositoryDTO.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@

import io.swagger.v3.oas.annotations.media.Schema;

import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Null;
Expand Down Expand Up @@ -54,31 +53,4 @@ public record RepositoryDTO(
"REPOSITORYDTO_REPOSITORYDESCRIPTION_SIZE"
+ " {RepositoryDTO.repositoryDescription.Size}")
String repositoryDescription,
@Schema(description = "Whether or Not Private Repo", example = "false") Boolean isPrivate,
@Schema(description = "Star Count")
@Null(
groups = CreateGroup.class,
message = "REPOSITORYDTO_STAR_NULL {RepositoryDTO.star.Null}")
@Min(
groups = UpdateGroup.class,
value = 0,
message = "REPOSITORYDTO_STAR_MIN {RepositoryDTO.star.Min}")
Integer star,
@Schema(description = "Fork Count")
@Null(
groups = CreateGroup.class,
message = "REPOSITORYDTO_FORK_NULL {RepositoryDTO.fork.Null}")
@Min(
groups = UpdateGroup.class,
value = 0,
message = "REPOSITORYDTO_FORK_MIN {RepositoryDTO.fork.Min}")
Integer fork,
@Schema(description = "Watcher Count")
@Null(
groups = CreateGroup.class,
message = "REPOSITORYDTO_WATCHER_NULL {RepositoryDTO.watcher.Null}")
@Min(
groups = UpdateGroup.class,
value = 0,
message = "REPOSITORYDTO_WATCHER_MIN {RepositoryDTO.watcher.Min}")
Integer watcher) {}
@Schema(description = "Whether or Not Private Repo", example = "false") Boolean isPrivate) {}
3 changes: 0 additions & 3 deletions src/main/java/edu/cmipt/gcs/pojo/repository/RepositoryPO.java
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,6 @@ public RepositoryPO(RepositoryDTO repositoryDTO, String userId, boolean generate
} catch (NumberFormatException e) {
this.userId = null;
}
this.star = repositoryDTO.star();
this.fork = repositoryDTO.fork();
this.watcher = repositoryDTO.watcher();
if (generateUrl) {
// TODO: https is not supported now
this.httpsUrl = "";
Expand Down
6 changes: 0 additions & 6 deletions src/main/resources/message/message.properties
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,6 @@ RepositoryDTO.id.NotNull=Repository id cannot be null
RepositoryDTO.name.Size=Repository name must be between {min} and {max} characters
RepositoryDTO.name.NotBlank=Repository name cannot be blank
RepositoryDTO.description.Size=Repository description must be between {min} and {max} characters
RepositoryDTO.star.Null=Start must be null when creating a new repository
RepositoryDTO.star.Min=Star must be greater than or equal to {value}
RepositoryDTO.fork.Null=Fork must be null when creating a new repository
RepositoryDTO.fork.Min=Fork must be greater than or equal to {value}
RepositoryDTO.watcher.Null=Watcher must be null when creating a new repository
RepositoryDTO.watcher.Min=Watcher must be greater than or equal to {value}

REPOSITORYNAME_PATTERN_MISMATCH=Repository name can only be alphanumeric, hyphen or underline
REPOSITORY_NOT_FOUND=Repository not found: {}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,11 @@ public void testCreateRepositoryValid() throws Exception {
.content(
"""
{
"repositoryName": "%s"
"repositoryName": "%s",
"isPrivate": %s
}
"""
.formatted(repositoryName)))
.formatted(repositoryName, i % 2 == 0 ? "false" : "true")))
.andExpect(status().isOk());
}
var content =
Expand Down Expand Up @@ -103,7 +104,6 @@ public void testUpdateRepositoryValid() throws Exception {
jsonPath("$.id").value(TestConstant.REPOSITORY_ID),
jsonPath("$.repositoryName").value(TestConstant.REPOSITORY_NAME),
jsonPath("$.repositoryDescription").value(newDescription),
jsonPath("$.isPrivate").value(false),
jsonPath("$.userId").value(TestConstant.ID),
jsonPath("$.star").value(0),
jsonPath("$.fork").value(0),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,6 @@ public void testPageOtherUserRepositoryValid() throws Exception {
.andExpectAll(
status().isOk(),
jsonPath("$").isArray(),
jsonPath("$.length()").value(TestConstant.REPOSITORY_SIZE));
jsonPath("$.length()").value(TestConstant.REPOSITORY_SIZE / 2));
}
}

0 comments on commit 93903a3

Please sign in to comment.