From 128961b7457521bdda07cea13637e21d7becf1fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Pfeuffer?= Date: Fri, 24 Aug 2018 14:35:58 +0200 Subject: [PATCH] Add bean validation to user, group and repository The validations are taken from the isValid methods of the corresponding model objects. --- .../scm/api/v2/resources/GroupCollectionResource.java | 3 ++- .../src/main/java/sonia/scm/api/v2/resources/GroupDto.java | 4 ++++ .../java/sonia/scm/api/v2/resources/GroupResource.java | 3 ++- .../java/sonia/scm/api/v2/resources/RepositoryDto.java | 4 +++- .../sonia/scm/api/v2/resources/RepositoryResource.java | 3 ++- .../sonia/scm/api/v2/resources/UserCollectionResource.java | 3 ++- .../src/main/java/sonia/scm/api/v2/resources/UserDto.java | 7 +++++++ .../main/java/sonia/scm/api/v2/resources/UserResource.java | 3 ++- 8 files changed, 24 insertions(+), 6 deletions(-) diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/GroupCollectionResource.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/GroupCollectionResource.java index acc02c0da4..8abab0f720 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/GroupCollectionResource.java +++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/GroupCollectionResource.java @@ -11,6 +11,7 @@ import sonia.scm.group.GroupManager; import sonia.scm.web.VndMediaType; import javax.inject.Inject; +import javax.validation.Valid; import javax.ws.rs.Consumes; import javax.ws.rs.DefaultValue; import javax.ws.rs.GET; @@ -85,7 +86,7 @@ public class GroupCollectionResource { }) @TypeHint(TypeHint.NO_CONTENT.class) @ResponseHeaders(@ResponseHeader(name = "Location", description = "uri to the created group")) - public Response create(GroupDto groupDto) throws AlreadyExistsException { + public Response create(@Valid GroupDto groupDto) throws AlreadyExistsException { return adapter.create(groupDto, () -> dtoToGroupMapper.map(groupDto), group -> resourceLinks.group().self(group.getName())); diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/GroupDto.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/GroupDto.java index cb05da6568..b847412a33 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/GroupDto.java +++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/GroupDto.java @@ -6,7 +6,9 @@ import de.otto.edison.hal.Links; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; +import org.hibernate.validator.constraints.NotEmpty; +import javax.validation.constraints.Pattern; import java.time.Instant; import java.util.List; import java.util.Map; @@ -18,7 +20,9 @@ public class GroupDto extends HalRepresentation { private String description; @JsonInclude(JsonInclude.Include.NON_NULL) private Instant lastModified; + @Pattern(regexp = "^[A-z0-9\\.\\-_@]|[^ ]([A-z0-9\\.\\-_@ ]*[A-z0-9\\.\\-_@]|[^ ])?$") private String name; + @NotEmpty private String type; private Map properties; private List members; diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/GroupResource.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/GroupResource.java index e1e8e0ccdb..4dae8f26dd 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/GroupResource.java +++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/GroupResource.java @@ -9,6 +9,7 @@ import sonia.scm.group.GroupManager; import sonia.scm.web.VndMediaType; import javax.inject.Inject; +import javax.validation.Valid; import javax.ws.rs.Consumes; import javax.ws.rs.DELETE; import javax.ws.rs.GET; @@ -96,7 +97,7 @@ public class GroupResource { @ResponseCode(code = 500, condition = "internal server error") }) @TypeHint(TypeHint.NO_CONTENT.class) - public Response update(@PathParam("id") String name, GroupDto groupDto) throws NotFoundException { + public Response update(@PathParam("id") String name, @Valid GroupDto groupDto) throws NotFoundException { return adapter.update(name, existing -> dtoToGroupMapper.map(groupDto)); } } diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/RepositoryDto.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/RepositoryDto.java index cf343f8f77..c597e12d4f 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/RepositoryDto.java +++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/RepositoryDto.java @@ -6,6 +6,7 @@ import de.otto.edison.hal.Links; import lombok.Getter; import lombok.Setter; import org.hibernate.validator.constraints.Email; +import org.hibernate.validator.constraints.NotEmpty; import javax.validation.constraints.Pattern; import java.time.Instant; @@ -23,9 +24,10 @@ public class RepositoryDto extends HalRepresentation { @JsonInclude(JsonInclude.Include.NON_NULL) private Instant lastModified; private String namespace; - @Pattern(regexp = "[\\w-]+", message = "The name can only contain numbers, letters, underscore and hyphen") + @Pattern(regexp = "(?!^\\.\\.$)(?!^\\.$)(?!.*[\\\\\\[\\]])^[A-z0-9\\.][A-z0-9\\.\\-_/]*$") private String name; private boolean archived = false; + @NotEmpty private String type; protected Map properties; diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/RepositoryResource.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/RepositoryResource.java index 2d4ee9f600..99db629f07 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/RepositoryResource.java +++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/RepositoryResource.java @@ -12,6 +12,7 @@ import sonia.scm.web.VndMediaType; import javax.inject.Inject; import javax.inject.Provider; +import javax.validation.Valid; import javax.ws.rs.Consumes; import javax.ws.rs.DELETE; import javax.ws.rs.GET; @@ -125,7 +126,7 @@ public class RepositoryResource { @ResponseCode(code = 500, condition = "internal server error") }) @TypeHint(TypeHint.NO_CONTENT.class) - public Response update(@PathParam("namespace") String namespace, @PathParam("name") String name, RepositoryDto repositoryDto) throws NotFoundException { + public Response update(@PathParam("namespace") String namespace, @PathParam("name") String name, @Valid RepositoryDto repositoryDto) throws NotFoundException { return adapter.update( loadBy(namespace, name), existing -> dtoToRepositoryMapper.map(repositoryDto, existing.getId()), diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/UserCollectionResource.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/UserCollectionResource.java index 550c60de5d..81c3a66c6d 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/UserCollectionResource.java +++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/UserCollectionResource.java @@ -11,6 +11,7 @@ import sonia.scm.user.UserManager; import sonia.scm.web.VndMediaType; import javax.inject.Inject; +import javax.validation.Valid; import javax.ws.rs.Consumes; import javax.ws.rs.DefaultValue; import javax.ws.rs.GET; @@ -87,7 +88,7 @@ public class UserCollectionResource { }) @TypeHint(TypeHint.NO_CONTENT.class) @ResponseHeaders(@ResponseHeader(name = "Location", description = "uri to the created user")) - public Response create(UserDto userDto) throws AlreadyExistsException { + public Response create(@Valid UserDto userDto) throws AlreadyExistsException { return adapter.create(userDto, () -> dtoToUserMapper.map(userDto, ""), user -> resourceLinks.user().self(user.getName())); diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/UserDto.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/UserDto.java index cf7bf90504..6d07d27e32 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/UserDto.java +++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/UserDto.java @@ -6,7 +6,10 @@ import de.otto.edison.hal.Links; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; +import org.hibernate.validator.constraints.Email; +import org.hibernate.validator.constraints.NotEmpty; +import javax.validation.constraints.Pattern; import java.time.Instant; import java.util.Map; @@ -15,12 +18,16 @@ public class UserDto extends HalRepresentation { private boolean active; private boolean admin; private Instant creationDate; + @NotEmpty private String displayName; @JsonInclude(JsonInclude.Include.NON_NULL) private Instant lastModified; + @NotEmpty @Email private String mail; + @Pattern(regexp = "^[A-z0-9\\.\\-_@]|[^ ]([A-z0-9\\.\\-_@ ]*[A-z0-9\\.\\-_@]|[^ ])?$") private String name; private String password; + @NotEmpty private String type; private Map properties; diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/UserResource.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/UserResource.java index 687c94e4ff..dddfcfb886 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/UserResource.java +++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/UserResource.java @@ -9,6 +9,7 @@ import sonia.scm.user.UserManager; import sonia.scm.web.VndMediaType; import javax.inject.Inject; +import javax.validation.Valid; import javax.ws.rs.Consumes; import javax.ws.rs.DELETE; import javax.ws.rs.GET; @@ -96,7 +97,7 @@ public class UserResource { @ResponseCode(code = 500, condition = "internal server error") }) @TypeHint(TypeHint.NO_CONTENT.class) - public Response update(@PathParam("id") String name, UserDto userDto) throws NotFoundException { + public Response update(@PathParam("id") String name, @Valid UserDto userDto) throws NotFoundException { return adapter.update(name, existing -> dtoToUserMapper.map(userDto, existing.getPassword())); } }