mirror of https://github.com/usbharu/Hideout.git
実際に起動できるように
This commit is contained in:
parent
bd747718d4
commit
5e7b538d1d
|
@ -165,6 +165,7 @@ dependencies {
|
||||||
implementation("org.springframework.boot:spring-boot-starter-log4j2")
|
implementation("org.springframework.boot:spring-boot-starter-log4j2")
|
||||||
implementation("org.springframework.boot:spring-boot-starter-validation")
|
implementation("org.springframework.boot:spring-boot-starter-validation")
|
||||||
|
|
||||||
|
|
||||||
implementation(libs.blurhash)
|
implementation(libs.blurhash)
|
||||||
implementation(libs.aws.s3)
|
implementation(libs.aws.s3)
|
||||||
implementation(libs.jsoup)
|
implementation(libs.jsoup)
|
||||||
|
@ -173,6 +174,7 @@ dependencies {
|
||||||
implementation(libs.imageio.webp)
|
implementation(libs.imageio.webp)
|
||||||
implementation(libs.thumbnailator)
|
implementation(libs.thumbnailator)
|
||||||
implementation(libs.flyway.core)
|
implementation(libs.flyway.core)
|
||||||
|
runtimeOnly(libs.flyway.postgresql)
|
||||||
|
|
||||||
implementation("dev.usbharu:owl-common-serialize-jackson:0.0.1")
|
implementation("dev.usbharu:owl-common-serialize-jackson:0.0.1")
|
||||||
|
|
||||||
|
|
|
@ -23,4 +23,5 @@ import java.net.URL
|
||||||
data class ApplicationConfig(
|
data class ApplicationConfig(
|
||||||
val url: URL,
|
val url: URL,
|
||||||
val private: Boolean = true,
|
val private: Boolean = true,
|
||||||
|
val keySize: Int = 2048,
|
||||||
)
|
)
|
||||||
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
/*
|
||||||
|
* 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.config
|
||||||
|
|
||||||
|
import org.springframework.context.annotation.Bean
|
||||||
|
import org.springframework.context.annotation.Configuration
|
||||||
|
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder
|
||||||
|
import org.springframework.security.crypto.password.PasswordEncoder
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
class SecurityConfig {
|
||||||
|
@Bean
|
||||||
|
fun passwordEncoder(): PasswordEncoder {
|
||||||
|
return BCryptPasswordEncoder()
|
||||||
|
}
|
||||||
|
}
|
|
@ -16,5 +16,22 @@
|
||||||
|
|
||||||
package dev.usbharu.hideout.core.domain.model.actor
|
package dev.usbharu.hideout.core.domain.model.actor
|
||||||
|
|
||||||
|
import java.security.PrivateKey
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
@JvmInline
|
@JvmInline
|
||||||
value class ActorPrivateKey(val privateKey: String)
|
value class ActorPrivateKey(val privateKey: String) {
|
||||||
|
companion object {
|
||||||
|
fun create(privateKey: PrivateKey): ActorPrivateKey {
|
||||||
|
return ActorPrivateKey(
|
||||||
|
"-----BEGIN PRIVATE KEY-----\n" +
|
||||||
|
Base64
|
||||||
|
.getEncoder()
|
||||||
|
.encodeToString(privateKey.encoded)
|
||||||
|
.chunked(64)
|
||||||
|
.joinToString("\n") +
|
||||||
|
"\n-----END PRIVATE KEY-----"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -16,5 +16,22 @@
|
||||||
|
|
||||||
package dev.usbharu.hideout.core.domain.model.actor
|
package dev.usbharu.hideout.core.domain.model.actor
|
||||||
|
|
||||||
|
import java.security.PublicKey
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
@JvmInline
|
@JvmInline
|
||||||
value class ActorPublicKey(val publicKey: String)
|
value class ActorPublicKey(val publicKey: String) {
|
||||||
|
companion object {
|
||||||
|
fun create(publicKey: PublicKey): ActorPublicKey {
|
||||||
|
return ActorPublicKey(
|
||||||
|
"-----BEGIN PUBLIC KEY-----\n" +
|
||||||
|
Base64
|
||||||
|
.getEncoder()
|
||||||
|
.encodeToString(publicKey.encoded)
|
||||||
|
.chunked(64)
|
||||||
|
.joinToString("\n") +
|
||||||
|
"\n-----END PUBLIC KEY-----"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -20,4 +20,5 @@ interface ActorRepository {
|
||||||
suspend fun save(actor: Actor): Actor
|
suspend fun save(actor: Actor): Actor
|
||||||
suspend fun delete(actor: Actor)
|
suspend fun delete(actor: Actor)
|
||||||
suspend fun findById(id: ActorId): Actor?
|
suspend fun findById(id: ActorId): Actor?
|
||||||
|
suspend fun findByNameAndDomain(name: String, domain: String): Actor?
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,41 @@
|
||||||
|
/*
|
||||||
|
* 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.domain.service.actor.local
|
||||||
|
|
||||||
|
import dev.usbharu.hideout.core.config.ApplicationConfig
|
||||||
|
import dev.usbharu.hideout.core.domain.model.actor.ActorPrivateKey
|
||||||
|
import dev.usbharu.hideout.core.domain.model.actor.ActorPublicKey
|
||||||
|
import dev.usbharu.hideout.core.domain.model.actor.ActorRepository
|
||||||
|
import org.springframework.stereotype.Service
|
||||||
|
import java.security.KeyPairGenerator
|
||||||
|
|
||||||
|
@Service
|
||||||
|
class LocalActorDomainServiceImpl(
|
||||||
|
private val actorRepository: ActorRepository,
|
||||||
|
private val applicationConfig: ApplicationConfig,
|
||||||
|
) : LocalActorDomainService {
|
||||||
|
override suspend fun usernameAlreadyUse(name: String): Boolean =
|
||||||
|
actorRepository.findByNameAndDomain(name, applicationConfig.url.host) == null
|
||||||
|
|
||||||
|
override suspend fun generateKeyPair(): Pair<ActorPublicKey, ActorPrivateKey> {
|
||||||
|
val keyPairGenerator = KeyPairGenerator.getInstance("RSA")
|
||||||
|
keyPairGenerator.initialize(applicationConfig.keySize)
|
||||||
|
val generateKeyPair = keyPairGenerator.generateKeyPair()
|
||||||
|
|
||||||
|
return ActorPublicKey.create(generateKeyPair.public) to ActorPrivateKey.create(generateKeyPair.private)
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,43 @@
|
||||||
|
/*
|
||||||
|
* 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.domain.service.actor.local
|
||||||
|
|
||||||
|
import dev.usbharu.hideout.core.domain.model.actor.Actor
|
||||||
|
import org.springframework.stereotype.Service
|
||||||
|
|
||||||
|
@Service
|
||||||
|
class LocalActorMigrationCheckDomainServiceImpl : LocalActorMigrationCheckDomainService {
|
||||||
|
override suspend fun canAccountMigration(from: Actor, to: Actor): AccountMigrationCheck {
|
||||||
|
if (to == from) {
|
||||||
|
return AccountMigrationCheck.SelfReferences()
|
||||||
|
}
|
||||||
|
|
||||||
|
if (to.moveTo != null) {
|
||||||
|
return AccountMigrationCheck.AlreadyMoved("${to.name}@${to.domain} was move to ${to.moveTo}")
|
||||||
|
}
|
||||||
|
|
||||||
|
if (from.moveTo != null) {
|
||||||
|
return AccountMigrationCheck.AlreadyMoved("${from.name}@${from.domain} was move to ${from.moveTo}")
|
||||||
|
}
|
||||||
|
|
||||||
|
if (to.alsoKnownAs.contains(to.id).not()) {
|
||||||
|
return AccountMigrationCheck.AlsoKnownAsNotFound("${to.id} has ${to.alsoKnownAs}")
|
||||||
|
}
|
||||||
|
|
||||||
|
return AccountMigrationCheck.CanAccountMigration()
|
||||||
|
}
|
||||||
|
}
|
|
@ -83,7 +83,20 @@ class ExposedActorRepository(
|
||||||
Actors.id eq id.id
|
Actors.id eq id.id
|
||||||
}
|
}
|
||||||
.let(actorQueryMapper::map)
|
.let(actorQueryMapper::map)
|
||||||
.first()
|
.firstOrNull()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun findByNameAndDomain(name: String, domain: String): Actor? {
|
||||||
|
return query {
|
||||||
|
Actors
|
||||||
|
.leftJoin(ActorsAlsoKnownAs, onColumn = { id }, otherColumn = { actorId })
|
||||||
|
.selectAll()
|
||||||
|
.where {
|
||||||
|
Actors.name eq name and (Actors.domain eq domain)
|
||||||
|
}
|
||||||
|
.let(actorQueryMapper::map)
|
||||||
|
.firstOrNull()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,7 @@ import dev.usbharu.hideout.core.domain.model.actor.ActorId
|
||||||
import dev.usbharu.hideout.core.domain.model.post.*
|
import dev.usbharu.hideout.core.domain.model.post.*
|
||||||
import dev.usbharu.hideout.core.domain.shared.domainevent.DomainEventPublisher
|
import dev.usbharu.hideout.core.domain.shared.domainevent.DomainEventPublisher
|
||||||
import dev.usbharu.hideout.core.domain.shared.repository.DomainEventPublishableRepository
|
import dev.usbharu.hideout.core.domain.shared.repository.DomainEventPublishableRepository
|
||||||
|
import dev.usbharu.hideout.core.infrastructure.exposed.QueryMapper
|
||||||
import dev.usbharu.hideout.core.infrastructure.exposedrepository.Posts.actorId
|
import dev.usbharu.hideout.core.infrastructure.exposedrepository.Posts.actorId
|
||||||
import dev.usbharu.hideout.core.infrastructure.exposedrepository.Posts.apId
|
import dev.usbharu.hideout.core.infrastructure.exposedrepository.Posts.apId
|
||||||
import dev.usbharu.hideout.core.infrastructure.exposedrepository.Posts.content
|
import dev.usbharu.hideout.core.infrastructure.exposedrepository.Posts.content
|
||||||
|
@ -44,7 +45,10 @@ import org.slf4j.LoggerFactory
|
||||||
import org.springframework.stereotype.Repository
|
import org.springframework.stereotype.Repository
|
||||||
|
|
||||||
@Repository
|
@Repository
|
||||||
class ExposedPostRepository(override val domainEventPublisher: DomainEventPublisher) :
|
class ExposedPostRepository(
|
||||||
|
private val postQueryMapper: QueryMapper<Post>,
|
||||||
|
override val domainEventPublisher: DomainEventPublisher,
|
||||||
|
) :
|
||||||
PostRepository,
|
PostRepository,
|
||||||
AbstractRepository(),
|
AbstractRepository(),
|
||||||
DomainEventPublishableRepository<Post> {
|
DomainEventPublishableRepository<Post> {
|
||||||
|
@ -144,16 +148,23 @@ class ExposedPostRepository(override val domainEventPublisher: DomainEventPublis
|
||||||
return posts
|
return posts
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun findById(id: PostId): Post? {
|
override suspend fun findById(id: PostId): Post? = query {
|
||||||
query {
|
Posts
|
||||||
Posts.selectAll().where {
|
.selectAll()
|
||||||
|
.where {
|
||||||
Posts.id eq id.id
|
Posts.id eq id.id
|
||||||
}
|
}
|
||||||
}
|
.let(postQueryMapper::map)
|
||||||
|
.first()
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun findByActorId(id: ActorId): List<Post> {
|
override suspend fun findByActorId(id: ActorId): List<Post> = query {
|
||||||
TODO("Not yet implemented")
|
Posts
|
||||||
|
.selectAll()
|
||||||
|
.where {
|
||||||
|
actorId eq id.id
|
||||||
|
}
|
||||||
|
.let(postQueryMapper::map)
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun delete(post: Post) {
|
override suspend fun delete(post: Post) {
|
||||||
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
/*
|
||||||
|
* 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.infrastructure.springframework
|
||||||
|
|
||||||
|
import dev.usbharu.hideout.core.domain.service.userdetail.PasswordEncoder
|
||||||
|
import org.springframework.stereotype.Component
|
||||||
|
|
||||||
|
@Component
|
||||||
|
class SpringSecurityPasswordEncoder(private val passwordEncoder: org.springframework.security.crypto.password.PasswordEncoder) :
|
||||||
|
PasswordEncoder {
|
||||||
|
override suspend fun encode(input: String): String {
|
||||||
|
return passwordEncoder.encode(input)
|
||||||
|
}
|
||||||
|
}
|
|
@ -23,7 +23,7 @@ spring:
|
||||||
default-property-inclusion: always
|
default-property-inclusion: always
|
||||||
datasource:
|
datasource:
|
||||||
driver-class-name: org.postgresql.Driver
|
driver-class-name: org.postgresql.Driver
|
||||||
url: "jdbc:postgresql:hideout2"
|
url: "jdbc:postgresql:hideout3"
|
||||||
username: "postgres"
|
username: "postgres"
|
||||||
password: ""
|
password: ""
|
||||||
data:
|
data:
|
||||||
|
|
|
@ -41,20 +41,20 @@ create table if not exists actors
|
||||||
url varchar(1000) not null unique,
|
url varchar(1000) not null unique,
|
||||||
public_key varchar(10000) not null,
|
public_key varchar(10000) not null,
|
||||||
private_key varchar(10000) null,
|
private_key varchar(10000) null,
|
||||||
created_at bigint not null,
|
created_at timestamp not null,
|
||||||
key_id varchar(1000) not null,
|
key_id varchar(1000) not null,
|
||||||
"following" varchar(1000) null,
|
"following" varchar(1000) null,
|
||||||
followers varchar(1000) null,
|
followers varchar(1000) null,
|
||||||
"instance" bigint not null,
|
"instance" bigint not null,
|
||||||
locked boolean not null,
|
locked boolean not null,
|
||||||
following_count int not null,
|
following_count int null,
|
||||||
followers_count int not null,
|
followers_count int null,
|
||||||
posts_count int not null,
|
posts_count int not null,
|
||||||
last_post_at timestamp null default null,
|
last_post_at timestamp null default null,
|
||||||
last_update_at timestamp not null,
|
last_update_at timestamp not null,
|
||||||
suspend boolean not null,
|
suspend boolean not null,
|
||||||
move_to bigint null default null,
|
move_to bigint null default null,
|
||||||
emojis varchar(3000) not null default '',
|
emojis varchar(3000) not null default '',
|
||||||
unique ("name", "domain"),
|
unique ("name", "domain"),
|
||||||
constraint fk_actors_instance__id foreign key ("instance") references instance (id) on delete restrict on update restrict,
|
constraint fk_actors_instance__id foreign key ("instance") references instance (id) on delete restrict on update restrict,
|
||||||
constraint fk_actors_actors__move_to foreign key ("move_to") references actors (id) on delete restrict on update restrict
|
constraint fk_actors_actors__move_to foreign key ("move_to") references actors (id) on delete restrict on update restrict
|
||||||
|
@ -250,8 +250,9 @@ values (0, 'system', '', '', '', null, '', '', false, false, '', current_timesta
|
||||||
|
|
||||||
insert into actors (id, name, domain, screen_name, description, inbox, outbox, url, public_key, private_key, created_at,
|
insert into actors (id, name, domain, screen_name, description, inbox, outbox, url, public_key, private_key, created_at,
|
||||||
key_id, following, followers, instance, locked, following_count, followers_count, posts_count,
|
key_id, following, followers, instance, locked, following_count, followers_count, posts_count,
|
||||||
last_post_at)
|
last_post_at, last_update_at, suspend, move_to, emojis)
|
||||||
values (0, 'ghost', '', '', '', '', '', '', '', null, 0, '', '', '', 0, true, 0, 0, 0, null);
|
values (0, '', '', '', '', '', '', '', '', null, current_timestamp, '', null, null, 0, true, null, null, 0, null,
|
||||||
|
current_timestamp, false, null, '');
|
||||||
|
|
||||||
create table if not exists deleted_actors
|
create table if not exists deleted_actors
|
||||||
(
|
(
|
||||||
|
|
|
@ -82,6 +82,7 @@ imageio-webp = { module = "com.twelvemonkeys.imageio:imageio-webp", version = "3
|
||||||
thumbnailator = { module = "net.coobird:thumbnailator", version = "0.4.20" }
|
thumbnailator = { module = "net.coobird:thumbnailator", version = "0.4.20" }
|
||||||
|
|
||||||
flyway-core = { module = "org.flywaydb:flyway-core" }
|
flyway-core = { module = "org.flywaydb:flyway-core" }
|
||||||
|
flyway-postgresql = { module = "org.flywaydb:flyway-database-postgresql", version = "10.14.0" }
|
||||||
|
|
||||||
h2db = { module = "com.h2database:h2", version = "2.2.224" }
|
h2db = { module = "com.h2database:h2", version = "2.2.224" }
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue