Update rest resource annotations

This commit is contained in:
Florian Scholdei
2020-02-19 13:51:54 +01:00
parent d103b52228
commit 6ea21f01ef
12 changed files with 156 additions and 87 deletions

View File

@@ -81,7 +81,7 @@ public class AuthenticationResource {
@POST
@Path("access_token")
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
@Operation(summary = "Login via Form", description = "Form-based authentication", tags = "Authentication")
@Operation(summary = "Login via Form", description = "Form-based authentication.", tags = "Authentication")
@ApiResponse(responseCode = "200", description = "success")
@ApiResponse(responseCode = "400", description = "bad request, required parameter is missing")
@ApiResponse(responseCode = "401", description = "unauthorized, the specified username or password is wrong")
@@ -104,7 +104,7 @@ public class AuthenticationResource {
@POST
@Path("access_token")
@Consumes(MediaType.APPLICATION_JSON)
@Operation(summary = "Login via JSON", description = "JSON-based authentication", tags = "Authentication")
@Operation(summary = "Login via JSON", description = "JSON-based authentication.", tags = "Authentication")
@ApiResponse(responseCode = "200", description = "success")
@ApiResponse(responseCode = "400", description = "bad request, required parameter is missing")
@ApiResponse(responseCode = "401", description = "unauthorized, the specified username or password is wrong")

View File

@@ -56,7 +56,7 @@ public class DiffRootResource {
@Produces(VndMediaType.DIFF)
@Operation(summary = "Diff by revision", description = "Get the repository diff of a revision.", tags = "Repository")
@ApiResponse(responseCode = "200", description = "success")
@ApiResponse(responseCode = "400", description = "Bad Request")
@ApiResponse(responseCode = "400", description = "bad request")
@ApiResponse(responseCode = "401", description = "not authenticated / invalid credentials")
@ApiResponse(responseCode = "403", description = "not authorized, the current user has no privileges to read the diff")
@ApiResponse(responseCode = "404", description = "not found, no revision with the specified param for the repository available or repository not found")
@@ -94,7 +94,7 @@ public class DiffRootResource {
schema = @Schema(implementation = DiffResultDto.class)
)
)
@ApiResponse(responseCode = "400", description = "Bad Request")
@ApiResponse(responseCode = "400", description = "bad request")
@ApiResponse(responseCode = "401", description = "not authenticated / invalid credentials")
@ApiResponse(responseCode = "403", description = "not authorized, the current user has no privileges to read the diff")
@ApiResponse(responseCode = "404", description = "not found, no revision with the specified param for the repository available or repository not found")

View File

@@ -31,7 +31,7 @@ public class GlobalPermissionResource {
@GET
@Produces(VndMediaType.PERMISSION_COLLECTION)
@Operation(summary = "List of permissions", description = "Returns all available permissions", tags = "Permissions")
@Operation(summary = "List of permissions", description = "Returns all available permissions.", tags = "Permissions")
@ApiResponse(
responseCode = "200",
description = "success",

View File

@@ -56,7 +56,7 @@ public class GroupCollectionResource {
@GET
@Path("")
@Produces(VndMediaType.GROUP_COLLECTION)
@Operation(summary = "List of groups", description = "Returns all groups for a given page number", tags = "Group")
@Operation(summary = "List of groups", description = "Returns all groups for a given page number with a given page size.", tags = "Group")
@ApiResponse(
responseCode = "200",
description = "success",
@@ -96,7 +96,7 @@ public class GroupCollectionResource {
@POST
@Path("")
@Consumes(VndMediaType.GROUP)
@Operation(summary = "Create group", description = "Creates a new group", tags = "Group")
@Operation(summary = "Create group", description = "Creates a new group.", tags = "Group")
@ApiResponse(responseCode = "201", description = "create success")
@ApiResponse(responseCode = "401", description = "not authenticated / invalid credentials")
@ApiResponse(responseCode = "403", description = "not authorized, the current user does not have the \"group\" privilege")

View File

@@ -76,7 +76,7 @@ public class GroupPermissionResource {
@Consumes(VndMediaType.PERMISSION_COLLECTION)
@Operation(summary = "Update Group permissions", description = "Sets permissions for a group. Overwrites all existing permissions.", tags = {"Group", "Permissions"})
@ApiResponse(responseCode = "204", description = "update success")
@ApiResponse(responseCode = "400", description = "Invalid body")
@ApiResponse(responseCode = "400", description = "invalid body")
@ApiResponse(responseCode = "401", description = "not authenticated / invalid credentials")
@ApiResponse(responseCode = "403", description = "not authorized, the current group does not have the correct privilege")
@ApiResponse(responseCode = "404", description = "not found, no group with the specified id/name available")

View File

@@ -107,7 +107,7 @@ public class GroupResource {
@Consumes(VndMediaType.GROUP)
@Operation(summary = "Update group", description = "Modifies a group.", tags = "Group")
@ApiResponse(responseCode = "204", description = "update success")
@ApiResponse(responseCode = "400", description = "Invalid body, e.g. illegal change of id/group name")
@ApiResponse(responseCode = "400", description = "invalid body, e.g. illegal change of id/group name")
@ApiResponse(responseCode = "401", description = "not authenticated / invalid credentials")
@ApiResponse(responseCode = "403", description = "not authorized, the current user does not have the \"group\" privilege")
@ApiResponse(responseCode = "404", description = "not found, no group with the specified id/name available")

View File

@@ -164,7 +164,7 @@ public class RepositoryResource {
@Consumes(VndMediaType.REPOSITORY)
@StatusCodes({
@ResponseCode(code = 204, condition = "update success"),
@ResponseCode(code = 400, condition = "Invalid body, e.g. illegal change of namespace or name"),
@ResponseCode(code = 400, condition = "invalid body, e.g. illegal change of namespace or name"),
@ResponseCode(code = 401, condition = "not authenticated / invalid credentials"),
@ResponseCode(code = 403, condition = "not authorized, the current user does not have the \"repository\" privilege"),
@ResponseCode(code = 404, condition = "not found, no repository with the specified namespace and name available"),

View File

@@ -90,7 +90,7 @@ public class RepositoryRoleResource {
@Consumes(VndMediaType.REPOSITORY_ROLE)
@StatusCodes({
@ResponseCode(code = 204, condition = "update success"),
@ResponseCode(code = 400, condition = "Invalid body, e.g. illegal change of repository role name"),
@ResponseCode(code = 400, condition = "invalid body, e.g. illegal change of repository role name"),
@ResponseCode(code = 401, condition = "not authenticated / invalid credentials"),
@ResponseCode(code = 403, condition = "not authorized, the current user does not have the \"repositoryRole\" privilege"),
@ResponseCode(code = 404, condition = "not found, no repository role with the specified name available"),

View File

@@ -1,10 +1,11 @@
package sonia.scm.api.v2.resources;
import com.webcohesion.enunciate.metadata.rs.ResponseCode;
import com.webcohesion.enunciate.metadata.rs.ResponseHeader;
import com.webcohesion.enunciate.metadata.rs.ResponseHeaders;
import com.webcohesion.enunciate.metadata.rs.StatusCodes;
import com.webcohesion.enunciate.metadata.rs.TypeHint;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import org.apache.shiro.authc.credential.PasswordService;
import sonia.scm.search.SearchRequest;
import sonia.scm.search.SearchUtil;
@@ -59,14 +60,25 @@ public class UserCollectionResource {
@GET
@Path("")
@Produces(VndMediaType.USER_COLLECTION)
@TypeHint(CollectionDto.class)
@StatusCodes({
@ResponseCode(code = 200, condition = "success"),
@ResponseCode(code = 400, condition = "\"sortBy\" field unknown"),
@ResponseCode(code = 401, condition = "not authenticated / invalid credentials"),
@ResponseCode(code = 403, condition = "not authorized, the current user does not have the \"user\" privilege"),
@ResponseCode(code = 500, condition = "internal server error")
})
@Operation(summary = "List of users", description = "Returns all users for a given page number with a given page size.", tags = "User")
@ApiResponse(
responseCode = "200",
description = "success",
content = @Content(
mediaType = VndMediaType.USER_COLLECTION,
schema = @Schema(implementation = CollectionDto.class)
)
)
@ApiResponse(responseCode = "400", description = "\"sortBy\" field unknown")
@ApiResponse(responseCode = "401", description = "not authenticated / invalid credentials")
@ApiResponse(responseCode = "403", description = "not authorized, the current user does not have the \"user\" privilege")
@ApiResponse(
responseCode = "500",
description = "internal server error",
content = @Content(
mediaType = VndMediaType.ERROR_TYPE,
schema = @Schema(implementation = ErrorDto.class)
))
public Response getAll(@DefaultValue("0") @QueryParam("page") int page,
@DefaultValue("" + DEFAULT_PAGE_SIZE) @QueryParam("pageSize") int pageSize,
@QueryParam("sortBy") String sortBy,
@@ -88,14 +100,18 @@ public class UserCollectionResource {
@POST
@Path("")
@Consumes(VndMediaType.USER)
@StatusCodes({
@ResponseCode(code = 201, condition = "create success"),
@ResponseCode(code = 401, condition = "not authenticated / invalid credentials"),
@ResponseCode(code = 403, condition = "not authorized, the current user does not have the \"user\" privilege"),
@ResponseCode(code = 409, condition = "conflict, a user with this name already exists"),
@ResponseCode(code = 500, condition = "internal server error")
})
@TypeHint(TypeHint.NO_CONTENT.class)
@Operation(summary = "Create user", description = "Creates a new user.", tags = "User")
@ApiResponse(responseCode = "201", description = "create success")
@ApiResponse(responseCode = "401", description = "not authenticated / invalid credentials")
@ApiResponse(responseCode = "403", description = "not authorized, the current user does not have the \"user\" privilege")
@ApiResponse(responseCode = "409", description = "conflict, a user with this name already exists")
@ApiResponse(
responseCode = "500",
description = "internal server error",
content = @Content(
mediaType = VndMediaType.ERROR_TYPE,
schema = @Schema(implementation = ErrorDto.class)
))
@ResponseHeaders(@ResponseHeader(name = "Location", description = "uri to the created user"))
public Response create(@Valid UserDto user) {
return adapter.create(user, () -> dtoToUserMapper.map(user, passwordService.encryptPassword(user.getPassword())), u -> resourceLinks.user().self(u.getName()));

View File

@@ -1,8 +1,9 @@
package sonia.scm.api.v2.resources;
import com.webcohesion.enunciate.metadata.rs.ResponseCode;
import com.webcohesion.enunciate.metadata.rs.StatusCodes;
import com.webcohesion.enunciate.metadata.rs.TypeHint;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import sonia.scm.security.PermissionAssigner;
import sonia.scm.security.PermissionDescriptor;
import sonia.scm.security.PermissionPermissions;
@@ -40,14 +41,32 @@ public class UserPermissionResource {
@GET
@Path("")
@Produces(VndMediaType.PERMISSION_COLLECTION)
@TypeHint(PermissionListDto.class)
@StatusCodes({
@ResponseCode(code = 200, condition = "success"),
@ResponseCode(code = 401, condition = "not authenticated / invalid credentials"),
@ResponseCode(code = 403, condition = "not authorized, the current user has no privileges to read the user"),
@ResponseCode(code = 404, condition = "not found, no user with the specified id/name available"),
@ResponseCode(code = 500, condition = "internal server error")
})
@Operation(summary = "User permission", description = "Returns the global git configuration.", tags = {"User", "Permissions"})
@ApiResponse(
responseCode = "200",
description = "success",
content = @Content(
mediaType = VndMediaType.PERMISSION_COLLECTION,
schema = @Schema(implementation = PermissionListDto.class)
)
)
@ApiResponse(responseCode = "401", description = "not authenticated / invalid credentials")
@ApiResponse(responseCode = "403", description = "not authorized, the current user has no privileges to read the user")
@ApiResponse(
responseCode = "404",
description = "not found, no user with the specified id/name available",
content = @Content(
mediaType = VndMediaType.ERROR_TYPE,
schema = @Schema(implementation = ErrorDto.class)
)
)
@ApiResponse(
responseCode = "500",
description = "internal server error",
content = @Content(
mediaType = VndMediaType.ERROR_TYPE,
schema = @Schema(implementation = ErrorDto.class)
))
public Response getPermissions(@PathParam("id") String id) {
PermissionPermissions.read().check();
Collection<PermissionDescriptor> permissions = permissionAssigner.readPermissionsForUser(id);
@@ -63,15 +82,20 @@ public class UserPermissionResource {
@PUT
@Path("")
@Consumes(VndMediaType.PERMISSION_COLLECTION)
@StatusCodes({
@ResponseCode(code = 204, condition = "update success"),
@ResponseCode(code = 400, condition = "Invalid body"),
@ResponseCode(code = 401, condition = "not authenticated / invalid credentials"),
@ResponseCode(code = 403, condition = "not authorized, the current user does not have the correct privilege"),
@ResponseCode(code = 404, condition = "not found, no user with the specified id/name available"),
@ResponseCode(code = 500, condition = "internal server error")
})
@TypeHint(TypeHint.NO_CONTENT.class)
@Operation(summary = "Update user permissions", description = "Sets permissions for a user. Overwrites all existing permissions.", tags = {"User", "Permissions"})
@ApiResponse(responseCode = "204", description = "update success")
@ApiResponse(responseCode = "400", description = "invalid body")
@ApiResponse(responseCode = "401", description = "not authenticated / invalid credentials")
@ApiResponse(responseCode = "403", description = "not authorized, the current user does not have the correct privilege")
@ApiResponse(responseCode = "404", description = "not found, no user with the specified id/name available")
@ApiResponse(
responseCode = "500",
description = "internal server error",
content = @Content(
mediaType = VndMediaType.ERROR_TYPE,
schema = @Schema(implementation = ErrorDto.class)
)
)
public Response overwritePermissions(@PathParam("id") String id, @Valid PermissionListDto newPermissions) {
Collection<PermissionDescriptor> permissionDescriptors = Arrays.stream(newPermissions.getPermissions())
.map(PermissionDescriptor::new)

View File

@@ -1,12 +1,12 @@
package sonia.scm.api.v2.resources;
import com.webcohesion.enunciate.metadata.rs.ResponseCode;
import com.webcohesion.enunciate.metadata.rs.StatusCodes;
import com.webcohesion.enunciate.metadata.rs.TypeHint;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import org.apache.shiro.authc.credential.PasswordService;
import sonia.scm.user.User;
import sonia.scm.user.UserManager;
import sonia.scm.user.UserPermissions;
import sonia.scm.web.VndMediaType;
import javax.inject.Inject;
@@ -54,14 +54,31 @@ public class UserResource {
@GET
@Path("")
@Produces(VndMediaType.USER)
@TypeHint(UserDto.class)
@StatusCodes({
@ResponseCode(code = 200, condition = "success"),
@ResponseCode(code = 401, condition = "not authenticated / invalid credentials"),
@ResponseCode(code = 403, condition = "not authorized, the current user has no privileges to read the user"),
@ResponseCode(code = 404, condition = "not found, no user with the specified id/name available"),
@ResponseCode(code = 500, condition = "internal server error")
})
@Operation(summary = "Returns a single user", description = "Returns the user for the given id.", tags = "User")
@ApiResponse(
responseCode = "200",
description = "success",
content = @Content(
mediaType = VndMediaType.USER,
schema = @Schema(implementation = UserDto.class)
)
)
@ApiResponse(responseCode = "401", description = "not authenticated / invalid credentials")
@ApiResponse(responseCode = "403", description = "not authorized, the current user has no privileges to read the user")
@ApiResponse(
responseCode = "404",
description = "not found, no user with the specified id/name available",
content = @Content(
mediaType = VndMediaType.ERROR_TYPE,
schema = @Schema(implementation = ErrorDto.class)
))
@ApiResponse(
responseCode = "500",
description = "internal server error",
content = @Content(
mediaType = VndMediaType.ERROR_TYPE,
schema = @Schema(implementation = ErrorDto.class)
))
public Response get(@PathParam("id") String id) {
return adapter.get(id, userToDtoMapper::map);
}
@@ -75,13 +92,11 @@ public class UserResource {
*/
@DELETE
@Path("")
@StatusCodes({
@ResponseCode(code = 204, condition = "delete success or nothing to delete"),
@ResponseCode(code = 401, condition = "not authenticated / invalid credentials"),
@ResponseCode(code = 403, condition = "not authorized, the current user does not have the \"user\" privilege"),
@ResponseCode(code = 500, condition = "internal server error")
})
@TypeHint(TypeHint.NO_CONTENT.class)
@Operation(summary = "Deletes a user", description = "Deletes the user for the given id.", tags = "User")
@ApiResponse(responseCode = "204", description = "delete success or nothing to delete")
@ApiResponse(responseCode = "401", description = "not authenticated / invalid credentials")
@ApiResponse(responseCode = "403", description = "not authorized, the current user does not have the \"user\" privilege")
@ApiResponse(responseCode = "500", description = "internal server error")
public Response delete(@PathParam("id") String name) {
return adapter.delete(name);
}
@@ -98,15 +113,19 @@ public class UserResource {
@PUT
@Path("")
@Consumes(VndMediaType.USER)
@StatusCodes({
@ResponseCode(code = 204, condition = "update success"),
@ResponseCode(code = 400, condition = "Invalid body, e.g. illegal change of id/user name"),
@ResponseCode(code = 401, condition = "not authenticated / invalid credentials"),
@ResponseCode(code = 403, condition = "not authorized, the current user does not have the \"user\" privilege"),
@ResponseCode(code = 404, condition = "not found, no user with the specified id/name available"),
@ResponseCode(code = 500, condition = "internal server error")
})
@TypeHint(TypeHint.NO_CONTENT.class)
@Operation(summary = "Modifies a user", description = "Modifies the user for the given id.", tags = "User")
@ApiResponse(responseCode = "204", description = "update success")
@ApiResponse(responseCode = "400", description = "invalid body, e.g. illegal change of id/user name")
@ApiResponse(responseCode = "401", description = "not authenticated / invalid credentials")
@ApiResponse(responseCode = "403", description = "not authorized, the current user does not have the \"user\" privilege")
@ApiResponse(
responseCode = "404",
description = "not found, no user with the specified id/name available",
content = @Content(
mediaType = VndMediaType.ERROR_TYPE,
schema = @Schema(implementation = ErrorDto.class)
))
@ApiResponse(responseCode = "500", description = "internal server error")
public Response update(@PathParam("id") String name, @Valid UserDto user) {
return adapter.update(name, existing -> dtoToUserMapper.map(user, existing.getPassword()));
}
@@ -125,15 +144,19 @@ public class UserResource {
@PUT
@Path("password")
@Consumes(VndMediaType.PASSWORD_OVERWRITE)
@StatusCodes({
@ResponseCode(code = 204, condition = "update success"),
@ResponseCode(code = 400, condition = "Invalid body, e.g. the user type is not xml or the given oldPassword do not match the stored one"),
@ResponseCode(code = 401, condition = "not authenticated / invalid credentials"),
@ResponseCode(code = 403, condition = "not authorized, the current user does not have the \"user\" privilege"),
@ResponseCode(code = 404, condition = "not found, no user with the specified id/name available"),
@ResponseCode(code = 500, condition = "internal server error")
})
@TypeHint(TypeHint.NO_CONTENT.class)
@Operation(summary = "Modifies a user password", description = "Lets admins modifies the user password for the given id.", tags = "User")
@ApiResponse(responseCode = "204", description = "update success")
@ApiResponse(responseCode = "400", description = "invalid body, e.g. the user type is not xml or the given oldPassword do not match the stored one")
@ApiResponse(responseCode = "401", description = "not authenticated / invalid credentials")
@ApiResponse(responseCode = "403", description = "not authorized, the current user does not have the \"user\" privilege")
@ApiResponse(
responseCode = "404",
description = "not found, no user with the specified id/name available",
content = @Content(
mediaType = VndMediaType.ERROR_TYPE,
schema = @Schema(implementation = ErrorDto.class)
))
@ApiResponse(responseCode = "500", description = "internal server error")
public Response overwritePassword(@PathParam("id") String name, @Valid PasswordOverwriteDto passwordOverwrite) {
userManager.overwritePassword(name, passwordService.encryptPassword(passwordOverwrite.getNewPassword()));
return Response.noContent().build();

View File

@@ -1,5 +1,8 @@
package sonia.scm.api.v2.resources;
import io.swagger.v3.oas.annotations.OpenAPIDefinition;
import io.swagger.v3.oas.annotations.tags.Tag;
import javax.inject.Inject;
import javax.inject.Provider;
import javax.ws.rs.Path;
@@ -7,6 +10,9 @@ import javax.ws.rs.Path;
/**
* RESTful Web Service Resource to manage users.
*/
@OpenAPIDefinition(tags = {
@Tag(name = "User", description = "User related endpoints")
})
@Path(UserRootResource.USERS_PATH_V2)
public class UserRootResource {