From 30f3d61cdd3608617e0a9cc07f09a325c8196e14 Mon Sep 17 00:00:00 2001 From: Alexandre Grison <a.grison@gmail.com> Date: Tue, 9 May 2017 17:25:43 +0200 Subject: [PATCH] Fixes --- api.iml | 63 +++++++------------ .../realworld/exception/InvalidException.kt | 2 +- .../io/realworld/jwt/ApiKeySecuredAspect.kt | 4 +- .../kotlin/io/realworld/model/inout/Login.kt | 2 +- .../io/realworld/model/inout/Register.kt | 2 +- .../io/realworld/model/inout/UpdateUser.kt | 21 +++++-- .../kotlin/io/realworld/web/ArticleHandler.kt | 13 +++- .../io/realworld/web/InvalidRequestHandler.kt | 2 +- .../kotlin/io/realworld/web/UserHandler.kt | 4 +- 9 files changed, 56 insertions(+), 57 deletions(-) diff --git a/api.iml b/api.iml index 9d1ea10..4e66be8 100644 --- a/api.iml +++ b/api.iml @@ -5,48 +5,27 @@ <configuration /> </facet> <facet type="kotlin-language" name="Kotlin"> - <configuration version="1"> - <option name="compilerInfo"> - <KotlinCompilerInfo> - <option name="compilerSettings"> - <CompilerSettings /> - </option> - <option name="k2jsCompilerArguments"> - <K2JSCompilerArguments /> - </option> - <option name="k2jvmCompilerArguments"> - <K2JVMCompilerArguments> - <option name="jvmTarget" value="1.8" /> - </K2JVMCompilerArguments> - </option> - <option name="_commonCompilerArguments"> - <DummyImpl> - <option name="pluginClasspaths"> - <array> - <option value="$MAVEN_REPOSITORY$/org/jetbrains/kotlin/kotlin-maven-allopen/1.1.2/kotlin-maven-allopen-1.1.2.jar" /> - </array> - </option> - <option name="coroutinesWarn" value="true" /> - <option name="pluginOptions"> - <array> - <option value="plugin:org.jetbrains.kotlin.allopen:annotation=org.springframework.stereotype.Component" /> - <option value="plugin:org.jetbrains.kotlin.allopen:annotation=org.springframework.transaction.annotation.Transactional" /> - <option value="plugin:org.jetbrains.kotlin.allopen:annotation=org.springframework.scheduling.annotation.Async" /> - <option value="plugin:org.jetbrains.kotlin.allopen:annotation=org.springframework.cache.annotation.Cacheable" /> - </array> - </option> - </DummyImpl> - </option> - </KotlinCompilerInfo> - </option> - <option name="useProjectSettings" value="false" /> - <option name="versionInfo"> - <KotlinVersionInfo> - <option name="apiLevel" value="1.1" /> - <option name="languageLevel" value="1.1" /> - <option name="targetPlatformName" value="JVM 1.8" /> - </KotlinVersionInfo> - </option> + <configuration version="2" platform="JVM 1.8" useProjectSettings="false"> + <compilerSettings /> + <compilerArguments> + <option name="jvmTarget" value="1.8" /> + <option name="languageVersion" value="1.1" /> + <option name="apiVersion" value="1.1" /> + <option name="pluginClasspaths"> + <array> + <option value="$MAVEN_REPOSITORY$/org/jetbrains/kotlin/kotlin-maven-allopen/1.1.2/kotlin-maven-allopen-1.1.2.jar" /> + </array> + </option> + <option name="coroutinesWarn" value="true" /> + <option name="pluginOptions"> + <array> + <option value="plugin:org.jetbrains.kotlin.allopen:annotation=org.springframework.stereotype.Component" /> + <option value="plugin:org.jetbrains.kotlin.allopen:annotation=org.springframework.transaction.annotation.Transactional" /> + <option value="plugin:org.jetbrains.kotlin.allopen:annotation=org.springframework.scheduling.annotation.Async" /> + <option value="plugin:org.jetbrains.kotlin.allopen:annotation=org.springframework.cache.annotation.Cacheable" /> + </array> + </option> + </compilerArguments> </configuration> </facet> </component> diff --git a/src/main/kotlin/io/realworld/exception/InvalidException.kt b/src/main/kotlin/io/realworld/exception/InvalidException.kt index 5365198..d8d6339 100644 --- a/src/main/kotlin/io/realworld/exception/InvalidException.kt +++ b/src/main/kotlin/io/realworld/exception/InvalidException.kt @@ -2,7 +2,7 @@ package io.realworld.exception import org.springframework.validation.Errors -data class InvalidException(val errors: Errors) : RuntimeException() +data class InvalidException(val errors: Errors?) : RuntimeException() object InvalidRequest { fun check(errors: Errors) { diff --git a/src/main/kotlin/io/realworld/jwt/ApiKeySecuredAspect.kt b/src/main/kotlin/io/realworld/jwt/ApiKeySecuredAspect.kt index c51cb30..63d0fb7 100644 --- a/src/main/kotlin/io/realworld/jwt/ApiKeySecuredAspect.kt +++ b/src/main/kotlin/io/realworld/jwt/ApiKeySecuredAspect.kt @@ -116,7 +116,7 @@ class ApiKeySecuredAspect(@Autowired val userService: UserService) { if (StringUtils.isEmpty(e.message)) rs.reason else e.message, rs.value) } else { - LOG.error("ERROR accessing resource", e) + LOG.error("ERROR accessing resource") } throw e } @@ -138,4 +138,4 @@ class ApiKeySecuredAspect(@Autowired val userService: UserService) { companion object { private val LOG = LoggerFactory.getLogger(ApiKeySecuredAspect::class.java) } -} \ No newline at end of file +} diff --git a/src/main/kotlin/io/realworld/model/inout/Login.kt b/src/main/kotlin/io/realworld/model/inout/Login.kt index c00a949..45803dd 100644 --- a/src/main/kotlin/io/realworld/model/inout/Login.kt +++ b/src/main/kotlin/io/realworld/model/inout/Login.kt @@ -9,7 +9,7 @@ import javax.validation.constraints.Size class Login { @NotNull(message = "can't be missing") @Size(min = 1, message = "can't be empty") - @Pattern(regexp="^[a-z0-9._%+-]+@[a-z0-9.-]+\\.[a-z]{2,4}$", message="must be a valid email") + @Pattern(regexp="^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,4}$", message="must be a valid email") var email: String? = "" @NotNull(message = "can't be missing") diff --git a/src/main/kotlin/io/realworld/model/inout/Register.kt b/src/main/kotlin/io/realworld/model/inout/Register.kt index 006a8ec..fee6ae1 100644 --- a/src/main/kotlin/io/realworld/model/inout/Register.kt +++ b/src/main/kotlin/io/realworld/model/inout/Register.kt @@ -14,7 +14,7 @@ class Register { @NotNull(message = "can't be missing") @Size(min = 1, message = "can't be empty") - @Pattern(regexp="^[a-z0-9._%+-]+@[a-z0-9.-]+\\.[a-z]{2,4}$", message="must be a valid email") + @Pattern(regexp="^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,4}$", message="must be a valid email") var email: String? = "" @NotNull(message = "can't be missing") diff --git a/src/main/kotlin/io/realworld/model/inout/UpdateUser.kt b/src/main/kotlin/io/realworld/model/inout/UpdateUser.kt index 1122ed0..a619a65 100644 --- a/src/main/kotlin/io/realworld/model/inout/UpdateUser.kt +++ b/src/main/kotlin/io/realworld/model/inout/UpdateUser.kt @@ -1,10 +1,21 @@ package io.realworld.model.inout import com.fasterxml.jackson.annotation.JsonRootName +import javax.validation.constraints.NotNull +import javax.validation.constraints.Pattern +import javax.validation.constraints.Size @JsonRootName("user") -data class UpdateUser(var username: String? = null, - var email: String? = null, - var password: String? = null, - var image: String? = null, - var bio: String? = null) \ No newline at end of file +class UpdateUser { + @Size(min = 1, message = "can't be empty") + @Pattern(regexp="^\\w+$", message = "must be alphanumeric") + var username: String? = null + + @Size(min = 1, message = "can't be empty") + @Pattern(regexp="^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,4}$", message="must be a valid email") + var email: String? = null + + var password: String? = null + var image: String? = "" + var bio: String? = "" +} \ No newline at end of file diff --git a/src/main/kotlin/io/realworld/web/ArticleHandler.kt b/src/main/kotlin/io/realworld/web/ArticleHandler.kt index 4351110..da33df4 100644 --- a/src/main/kotlin/io/realworld/web/ArticleHandler.kt +++ b/src/main/kotlin/io/realworld/web/ArticleHandler.kt @@ -20,6 +20,7 @@ import io.realworld.repository.specification.ArticlesSpecifications import io.realworld.service.UserService import org.springframework.data.domain.PageRequest import org.springframework.data.domain.Sort +import org.springframework.http.HttpStatus import org.springframework.validation.Errors import org.springframework.validation.FieldError import org.springframework.web.bind.annotation.* @@ -147,6 +148,7 @@ class ArticleHandler(val repository: ArticleRepository, } @ApiKeySecured + @ResponseStatus(HttpStatus.OK) @DeleteMapping("/api/articles/{slug}") fun deleteArticle(@PathVariable slug: String) { repository.findBySlug(slug)?.let { @@ -183,13 +185,18 @@ class ArticleHandler(val repository: ArticleRepository, } @ApiKeySecured + @ResponseStatus(HttpStatus.OK) @DeleteMapping("/api/articles/{slug}/comments/{id}") fun deleteComment(@PathVariable slug: String, @PathVariable id: Long) { repository.findBySlug(slug)?.let { + val currentUser = userService.currentUser() val comment = commentRepository.findById(id).orElseThrow({ NotFoundException() }) - if (comment.article.id == it.id) - return commentRepository.delete(comment) - throw ForbiddenRequestException() + if (comment.article.id != it.id) + throw ForbiddenRequestException() + if (comment.author.id != currentUser.id) + throw ForbiddenRequestException() + + return commentRepository.delete(comment) } throw NotFoundException() } diff --git a/src/main/kotlin/io/realworld/web/InvalidRequestHandler.kt b/src/main/kotlin/io/realworld/web/InvalidRequestHandler.kt index 828fd76..31743fc 100644 --- a/src/main/kotlin/io/realworld/web/InvalidRequestHandler.kt +++ b/src/main/kotlin/io/realworld/web/InvalidRequestHandler.kt @@ -29,7 +29,7 @@ class InvalidRequestHandler { @ResponseStatus(HttpStatus.UNPROCESSABLE_ENTITY) fun processValidationError(ex: InvalidException): Any { val errors = mutableMapOf<String, MutableList<String>>() - ex.errors.fieldErrors.forEach { + ex.errors?.fieldErrors?.forEach { if (errors.containsKey(it.field)) errors.get(it.field)!!.add(it.defaultMessage) else diff --git a/src/main/kotlin/io/realworld/web/UserHandler.kt b/src/main/kotlin/io/realworld/web/UserHandler.kt index bb7c2ab..2f73159 100644 --- a/src/main/kotlin/io/realworld/web/UserHandler.kt +++ b/src/main/kotlin/io/realworld/web/UserHandler.kt @@ -57,7 +57,9 @@ class UserHandler(val repository: UserRepository, @ApiKeySecured @PutMapping("/api/user") - fun updateUser(@RequestBody user: UpdateUser): Any { + fun updateUser(@Valid @RequestBody user: UpdateUser, errors: Errors): Any { + InvalidRequest.check(errors) + val currentUser = service.currentUser() // check for errors -- GitLab