From a02c995b6a04489d5a79dba3a8476887989c399f Mon Sep 17 00:00:00 2001 From: usbharu Date: Thu, 4 Apr 2024 12:57:24 +0900 Subject: [PATCH 1/7] =?UTF-8?q?feat:=20=E6=96=B0=E8=A6=8F=E3=82=A2?= =?UTF-8?q?=E3=82=AB=E3=82=A6=E3=83=B3=E3=83=88=E4=BD=9C=E6=88=90=E3=82=A8?= =?UTF-8?q?=E3=83=B3=E3=83=89=E3=83=9D=E3=82=A4=E3=83=B3=E3=83=88=E3=82=92?= =?UTF-8?q?=E5=88=86=E9=9B=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../exposedquery/NoteQueryServiceImpl.kt | 12 +++++------ .../interfaces/api/auth/AuthController.kt | 21 ++++++++++++++++++- .../core/interfaces/api/auth/SignUpForm.kt | 7 +++++++ .../core/service/auth/AuthApiService.kt | 8 +++++++ .../core/service/auth/RegisterAccountDto.kt | 7 +++++++ .../config/MastodonApiSecurityConfig.kt | 2 +- src/main/resources/templates/sign_up.html | 12 ++++++++++- 7 files changed, 60 insertions(+), 9 deletions(-) create mode 100644 src/main/kotlin/dev/usbharu/hideout/core/interfaces/api/auth/SignUpForm.kt create mode 100644 src/main/kotlin/dev/usbharu/hideout/core/service/auth/AuthApiService.kt create mode 100644 src/main/kotlin/dev/usbharu/hideout/core/service/auth/RegisterAccountDto.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/infrastructure/exposedquery/NoteQueryServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/activitypub/infrastructure/exposedquery/NoteQueryServiceImpl.kt index b69475c7..85ee76ae 100644 --- a/src/main/kotlin/dev/usbharu/hideout/activitypub/infrastructure/exposedquery/NoteQueryServiceImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/activitypub/infrastructure/exposedquery/NoteQueryServiceImpl.kt @@ -43,9 +43,9 @@ class NoteQueryServiceImpl(private val postRepository: PostRepository, private v .selectAll().where { Posts.id eq id } .let { (it.toNote() ?: return null) to ( - postQueryMapper.map(it) - .singleOrNull() ?: return null - ) + postQueryMapper.map(it) + .singleOrNull() ?: return null + ) } } @@ -57,9 +57,9 @@ class NoteQueryServiceImpl(private val postRepository: PostRepository, private v .selectAll().where { Posts.apId eq apId } .let { (it.toNote() ?: return null) to ( - postQueryMapper.map(it) - .singleOrNull() ?: return null - ) + postQueryMapper.map(it) + .singleOrNull() ?: return null + ) } } diff --git a/src/main/kotlin/dev/usbharu/hideout/core/interfaces/api/auth/AuthController.kt b/src/main/kotlin/dev/usbharu/hideout/core/interfaces/api/auth/AuthController.kt index 7b582c77..93e05968 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/interfaces/api/auth/AuthController.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/interfaces/api/auth/AuthController.kt @@ -16,12 +16,31 @@ package dev.usbharu.hideout.core.interfaces.api.auth +import dev.usbharu.hideout.core.service.auth.AuthApiService +import dev.usbharu.hideout.core.service.auth.RegisterAccountDto import org.springframework.stereotype.Controller +import org.springframework.ui.Model +import org.springframework.validation.annotation.Validated import org.springframework.web.bind.annotation.GetMapping +import org.springframework.web.bind.annotation.ModelAttribute +import org.springframework.web.bind.annotation.PostMapping @Controller -class AuthController { +class AuthController(private val authApiService: AuthApiService) { @GetMapping("/auth/sign_up") @Suppress("FunctionOnlyReturningConstant") fun signUp(): String = "sign_up" + + @PostMapping("/auth/sign_up") + suspend fun signUp(@Validated @ModelAttribute signUpForm: SignUpForm, model: Model): String { + val registerAccount = authApiService.registerAccount( + RegisterAccountDto( + signUpForm.username, + signUpForm.password, + signUpForm.recaptchaResponse + ) + ) + + return "redirect:"+registerAccount.first.url + } } diff --git a/src/main/kotlin/dev/usbharu/hideout/core/interfaces/api/auth/SignUpForm.kt b/src/main/kotlin/dev/usbharu/hideout/core/interfaces/api/auth/SignUpForm.kt new file mode 100644 index 00000000..5c032c5a --- /dev/null +++ b/src/main/kotlin/dev/usbharu/hideout/core/interfaces/api/auth/SignUpForm.kt @@ -0,0 +1,7 @@ +package dev.usbharu.hideout.core.interfaces.api.auth + +data class SignUpForm( + val username: String, + val password: String, + val recaptchaResponse: String +) diff --git a/src/main/kotlin/dev/usbharu/hideout/core/service/auth/AuthApiService.kt b/src/main/kotlin/dev/usbharu/hideout/core/service/auth/AuthApiService.kt new file mode 100644 index 00000000..80179321 --- /dev/null +++ b/src/main/kotlin/dev/usbharu/hideout/core/service/auth/AuthApiService.kt @@ -0,0 +1,8 @@ +package dev.usbharu.hideout.core.service.auth + +import dev.usbharu.hideout.core.domain.model.actor.Actor +import dev.usbharu.hideout.core.domain.model.userdetails.UserDetail + +interface AuthApiService { + suspend fun registerAccount(registerAccountDto: RegisterAccountDto): Pair +} \ No newline at end of file diff --git a/src/main/kotlin/dev/usbharu/hideout/core/service/auth/RegisterAccountDto.kt b/src/main/kotlin/dev/usbharu/hideout/core/service/auth/RegisterAccountDto.kt new file mode 100644 index 00000000..84a2d881 --- /dev/null +++ b/src/main/kotlin/dev/usbharu/hideout/core/service/auth/RegisterAccountDto.kt @@ -0,0 +1,7 @@ +package dev.usbharu.hideout.core.service.auth + +data class RegisterAccountDto( + val username:String, + val password:String, + val recaptchaResponse:String +) diff --git a/src/main/kotlin/dev/usbharu/hideout/mastodon/config/MastodonApiSecurityConfig.kt b/src/main/kotlin/dev/usbharu/hideout/mastodon/config/MastodonApiSecurityConfig.kt index 39ec70fb..c4bce048 100644 --- a/src/main/kotlin/dev/usbharu/hideout/mastodon/config/MastodonApiSecurityConfig.kt +++ b/src/main/kotlin/dev/usbharu/hideout/mastodon/config/MastodonApiSecurityConfig.kt @@ -41,7 +41,7 @@ class MastodonApiSecurityConfig { authorizeHttpRequests { authorize(POST, "/api/v1/apps", permitAll) authorize(GET, "/api/v1/instance/**", permitAll) - authorize(POST, "/api/v1/accounts", permitAll) + authorize(POST, "/api/v1/accounts", authenticated) authorize(GET, "/api/v1/accounts/verify_credentials", rf.hasScope("read:accounts")) authorize(GET, "/api/v1/accounts/relationships", rf.hasScope("read:follows")) diff --git a/src/main/resources/templates/sign_up.html b/src/main/resources/templates/sign_up.html index 079fdd7c..ce36b424 100644 --- a/src/main/resources/templates/sign_up.html +++ b/src/main/resources/templates/sign_up.html @@ -3,12 +3,22 @@ SignUp + + -
+ +
From c579efb1104ac54f06793948df127e15ffa28234 Mon Sep 17 00:00:00 2001 From: usbharu Date: Thu, 4 Apr 2024 15:14:22 +0900 Subject: [PATCH 2/7] =?UTF-8?q?feat:=20reCAPTCHA=E4=BA=8C=E5=AF=BE?= =?UTF-8?q?=E5=BF=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../application/config/CaptchaConfig.kt | 8 +++ .../core/service/auth/AuthApiService.kt | 2 +- .../core/service/auth/AuthApiServiceImpl.kt | 50 +++++++++++++++++++ .../core/service/auth/RecaptchaResult.kt | 9 ++++ 4 files changed, 68 insertions(+), 1 deletion(-) create mode 100644 src/main/kotlin/dev/usbharu/hideout/application/config/CaptchaConfig.kt create mode 100644 src/main/kotlin/dev/usbharu/hideout/core/service/auth/AuthApiServiceImpl.kt create mode 100644 src/main/kotlin/dev/usbharu/hideout/core/service/auth/RecaptchaResult.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/application/config/CaptchaConfig.kt b/src/main/kotlin/dev/usbharu/hideout/application/config/CaptchaConfig.kt new file mode 100644 index 00000000..217b2fa9 --- /dev/null +++ b/src/main/kotlin/dev/usbharu/hideout/application/config/CaptchaConfig.kt @@ -0,0 +1,8 @@ +package dev.usbharu.hideout.application.config + +import org.springframework.boot.context.properties.ConfigurationProperties + +@ConfigurationProperties("hideout.security") +data class CaptchaConfig( + val reCaptchaSiteKey:String +) diff --git a/src/main/kotlin/dev/usbharu/hideout/core/service/auth/AuthApiService.kt b/src/main/kotlin/dev/usbharu/hideout/core/service/auth/AuthApiService.kt index 80179321..ccd46365 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/service/auth/AuthApiService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/service/auth/AuthApiService.kt @@ -4,5 +4,5 @@ import dev.usbharu.hideout.core.domain.model.actor.Actor import dev.usbharu.hideout.core.domain.model.userdetails.UserDetail interface AuthApiService { - suspend fun registerAccount(registerAccountDto: RegisterAccountDto): Pair + suspend fun registerAccount(registerAccountDto: RegisterAccountDto): Actor } \ No newline at end of file diff --git a/src/main/kotlin/dev/usbharu/hideout/core/service/auth/AuthApiServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/core/service/auth/AuthApiServiceImpl.kt new file mode 100644 index 00000000..a749dc0c --- /dev/null +++ b/src/main/kotlin/dev/usbharu/hideout/core/service/auth/AuthApiServiceImpl.kt @@ -0,0 +1,50 @@ +package dev.usbharu.hideout.core.service.auth + +import com.fasterxml.jackson.databind.ObjectMapper +import com.fasterxml.jackson.module.kotlin.readValue +import dev.usbharu.hideout.application.config.CaptchaConfig +import dev.usbharu.hideout.core.domain.model.actor.Actor +import dev.usbharu.hideout.core.domain.model.userdetails.UserDetail +import dev.usbharu.hideout.core.service.user.UserCreateDto +import dev.usbharu.hideout.core.service.user.UserService +import io.ktor.client.* +import io.ktor.client.request.* +import io.ktor.client.statement.* +import org.slf4j.LoggerFactory +import org.springframework.stereotype.Service + +@Service +class AuthApiServiceImpl( + private val httpClient: HttpClient, + private val captchaConfig: CaptchaConfig, + private val objectMapper: ObjectMapper, + private val userService: UserService +) : + AuthApiService { + override suspend fun registerAccount(registerAccountDto: RegisterAccountDto): Actor { + val get = + httpClient.get("https://www.google.com/recaptcha/api/siteverify?secret=" + captchaConfig.reCaptchaSiteKey + "&response=" + registerAccountDto.recaptchaResponse) + + val recaptchaResult = objectMapper.readValue(get.bodyAsText()) + + logger.debug("reCAPTCHA: {}",recaptchaResult) + + require(recaptchaResult.success) + require(!(recaptchaResult.score < 0.5)) + + val createLocalUser = userService.createLocalUser( + UserCreateDto( + registerAccountDto.username, + registerAccountDto.username, + "", + registerAccountDto.password + ) + ) + + return createLocalUser + } + + companion object { + private val logger = LoggerFactory.getLogger(AuthApiServiceImpl::class.java) + } +} \ No newline at end of file diff --git a/src/main/kotlin/dev/usbharu/hideout/core/service/auth/RecaptchaResult.kt b/src/main/kotlin/dev/usbharu/hideout/core/service/auth/RecaptchaResult.kt new file mode 100644 index 00000000..ef710fa1 --- /dev/null +++ b/src/main/kotlin/dev/usbharu/hideout/core/service/auth/RecaptchaResult.kt @@ -0,0 +1,9 @@ +package dev.usbharu.hideout.core.service.auth + +data class RecaptchaResult( + val success: Boolean, + val challenge_ts: String, + val hostname: String, + val score: Float, + val action: String +) From 9327bb03724838a0d627afe5fe480bc9ddcfb1d5 Mon Sep 17 00:00:00 2001 From: usbharu Date: Thu, 4 Apr 2024 17:26:15 +0900 Subject: [PATCH 3/7] =?UTF-8?q?feat:=20=E3=83=87=E3=83=95=E3=82=A9?= =?UTF-8?q?=E3=83=AB=E3=83=88=E3=81=A7=E3=81=AF=E7=99=BB=E9=8C=B2=E4=B8=8D?= =?UTF-8?q?=E5=8F=AF=E3=81=AB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dev/usbharu/hideout/application/config/SpringConfig.kt | 3 ++- .../dev/usbharu/hideout/core/service/user/UserServiceImpl.kt | 4 ++++ src/main/resources/application.yml | 1 + 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/main/kotlin/dev/usbharu/hideout/application/config/SpringConfig.kt b/src/main/kotlin/dev/usbharu/hideout/application/config/SpringConfig.kt index 38c78e30..b2178286 100644 --- a/src/main/kotlin/dev/usbharu/hideout/application/config/SpringConfig.kt +++ b/src/main/kotlin/dev/usbharu/hideout/application/config/SpringConfig.kt @@ -44,7 +44,8 @@ class SpringConfig { @ConfigurationProperties("hideout") data class ApplicationConfig( - val url: URL + val url: URL, + val private:Boolean = true ) @ConfigurationProperties("hideout.storage.s3") diff --git a/src/main/kotlin/dev/usbharu/hideout/core/service/user/UserServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/core/service/user/UserServiceImpl.kt index 294656ca..2149f343 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/service/user/UserServiceImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/service/user/UserServiceImpl.kt @@ -59,6 +59,10 @@ class UserServiceImpl( } override suspend fun createLocalUser(user: UserCreateDto): Actor { + if (applicationConfig.private) { + throw IllegalStateException("Instance is a private mode.") + } + val nextId = actorRepository.nextId() val hashedPassword = userAuthService.hash(user.password) val keyPair = userAuthService.generateKeyPair() diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 87da1774..5756484e 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -7,6 +7,7 @@ hideout: key-id: a private-key: "MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQC7VJTUt9Us8cKjMzEfYyjiWA4R4/M2bS1GB4t7NXp98C3SC6dVMvDuictGeurT8jNbvJZHtCSuYEvuNMoSfm76oqFvAp8Gy0iz5sxjZmSnXyCdPEovGhLa0VzMaQ8s+CLOyS56YyCFGeJZqgtzJ6GR3eqoYSW9b9UMvkBpZODSctWSNGj3P7jRFDO5VoTwCQAWbFnOjDfH5Ulgp2PKSQnSJP3AJLQNFNe7br1XbrhV//eO+t51mIpGSDCUv3E0DDFcWDTH9cXDTTlRZVEiR2BwpZOOkE/Z0/BVnhZYL71oZV34bKfWjQIt6V/isSMahdsAASACp4ZTGtwiVuNd9tybAgMBAAECggEBAKTmjaS6tkK8BlPXClTQ2vpz/N6uxDeS35mXpqasqskVlaAidgg/sWqpjXDbXr93otIMLlWsM+X0CqMDgSXKejLS2jx4GDjI1ZTXg++0AMJ8sJ74pWzVDOfmCEQ/7wXs3+cbnXhKriO8Z036q92Qc1+N87SI38nkGa0ABH9CN83HmQqt4fB7UdHzuIRe/me2PGhIq5ZBzj6h3BpoPGzEP+x3l9YmK8t/1cN0pqI+dQwYdgfGjackLu/2qH80MCF7IyQaseZUOJyKrCLtSD/Iixv/hzDEUPfOCjFDgTpzf3cwta8+oE4wHCo1iI1/4TlPkwmXx4qSXtmw4aQPz7IDQvECgYEA8KNThCO2gsC2I9PQDM/8Cw0O983WCDY+oi+7JPiNAJwv5DYBqEZB1QYdj06YD16XlC/HAZMsMku1na2TN0driwenQQWzoev3g2S7gRDoS/FCJSI3jJ+kjgtaA7Qmzlgk1TxODN+G1H91HW7t0l7VnL27IWyYo2qRRK3jzxqUiPUCgYEAx0oQs2reBQGMVZnApD1jeq7n4MvNLcPvt8b/eU9iUv6Y4Mj0Suo/AU8lYZXm8ubbqAlwz2VSVunD2tOplHyMUrtCtObAfVDUAhCndKaA9gApgfb3xw1IKbuQ1u4IF1FJl3VtumfQn//LiH1B3rXhcdyo3/vIttEk48RakUKClU8CgYEAzV7W3COOlDDcQd935DdtKBFRAPRPAlspQUnzMi5eSHMD/ISLDY5IiQHbIH83D4bvXq0X7qQoSBSNP7Dvv3HYuqMhf0DaegrlBuJllFVVq9qPVRnKxt1Il2HgxOBvbhOT+9in1BzA+YJ99UzC85O0Qz06A+CmtHEy4aZ2kj5hHjECgYEAmNS4+A8Fkss8Js1RieK2LniBxMgmYml3pfVLKGnzmng7H2+cwPLhPIzIuwytXywh2bzbsYEfYx3EoEVgMEpPhoarQnYPukrJO4gwE2o5Te6T5mJSZGlQJQj9q4ZB2Dfzet6INsK0oG8XVGXSpQvQh3RUYekCZQkBBFcpqWpbIEsCgYAnM3DQf3FJoSnXaMhrVBIovic5l0xFkEHskAjFTevO86Fsz1C2aSeRKSqGFoOQ0tmJzBEs1R6KqnHInicDTQrKhArgLXX4v3CddjfTRJkFWDbE/CkvKZNOrcf1nhaGCPspRJj2KUkj1Fhl9Cncdn/RsYEONbwQSjIfMPkvxF+8HQ==" public-key: "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAu1SU1LfVLPHCozMxH2Mo4lgOEePzNm0tRgeLezV6ffAt0gunVTLw7onLRnrq0/IzW7yWR7QkrmBL7jTKEn5u+qKhbwKfBstIs+bMY2Zkp18gnTxKLxoS2tFczGkPLPgizskuemMghRniWaoLcyehkd3qqGElvW/VDL5AaWTg0nLVkjRo9z+40RQzuVaE8AkAFmxZzow3x+VJYKdjykkJ0iT9wCS0DRTXu269V264Vf/3jvredZiKRkgwlL9xNAwxXFg0x/XFw005UWVRIkdgcKWTjpBP2dPwVZ4WWC+9aGVd+Gyn1o0CLelf4rEjGoXbAAEgAqeGUxrcIlbjXfbcmwIDAQAB" + private: true From 5b322ade297c9a53cac34f69b1ed0546abedf528 Mon Sep 17 00:00:00 2001 From: usbharu Date: Thu, 4 Apr 2024 17:37:05 +0900 Subject: [PATCH 4/7] =?UTF-8?q?feat:=20=E7=99=BB=E9=8C=B2=E4=B8=8D?= =?UTF-8?q?=E5=8F=AF=E6=99=82=E3=81=ABHTML=E3=81=A7submit=E3=81=A7?= =?UTF-8?q?=E3=81=8D=E3=81=AA=E3=81=84=E3=82=88=E3=81=86=E3=81=AB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../core/interfaces/api/auth/AuthController.kt | 17 +++++++++++++---- src/main/resources/templates/sign_up.html | 2 +- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/src/main/kotlin/dev/usbharu/hideout/core/interfaces/api/auth/AuthController.kt b/src/main/kotlin/dev/usbharu/hideout/core/interfaces/api/auth/AuthController.kt index 93e05968..bbda1b84 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/interfaces/api/auth/AuthController.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/interfaces/api/auth/AuthController.kt @@ -16,6 +16,8 @@ package dev.usbharu.hideout.core.interfaces.api.auth +import dev.usbharu.hideout.application.config.ApplicationConfig +import dev.usbharu.hideout.application.config.CaptchaConfig import dev.usbharu.hideout.core.service.auth.AuthApiService import dev.usbharu.hideout.core.service.auth.RegisterAccountDto import org.springframework.stereotype.Controller @@ -26,10 +28,17 @@ import org.springframework.web.bind.annotation.ModelAttribute import org.springframework.web.bind.annotation.PostMapping @Controller -class AuthController(private val authApiService: AuthApiService) { +class AuthController( + private val authApiService: AuthApiService, + private val captchaConfig: CaptchaConfig, + private val applicationConfig: ApplicationConfig +) { @GetMapping("/auth/sign_up") - @Suppress("FunctionOnlyReturningConstant") - fun signUp(): String = "sign_up" + fun signUp(model: Model): String { + model.addAttribute("siteKey", captchaConfig.reCaptchaSiteKey) + model.addAttribute("applicationConfig", applicationConfig) + return "sign_up" + } @PostMapping("/auth/sign_up") suspend fun signUp(@Validated @ModelAttribute signUpForm: SignUpForm, model: Model): String { @@ -41,6 +50,6 @@ class AuthController(private val authApiService: AuthApiService) { ) ) - return "redirect:"+registerAccount.first.url + return "redirect:" + registerAccount.url } } diff --git a/src/main/resources/templates/sign_up.html b/src/main/resources/templates/sign_up.html index ce36b424..d7a16999 100644 --- a/src/main/resources/templates/sign_up.html +++ b/src/main/resources/templates/sign_up.html @@ -15,7 +15,7 @@ -
+ From 4218431012ab8e1772dabdf2127ee1649a5aa6ec Mon Sep 17 00:00:00 2001 From: usbharu Date: Thu, 4 Apr 2024 18:08:39 +0900 Subject: [PATCH 5/7] =?UTF-8?q?fix:=20sitekey=E3=81=A8secret=E3=82=92?= =?UTF-8?q?=E6=B7=B7=E5=90=8C=E3=82=92=E3=81=97=E3=81=A6=E3=81=84=E3=81=9F?= =?UTF-8?q?=E3=81=AE=E3=82=92=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/e2eTest/resources/application.yml | 1 + src/intTest/resources/application.yml | 1 + .../application/config/CaptchaConfig.kt | 3 +- .../core/service/auth/AuthApiServiceImpl.kt | 17 +++++---- .../core/service/user/ActorServiceTest.kt | 36 ++++++++++++++++++- 5 files changed, 47 insertions(+), 11 deletions(-) diff --git a/src/e2eTest/resources/application.yml b/src/e2eTest/resources/application.yml index 73e011d0..778035ba 100644 --- a/src/e2eTest/resources/application.yml +++ b/src/e2eTest/resources/application.yml @@ -12,6 +12,7 @@ hideout: debug: trace-query-exception: true trace-query-call: true + private: false spring: flyway: diff --git a/src/intTest/resources/application.yml b/src/intTest/resources/application.yml index 6f788e6d..57ab70fa 100644 --- a/src/intTest/resources/application.yml +++ b/src/intTest/resources/application.yml @@ -12,6 +12,7 @@ hideout: public-key: "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAu1SU1LfVLPHCozMxH2Mo4lgOEePzNm0tRgeLezV6ffAt0gunVTLw7onLRnrq0/IzW7yWR7QkrmBL7jTKEn5u+qKhbwKfBstIs+bMY2Zkp18gnTxKLxoS2tFczGkPLPgizskuemMghRniWaoLcyehkd3qqGElvW/VDL5AaWTg0nLVkjRo9z+40RQzuVaE8AkAFmxZzow3x+VJYKdjykkJ0iT9wCS0DRTXu269V264Vf/3jvredZiKRkgwlL9xNAwxXFg0x/XFw005UWVRIkdgcKWTjpBP2dPwVZ4WWC+9aGVd+Gyn1o0CLelf4rEjGoXbAAEgAqeGUxrcIlbjXfbcmwIDAQAB" storage: type: local + private: false spring: flyway: diff --git a/src/main/kotlin/dev/usbharu/hideout/application/config/CaptchaConfig.kt b/src/main/kotlin/dev/usbharu/hideout/application/config/CaptchaConfig.kt index 217b2fa9..ac8237f6 100644 --- a/src/main/kotlin/dev/usbharu/hideout/application/config/CaptchaConfig.kt +++ b/src/main/kotlin/dev/usbharu/hideout/application/config/CaptchaConfig.kt @@ -4,5 +4,6 @@ import org.springframework.boot.context.properties.ConfigurationProperties @ConfigurationProperties("hideout.security") data class CaptchaConfig( - val reCaptchaSiteKey:String + val reCaptchaSiteKey: String?, + val reCaptchaSecretKey: String? ) diff --git a/src/main/kotlin/dev/usbharu/hideout/core/service/auth/AuthApiServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/core/service/auth/AuthApiServiceImpl.kt index a749dc0c..bdf2d252 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/service/auth/AuthApiServiceImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/service/auth/AuthApiServiceImpl.kt @@ -4,7 +4,6 @@ import com.fasterxml.jackson.databind.ObjectMapper import com.fasterxml.jackson.module.kotlin.readValue import dev.usbharu.hideout.application.config.CaptchaConfig import dev.usbharu.hideout.core.domain.model.actor.Actor -import dev.usbharu.hideout.core.domain.model.userdetails.UserDetail import dev.usbharu.hideout.core.service.user.UserCreateDto import dev.usbharu.hideout.core.service.user.UserService import io.ktor.client.* @@ -22,15 +21,15 @@ class AuthApiServiceImpl( ) : AuthApiService { override suspend fun registerAccount(registerAccountDto: RegisterAccountDto): Actor { - val get = - httpClient.get("https://www.google.com/recaptcha/api/siteverify?secret=" + captchaConfig.reCaptchaSiteKey + "&response=" + registerAccountDto.recaptchaResponse) + if (captchaConfig.reCaptchaSecretKey != null && captchaConfig.reCaptchaSiteKey != null) { + val get = + httpClient.get("https://www.google.com/recaptcha/api/siteverify?secret=" + captchaConfig.reCaptchaSecretKey + "&response=" + registerAccountDto.recaptchaResponse) + val recaptchaResult = objectMapper.readValue(get.bodyAsText()) + logger.debug("reCAPTCHA: {}", recaptchaResult) + require(recaptchaResult.success) + require(!(recaptchaResult.score < 0.5)) + } - val recaptchaResult = objectMapper.readValue(get.bodyAsText()) - - logger.debug("reCAPTCHA: {}",recaptchaResult) - - require(recaptchaResult.success) - require(!(recaptchaResult.score < 0.5)) val createLocalUser = userService.createLocalUser( UserCreateDto( diff --git a/src/test/kotlin/dev/usbharu/hideout/core/service/user/ActorServiceTest.kt b/src/test/kotlin/dev/usbharu/hideout/core/service/user/ActorServiceTest.kt index 846c0d9e..7a22a57b 100644 --- a/src/test/kotlin/dev/usbharu/hideout/core/service/user/ActorServiceTest.kt +++ b/src/test/kotlin/dev/usbharu/hideout/core/service/user/ActorServiceTest.kt @@ -28,6 +28,7 @@ import jakarta.validation.Validation import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.test.runTest import org.junit.jupiter.api.Test +import org.junit.jupiter.api.assertThrows import org.mockito.ArgumentMatchers.anyString import org.mockito.kotlin.* import utils.TestApplicationConfig.testApplicationConfig @@ -60,7 +61,7 @@ class ActorServiceTest { actorRepository = actorRepository, userAuthService = userAuthService, actorBuilder = actorBuilder, - applicationConfig = testApplicationConfig, + applicationConfig = testApplicationConfig.copy(private = false), instanceService = mock(), userDetailRepository = mock(), deletedActorRepository = mock(), @@ -87,6 +88,39 @@ class ActorServiceTest { } } + @Test + fun `createLocalUser applicationconfig privateがtrueのときアカウントを作成できない`() = runTest { + + val actorRepository = mock { + onBlocking { nextId() } doReturn 110001L + } + val generateKeyPair = KeyPairGenerator.getInstance("RSA").generateKeyPair() + val userAuthService = mock { + onBlocking { hash(anyString()) } doReturn "hashedPassword" + onBlocking { generateKeyPair() } doReturn generateKeyPair + } + val userService = + UserServiceImpl( + actorRepository = actorRepository, + userAuthService = userAuthService, + actorBuilder = actorBuilder, + applicationConfig = testApplicationConfig.copy(private = true), + instanceService = mock(), + userDetailRepository = mock(), + deletedActorRepository = mock(), + reactionRepository = mock(), + relationshipRepository = mock(), + postService = mock(), + apSendDeleteService = mock(), + postRepository = mock() + ) + + assertThrows { + userService.createLocalUser(UserCreateDto("test", "testUser", "XXXXXXXXXXXXX", "test")) + } + + } + @Test fun `createRemoteUser リモートユーザーを作成できる`() = runTest { From 931a7a638a7c4e27fb25cb38ad44daccd68e6ff2 Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Thu, 16 May 2024 15:34:32 +0900 Subject: [PATCH 6/7] =?UTF-8?q?chore:=20=E3=83=9E=E3=83=BC=E3=82=B8?= =?UTF-8?q?=E3=82=92=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../application/config/SecurityConfig.kt | 2 +- .../core/service/auth/AuthApiService.kt | 23 +++++++++++++++++ .../core/service/auth/AuthApiServiceImpl.kt | 16 ++++++++++++ .../core/service/auth/RecaptchaResult.kt | 25 +++++++++++++++++++ .../core/service/auth/RegisterAccountDto.kt | 23 +++++++++++++++++ .../src/main/resources/templates/sign_up.html | 3 ++- .../core/service/auth/AuthApiService.kt | 8 ------ .../core/service/auth/RecaptchaResult.kt | 9 ------- .../core/service/auth/RegisterAccountDto.kt | 7 ------ 9 files changed, 90 insertions(+), 26 deletions(-) create mode 100644 hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/auth/AuthApiService.kt rename {src => hideout-core/src}/main/kotlin/dev/usbharu/hideout/core/service/auth/AuthApiServiceImpl.kt (75%) create mode 100644 hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/auth/RecaptchaResult.kt create mode 100644 hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/auth/RegisterAccountDto.kt delete mode 100644 src/main/kotlin/dev/usbharu/hideout/core/service/auth/AuthApiService.kt delete mode 100644 src/main/kotlin/dev/usbharu/hideout/core/service/auth/RecaptchaResult.kt delete mode 100644 src/main/kotlin/dev/usbharu/hideout/core/service/auth/RegisterAccountDto.kt diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/application/config/SecurityConfig.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/application/config/SecurityConfig.kt index b4f6fb05..a4a68a37 100644 --- a/hideout-core/src/main/kotlin/dev/usbharu/hideout/application/config/SecurityConfig.kt +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/application/config/SecurityConfig.kt @@ -215,7 +215,7 @@ class SecurityConfig { authorize(GET, "/users/*", permitAll) authorize(GET, "/users/*/posts/*", permitAll) - authorize("/auth/sign_up", hasRole("ANONYMOUS")) + authorize("/dev/usbharu/hideout/core/service/auth/sign_up", hasRole("ANONYMOUS")) authorize(GET, "/files/*", permitAll) authorize(GET, "/users/*/icon.jpg", permitAll) authorize(GET, "/users/*/header.jpg", permitAll) diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/auth/AuthApiService.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/auth/AuthApiService.kt new file mode 100644 index 00000000..e4ca5a32 --- /dev/null +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/auth/AuthApiService.kt @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2024 usbharu + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dev.usbharu.hideout.core.service.auth + +import dev.usbharu.hideout.core.domain.model.actor.Actor + +interface AuthApiService { + suspend fun registerAccount(registerAccountDto: RegisterAccountDto): Actor +} \ No newline at end of file diff --git a/src/main/kotlin/dev/usbharu/hideout/core/service/auth/AuthApiServiceImpl.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/auth/AuthApiServiceImpl.kt similarity index 75% rename from src/main/kotlin/dev/usbharu/hideout/core/service/auth/AuthApiServiceImpl.kt rename to hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/auth/AuthApiServiceImpl.kt index bdf2d252..bfdd81d1 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/service/auth/AuthApiServiceImpl.kt +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/auth/AuthApiServiceImpl.kt @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2024 usbharu + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package dev.usbharu.hideout.core.service.auth import com.fasterxml.jackson.databind.ObjectMapper diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/auth/RecaptchaResult.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/auth/RecaptchaResult.kt new file mode 100644 index 00000000..956fbcd9 --- /dev/null +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/auth/RecaptchaResult.kt @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2024 usbharu + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dev.usbharu.hideout.core.service.auth + +data class RecaptchaResult( + val success: Boolean, + val challenge_ts: String, + val hostname: String, + val score: Float, + val action: String +) diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/auth/RegisterAccountDto.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/auth/RegisterAccountDto.kt new file mode 100644 index 00000000..fec3ced4 --- /dev/null +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/service/auth/RegisterAccountDto.kt @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2024 usbharu + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dev.usbharu.hideout.core.service.auth + +data class RegisterAccountDto( + val username:String, + val password:String, + val recaptchaResponse:String +) diff --git a/hideout-core/src/main/resources/templates/sign_up.html b/hideout-core/src/main/resources/templates/sign_up.html index d7a16999..3408bb8a 100644 --- a/hideout-core/src/main/resources/templates/sign_up.html +++ b/hideout-core/src/main/resources/templates/sign_up.html @@ -15,7 +15,8 @@ - + diff --git a/src/main/kotlin/dev/usbharu/hideout/core/service/auth/AuthApiService.kt b/src/main/kotlin/dev/usbharu/hideout/core/service/auth/AuthApiService.kt deleted file mode 100644 index ccd46365..00000000 --- a/src/main/kotlin/dev/usbharu/hideout/core/service/auth/AuthApiService.kt +++ /dev/null @@ -1,8 +0,0 @@ -package dev.usbharu.hideout.core.service.auth - -import dev.usbharu.hideout.core.domain.model.actor.Actor -import dev.usbharu.hideout.core.domain.model.userdetails.UserDetail - -interface AuthApiService { - suspend fun registerAccount(registerAccountDto: RegisterAccountDto): Actor -} \ No newline at end of file diff --git a/src/main/kotlin/dev/usbharu/hideout/core/service/auth/RecaptchaResult.kt b/src/main/kotlin/dev/usbharu/hideout/core/service/auth/RecaptchaResult.kt deleted file mode 100644 index ef710fa1..00000000 --- a/src/main/kotlin/dev/usbharu/hideout/core/service/auth/RecaptchaResult.kt +++ /dev/null @@ -1,9 +0,0 @@ -package dev.usbharu.hideout.core.service.auth - -data class RecaptchaResult( - val success: Boolean, - val challenge_ts: String, - val hostname: String, - val score: Float, - val action: String -) diff --git a/src/main/kotlin/dev/usbharu/hideout/core/service/auth/RegisterAccountDto.kt b/src/main/kotlin/dev/usbharu/hideout/core/service/auth/RegisterAccountDto.kt deleted file mode 100644 index 84a2d881..00000000 --- a/src/main/kotlin/dev/usbharu/hideout/core/service/auth/RegisterAccountDto.kt +++ /dev/null @@ -1,7 +0,0 @@ -package dev.usbharu.hideout.core.service.auth - -data class RegisterAccountDto( - val username:String, - val password:String, - val recaptchaResponse:String -) From b686ac295f061685662fcdf2fea20451887e97d9 Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Thu, 16 May 2024 15:53:17 +0900 Subject: [PATCH 7/7] =?UTF-8?q?test:=20=E5=BF=85=E8=A6=81=E3=81=AB?= =?UTF-8?q?=E3=81=AA=E3=81=A3=E3=81=9F=E6=A8=A9=E9=99=90=E3=82=92=E8=BF=BD?= =?UTF-8?q?=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/intTest/kotlin/mastodon/account/AccountApiTest.kt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/hideout-core/src/intTest/kotlin/mastodon/account/AccountApiTest.kt b/hideout-core/src/intTest/kotlin/mastodon/account/AccountApiTest.kt index c936764d..6b482f85 100644 --- a/hideout-core/src/intTest/kotlin/mastodon/account/AccountApiTest.kt +++ b/hideout-core/src/intTest/kotlin/mastodon/account/AccountApiTest.kt @@ -113,6 +113,7 @@ class AccountApiTest { param("email", "test@example.com") param("agreement", "true") param("locale", "") + with(jwt()) with(csrf()) } .asyncDispatch() @@ -129,6 +130,7 @@ class AccountApiTest { contentType = MediaType.APPLICATION_FORM_URLENCODED param("username", "api-test-user-2") param("password", "very-secure-password") + with(jwt()) with(csrf()) } .asyncDispatch() @@ -145,6 +147,7 @@ class AccountApiTest { contentType = MediaType.APPLICATION_FORM_URLENCODED param("password", "api-test-user-3") with(csrf()) + with(jwt()) } .andDo { print() } .andExpect { status { isUnprocessableEntity() } } @@ -158,6 +161,7 @@ class AccountApiTest { contentType = MediaType.APPLICATION_FORM_URLENCODED param("username", "api-test-user-4") with(csrf()) + with(jwt()) } .andExpect { status { isUnprocessableEntity() } } }