From 69699b4538e06578a7ccd94971db3692f50f78c0 Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Tue, 21 Nov 2023 15:47:38 +0900 Subject: [PATCH 1/7] =?UTF-8?q?fix:=20=E3=83=AA=E3=83=A2=E3=83=BC=E3=83=88?= =?UTF-8?q?=E3=83=A6=E3=83=BC=E3=82=B6=E3=83=BC=E3=82=92=E5=8F=96=E5=BE=97?= =?UTF-8?q?=E6=99=82=E3=81=AB=E4=BD=BF=E7=94=A8=E3=81=97=E3=81=9FURL?= =?UTF-8?q?=E3=81=A7url=E3=81=8C=E7=99=BB=E9=8C=B2=E3=81=95=E3=82=8C?= =?UTF-8?q?=E3=81=A6=E3=81=97=E3=81=BE=E3=81=86=E5=95=8F=E9=A1=8C=E3=82=92?= =?UTF-8?q?=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/objects/user/APUserService.kt | 20 ++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/objects/user/APUserService.kt b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/objects/user/APUserService.kt index 9c0777e9..03de36a3 100644 --- a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/objects/user/APUserService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/objects/user/APUserService.kt @@ -80,26 +80,27 @@ class APUserServiceImpl( override suspend fun fetchPersonWithEntity(url: String, targetActor: String?): Pair { return try { val userEntity = userQueryService.findByUrl(url) + val id = userEntity.url return Person( type = emptyList(), name = userEntity.name, - id = url, + id = id, preferredUsername = userEntity.name, summary = userEntity.description, - inbox = "$url/inbox", - outbox = "$url/outbox", - url = url, + inbox = "$id/inbox", + outbox = "$id/outbox", + url = id, icon = Image( type = emptyList(), - name = "$url/icon.png", + name = "$id/icon.png", mediaType = "image/png", - url = "$url/icon.png" + url = "$id/icon.png" ), publicKey = Key( type = emptyList(), name = "Public Key", id = userEntity.keyId, - owner = url, + owner = id, publicKeyPem = userEntity.publicKey ), endpoints = mapOf("sharedInbox" to "${applicationConfig.url}/inbox"), @@ -109,17 +110,18 @@ class APUserServiceImpl( } catch (ignore: FailedToGetResourcesException) { val person = apResourceResolveService.resolve(url, null as Long?) + val id = person.id ?: throw IllegalActivityPubObjectException("id is null") person to userService.createRemoteUser( RemoteUserCreateDto( name = person.preferredUsername ?: throw IllegalActivityPubObjectException("preferredUsername is null"), - domain = url.substringAfter("://").substringBefore("/"), + domain = id.substringAfter("://").substringBefore("/"), screenName = (person.name ?: person.preferredUsername) ?: throw IllegalActivityPubObjectException("preferredUsername is null"), description = person.summary.orEmpty(), inbox = person.inbox ?: throw IllegalActivityPubObjectException("inbox is null"), outbox = person.outbox ?: throw IllegalActivityPubObjectException("outbox is null"), - url = url, + url = id, publicKey = person.publicKey?.publicKeyPem ?: throw IllegalActivityPubObjectException("publicKey is null"), keyId = person.publicKey?.id ?: throw IllegalActivityPubObjectException("publicKey keyId is null"), From fd64b234ad84193868865e5a989a8657da5325be Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Tue, 21 Nov 2023 16:24:46 +0900 Subject: [PATCH 2/7] =?UTF-8?q?feat:=20PostgreSQL=E3=81=A7=E4=BD=BF?= =?UTF-8?q?=E7=94=A8=E3=81=A7=E3=81=8D=E3=82=8B=E3=82=88=E3=81=86=E3=81=AB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../resources/db/migration/V1__Init_DB.sql | 324 +++++++++--------- 1 file changed, 162 insertions(+), 162 deletions(-) diff --git a/src/main/resources/db/migration/V1__Init_DB.sql b/src/main/resources/db/migration/V1__Init_DB.sql index 34da6594..15a61994 100644 --- a/src/main/resources/db/migration/V1__Init_DB.sql +++ b/src/main/resources/db/migration/V1__Init_DB.sql @@ -1,188 +1,188 @@ -CREATE TABLE IF NOT EXISTS "INSTANCE" +create table if not exists instance ( - ID BIGINT PRIMARY KEY, - "NAME" VARCHAR(1000) NOT NULL, - DESCRIPTION VARCHAR(5000) NOT NULL, - URL VARCHAR(255) NOT NULL, - ICON_URL VARCHAR(255) NOT NULL, - SHARED_INBOX VARCHAR(255) NULL, - SOFTWARE VARCHAR(255) NOT NULL, - VERSION VARCHAR(255) NOT NULL, - IS_BLOCKED BOOLEAN NOT NULL, - IS_MUTED BOOLEAN NOT NULL, - MODERATION_NOTE VARCHAR(10000) NOT NULL, - CREATED_AT TIMESTAMP NOT NULL + id bigint primary key, + "name" varchar(1000) not null, + description varchar(5000) not null, + url varchar(255) not null, + icon_url varchar(255) not null, + shared_inbox varchar(255) null, + software varchar(255) not null, + version varchar(255) not null, + is_blocked boolean not null, + is_muted boolean not null, + moderation_note varchar(10000) not null, + created_at timestamp not null ); -CREATE TABLE IF NOT EXISTS USERS +create table if not exists users ( - ID BIGINT PRIMARY KEY, - "NAME" VARCHAR(300) NOT NULL, - "DOMAIN" VARCHAR(1000) NOT NULL, - SCREEN_NAME VARCHAR(300) NOT NULL, - DESCRIPTION VARCHAR(10000) NOT NULL, - PASSWORD VARCHAR(255) NULL, - INBOX VARCHAR(1000) NOT NULL, - OUTBOX VARCHAR(1000) NOT NULL, - URL VARCHAR(1000) NOT NULL, - PUBLIC_KEY VARCHAR(10000) NOT NULL, - PRIVATE_KEY VARCHAR(10000) NULL, - CREATED_AT BIGINT NOT NULL, - KEY_ID VARCHAR(1000) NOT NULL, - "FOLLOWING" VARCHAR(1000) NULL, - FOLLOWERS VARCHAR(1000) NULL, - "INSTANCE" BIGINT NULL, - CONSTRAINT FK_USERS_INSTANCE__ID FOREIGN KEY ("INSTANCE") REFERENCES "INSTANCE" (ID) ON DELETE RESTRICT ON UPDATE RESTRICT + id bigint primary key, + "name" varchar(300) not null, + "domain" varchar(1000) not null, + screen_name varchar(300) not null, + description varchar(10000) not null, + password varchar(255) null, + inbox varchar(1000) not null, + outbox varchar(1000) not null, + url varchar(1000) not null, + public_key varchar(10000) not null, + private_key varchar(10000) null, + created_at bigint not null, + key_id varchar(1000) not null, + "following" varchar(1000) null, + followers varchar(1000) null, + "instance" bigint null, + constraint fk_users_instance__id foreign key ("instance") references instance (id) on delete restrict on update restrict ); -CREATE TABLE IF NOT EXISTS FOLLOW_REQUESTS +create table if not exists follow_requests ( - ID BIGSERIAL PRIMARY KEY, - USER_ID BIGINT NOT NULL, - FOLLOWER_ID BIGINT NOT NULL, - CONSTRAINT FK_FOLLOW_REQUESTS_USER_ID__ID FOREIGN KEY (USER_ID) REFERENCES USERS (ID) ON DELETE RESTRICT ON UPDATE RESTRICT, - CONSTRAINT FK_FOLLOW_REQUESTS_FOLLOWER_ID__ID FOREIGN KEY (FOLLOWER_ID) REFERENCES USERS (ID) ON DELETE RESTRICT ON UPDATE RESTRICT + id bigserial primary key, + user_id bigint not null, + follower_id bigint not null, + constraint fk_follow_requests_user_id__id foreign key (user_id) references users (id) on delete restrict on update restrict, + constraint fk_follow_requests_follower_id__id foreign key (follower_id) references users (id) on delete restrict on update restrict ); -CREATE TABLE IF NOT EXISTS MEDIA +create table if not exists media ( - ID BIGINT PRIMARY KEY, - "NAME" VARCHAR(255) NOT NULL, - URL VARCHAR(255) NOT NULL, - REMOTE_URL VARCHAR(255) NULL, - THUMBNAIL_URL VARCHAR(255) NULL, - "TYPE" INT NOT NULL, - BLURHASH VARCHAR(255) NULL, - MIME_TYPE VARCHAR(255) NOT NULL, - DESCRIPTION VARCHAR(4000) NULL + id bigint primary key, + "name" varchar(255) not null, + url varchar(255) not null, + remote_url varchar(255) null, + thumbnail_url varchar(255) null, + "type" int not null, + blurhash varchar(255) null, + mime_type varchar(255) not null, + description varchar(4000) null ); -CREATE TABLE IF NOT EXISTS META_INFO +create table if not exists meta_info ( - ID BIGINT PRIMARY KEY, - VERSION VARCHAR(1000) NOT NULL, - KID VARCHAR(1000) NOT NULL, - JWT_PRIVATE_KEY VARCHAR(100000) NOT NULL, - JWT_PUBLIC_KEY VARCHAR(100000) NOT NULL + id bigint primary key, + version varchar(1000) not null, + kid varchar(1000) not null, + jwt_private_key varchar(100000) not null, + jwt_public_key varchar(100000) not null ); -CREATE TABLE IF NOT EXISTS POSTS +create table if not exists posts ( - ID BIGINT PRIMARY KEY, - USER_ID BIGINT NOT NULL, - OVERVIEW VARCHAR(100) NULL, - TEXT VARCHAR(3000) NOT NULL, - CREATED_AT BIGINT NOT NULL, - VISIBILITY INT DEFAULT 0 NOT NULL, - URL VARCHAR(500) NOT NULL, - REPOST_ID BIGINT NULL, - REPLY_ID BIGINT NULL, - "SENSITIVE" BOOLEAN DEFAULT FALSE NOT NULL, - AP_ID VARCHAR(100) NOT NULL + id bigint primary key, + user_id bigint not null, + overview varchar(100) null, + text varchar(3000) not null, + created_at bigint not null, + visibility int default 0 not null, + url varchar(500) not null, + repost_id bigint null, + reply_id bigint null, + "sensitive" boolean default false not null, + ap_id varchar(100) not null ); -ALTER TABLE POSTS - ADD CONSTRAINT FK_POSTS_USERID__ID FOREIGN KEY (USER_ID) REFERENCES USERS (ID) ON DELETE RESTRICT ON UPDATE RESTRICT; -ALTER TABLE POSTS - ADD CONSTRAINT FK_POSTS_REPOSTID__ID FOREIGN KEY (REPOST_ID) REFERENCES POSTS (ID) ON DELETE RESTRICT ON UPDATE RESTRICT; -ALTER TABLE POSTS - ADD CONSTRAINT FK_POSTS_REPLYID__ID FOREIGN KEY (REPLY_ID) REFERENCES POSTS (ID) ON DELETE RESTRICT ON UPDATE RESTRICT; -CREATE TABLE IF NOT EXISTS POSTS_MEDIA +alter table posts + add constraint fk_posts_userid__id foreign key (user_id) references users (id) on delete restrict on update restrict; +alter table posts + add constraint fk_posts_repostid__id foreign key (repost_id) references posts (id) on delete restrict on update restrict; +alter table posts + add constraint fk_posts_replyid__id foreign key (reply_id) references posts (id) on delete restrict on update restrict; +create table if not exists posts_media ( - POST_ID BIGINT, - MEDIA_ID BIGINT, - CONSTRAINT pk_PostsMedia PRIMARY KEY (POST_ID, MEDIA_ID) + post_id bigint, + media_id bigint, + constraint pk_postsmedia primary key (post_id, media_id) ); -ALTER TABLE POSTS_MEDIA - ADD CONSTRAINT FK_POSTS_MEDIA_POST_ID__ID FOREIGN KEY (POST_ID) REFERENCES POSTS (ID) ON DELETE CASCADE ON UPDATE CASCADE; -ALTER TABLE POSTS_MEDIA - ADD CONSTRAINT FK_POSTS_MEDIA_MEDIA_ID__ID FOREIGN KEY (MEDIA_ID) REFERENCES MEDIA (ID) ON DELETE CASCADE ON UPDATE CASCADE; -CREATE TABLE IF NOT EXISTS REACTIONS +alter table posts_media + add constraint fk_posts_media_post_id__id foreign key (post_id) references posts (id) on delete cascade on update cascade; +alter table posts_media + add constraint fk_posts_media_media_id__id foreign key (media_id) references media (id) on delete cascade on update cascade; +create table if not exists reactions ( - ID BIGSERIAL PRIMARY KEY, - EMOJI_ID BIGINT NOT NULL, - POST_ID BIGINT NOT NULL, - USER_ID BIGINT NOT NULL + id bigserial primary key, + emoji_id bigint not null, + post_id bigint not null, + user_id bigint not null ); -ALTER TABLE REACTIONS - ADD CONSTRAINT FK_REACTIONS_POST_ID__ID FOREIGN KEY (POST_ID) REFERENCES POSTS (ID) ON DELETE RESTRICT ON UPDATE RESTRICT; -ALTER TABLE REACTIONS - ADD CONSTRAINT FK_REACTIONS_USER_ID__ID FOREIGN KEY (USER_ID) REFERENCES USERS (ID) ON DELETE RESTRICT ON UPDATE RESTRICT; -CREATE TABLE IF NOT EXISTS TIMELINES +alter table reactions + add constraint fk_reactions_post_id__id foreign key (post_id) references posts (id) on delete restrict on update restrict; +alter table reactions + add constraint fk_reactions_user_id__id foreign key (user_id) references users (id) on delete restrict on update restrict; +create table if not exists timelines ( - ID BIGINT PRIMARY KEY, - USER_ID BIGINT NOT NULL, - TIMELINE_ID BIGINT NOT NULL, - POST_ID BIGINT NOT NULL, - POST_USER_ID BIGINT NOT NULL, - CREATED_AT BIGINT NOT NULL, - REPLY_ID BIGINT NULL, - REPOST_ID BIGINT NULL, - VISIBILITY INT NOT NULL, - "SENSITIVE" BOOLEAN NOT NULL, - IS_LOCAL BOOLEAN NOT NULL, - IS_PURE_REPOST BOOLEAN NOT NULL, - MEDIA_IDS VARCHAR(255) NOT NULL + id bigint primary key, + user_id bigint not null, + timeline_id bigint not null, + post_id bigint not null, + post_user_id bigint not null, + created_at bigint not null, + reply_id bigint null, + repost_id bigint null, + visibility int not null, + "sensitive" boolean not null, + is_local boolean not null, + is_pure_repost boolean not null, + media_ids varchar(255) not null ); -CREATE TABLE IF NOT EXISTS USERS_FOLLOWERS +create table if not exists users_followers ( - ID BIGSERIAL PRIMARY KEY, - USER_ID BIGINT NOT NULL, - FOLLOWER_ID BIGINT NOT NULL, - CONSTRAINT FK_USERS_FOLLOWERS_USER_ID__ID FOREIGN KEY (USER_ID) REFERENCES USERS (ID) ON DELETE RESTRICT ON UPDATE RESTRICT, - CONSTRAINT FK_USERS_FOLLOWERS_FOLLOWER_ID__ID FOREIGN KEY (FOLLOWER_ID) REFERENCES USERS (ID) ON DELETE RESTRICT ON UPDATE RESTRICT + id bigserial primary key, + user_id bigint not null, + follower_id bigint not null, + constraint fk_users_followers_user_id__id foreign key (user_id) references users (id) on delete restrict on update restrict, + constraint fk_users_followers_follower_id__id foreign key (follower_id) references users (id) on delete restrict on update restrict ); -CREATE TABLE IF NOT EXISTS APPLICATION_AUTHORIZATION +create table if not exists application_authorization ( - ID VARCHAR(255) PRIMARY KEY, - REGISTERED_CLIENT_ID VARCHAR(255) NOT NULL, - PRINCIPAL_NAME VARCHAR(255) NOT NULL, - AUTHORIZATION_GRANT_TYPE VARCHAR(255) NOT NULL, - AUTHORIZED_SCOPES VARCHAR(1000) DEFAULT NULL NULL, - "ATTRIBUTES" VARCHAR(4000) DEFAULT NULL NULL, - "STATE" VARCHAR(500) DEFAULT NULL NULL, - AUTHORIZATION_CODE_VALUE VARCHAR(4000) DEFAULT NULL NULL, - AUTHORIZATION_CODE_ISSUED_AT TIMESTAMP DEFAULT NULL NULL, - AUTHORIZATION_CODE_EXPIRES_AT TIMESTAMP DEFAULT NULL NULL, - AUTHORIZATION_CODE_METADATA VARCHAR(2000) DEFAULT NULL NULL, - ACCESS_TOKEN_VALUE VARCHAR(4000) DEFAULT NULL NULL, - ACCESS_TOKEN_ISSUED_AT TIMESTAMP DEFAULT NULL NULL, - ACCESS_TOKEN_EXPIRES_AT TIMESTAMP DEFAULT NULL NULL, - ACCESS_TOKEN_METADATA VARCHAR(2000) DEFAULT NULL NULL, - ACCESS_TOKEN_TYPE VARCHAR(255) DEFAULT NULL NULL, - ACCESS_TOKEN_SCOPES VARCHAR(1000) DEFAULT NULL NULL, - REFRESH_TOKEN_VALUE VARCHAR(4000) DEFAULT NULL NULL, - REFRESH_TOKEN_ISSUED_AT TIMESTAMP DEFAULT NULL NULL, - REFRESH_TOKEN_EXPIRES_AT TIMESTAMP DEFAULT NULL NULL, - REFRESH_TOKEN_METADATA VARCHAR(2000) DEFAULT NULL NULL, - OIDC_ID_TOKEN_VALUE VARCHAR(4000) DEFAULT NULL NULL, - OIDC_ID_TOKEN_ISSUED_AT TIMESTAMP DEFAULT NULL NULL, - OIDC_ID_TOKEN_EXPIRES_AT TIMESTAMP DEFAULT NULL NULL, - OIDC_ID_TOKEN_METADATA VARCHAR(2000) DEFAULT NULL NULL, - OIDC_ID_TOKEN_CLAIMS VARCHAR(2000) DEFAULT NULL NULL, - USER_CODE_VALUE VARCHAR(4000) DEFAULT NULL NULL, - USER_CODE_ISSUED_AT TIMESTAMP DEFAULT NULL NULL, - USER_CODE_EXPIRES_AT TIMESTAMP DEFAULT NULL NULL, - USER_CODE_METADATA VARCHAR(2000) DEFAULT NULL NULL, - DEVICE_CODE_VALUE VARCHAR(4000) DEFAULT NULL NULL, - DEVICE_CODE_ISSUED_AT TIMESTAMP DEFAULT NULL NULL, - DEVICE_CODE_EXPIRES_AT TIMESTAMP DEFAULT NULL NULL, - DEVICE_CODE_METADATA VARCHAR(2000) DEFAULT NULL NULL + id varchar(255) primary key, + registered_client_id varchar(255) not null, + principal_name varchar(255) not null, + authorization_grant_type varchar(255) not null, + authorized_scopes varchar(1000) default null null, + "attributes" varchar(4000) default null null, + "state" varchar(500) default null null, + authorization_code_value varchar(4000) default null null, + authorization_code_issued_at timestamp default null null, + authorization_code_expires_at timestamp default null null, + authorization_code_metadata varchar(2000) default null null, + access_token_value varchar(4000) default null null, + access_token_issued_at timestamp default null null, + access_token_expires_at timestamp default null null, + access_token_metadata varchar(2000) default null null, + access_token_type varchar(255) default null null, + access_token_scopes varchar(1000) default null null, + refresh_token_value varchar(4000) default null null, + refresh_token_issued_at timestamp default null null, + refresh_token_expires_at timestamp default null null, + refresh_token_metadata varchar(2000) default null null, + oidc_id_token_value varchar(4000) default null null, + oidc_id_token_issued_at timestamp default null null, + oidc_id_token_expires_at timestamp default null null, + oidc_id_token_metadata varchar(2000) default null null, + oidc_id_token_claims varchar(2000) default null null, + user_code_value varchar(4000) default null null, + user_code_issued_at timestamp default null null, + user_code_expires_at timestamp default null null, + user_code_metadata varchar(2000) default null null, + device_code_value varchar(4000) default null null, + device_code_issued_at timestamp default null null, + device_code_expires_at timestamp default null null, + device_code_metadata varchar(2000) default null null ); -CREATE TABLE IF NOT EXISTS OAUTH2_AUTHORIZATION_CONSENT +create table if not exists oauth2_authorization_consent ( - REGISTERED_CLIENT_ID VARCHAR(100), - PRINCIPAL_NAME VARCHAR(200), - AUTHORITIES VARCHAR(1000) NOT NULL, - CONSTRAINT pk_oauth2_authorization_consent PRIMARY KEY (REGISTERED_CLIENT_ID, PRINCIPAL_NAME) + registered_client_id varchar(100), + principal_name varchar(200), + authorities varchar(1000) not null, + constraint pk_oauth2_authorization_consent primary key (registered_client_id, principal_name) ); -CREATE TABLE IF NOT EXISTS REGISTERED_CLIENT +create table if not exists registered_client ( - ID VARCHAR(100) PRIMARY KEY, - CLIENT_ID VARCHAR(100) NOT NULL, - CLIENT_ID_ISSUED_AT TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL, - CLIENT_SECRET VARCHAR(200) DEFAULT NULL NULL, - CLIENT_SECRET_EXPIRES_AT TIMESTAMP DEFAULT NULL NULL, - CLIENT_NAME VARCHAR(200) NOT NULL, - CLIENT_AUTHENTICATION_METHODS VARCHAR(1000) NOT NULL, - AUTHORIZATION_GRANT_TYPES VARCHAR(1000) NOT NULL, - REDIRECT_URIS VARCHAR(1000) DEFAULT NULL NULL, - POST_LOGOUT_REDIRECT_URIS VARCHAR(1000) DEFAULT NULL NULL, - SCOPES VARCHAR(1000) NOT NULL, - CLIENT_SETTINGS VARCHAR(2000) NOT NULL, - TOKEN_SETTINGS VARCHAR(2000) NOT NULL + id varchar(100) primary key, + client_id varchar(100) not null, + client_id_issued_at timestamp default current_timestamp not null, + client_secret varchar(200) default null null, + client_secret_expires_at timestamp default null null, + client_name varchar(200) not null, + client_authentication_methods varchar(1000) not null, + authorization_grant_types varchar(1000) not null, + redirect_uris varchar(1000) default null null, + post_logout_redirect_uris varchar(1000) default null null, + scopes varchar(1000) not null, + client_settings varchar(2000) not null, + token_settings varchar(2000) not null ) From 740c88e9a3a7f310f4af13189a8014cdd50b8485 Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Tue, 21 Nov 2023 16:25:08 +0900 Subject: [PATCH 3/7] =?UTF-8?q?feat:=20PostgreSQL=E3=81=A7=E4=BD=BF?= =?UTF-8?q?=E7=94=A8=E3=81=A7=E3=81=8D=E3=82=8B=E3=82=88=E3=81=86=E3=81=AB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/resources/application.yml | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 2d0a6c82..c9c2604f 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -18,9 +18,11 @@ spring: WRITE_DATES_AS_TIMESTAMPS: false default-property-inclusion: always datasource: - driver-class-name: org.h2.Driver - url: "jdbc:h2:./test-dev4;MODE=POSTGRESQL;TRACE_LEVEL_FILE=4" - username: "" + hikari: + transaction-isolation: "TRANSACTION_SERIALIZABLE" + driver-class-name: org.postgresql.Driver + url: "jdbc:postgresql:hideout2" + username: "postgres" password: "" # data: # mongodb: From 0cbe609dc2c3227726a24f44998ead02b6737596 Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Tue, 21 Nov 2023 16:25:31 +0900 Subject: [PATCH 4/7] =?UTF-8?q?fix:=20instance=E3=81=AE=E4=B8=80=E6=84=8F?= =?UTF-8?q?=E6=80=A7=E3=82=92=E4=BF=9D=E8=A8=BC=E3=81=A7=E3=81=8D=E3=82=8B?= =?UTF-8?q?=E3=82=88=E3=81=86=E3=81=AB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../hideout/application/config/SecurityConfig.kt | 9 +++++++-- .../exposedquery/InstanceQueryServiceImpl.kt | 2 +- .../exposedrepository/InstanceRepositoryImpl.kt | 4 ++-- .../httpsignature/HttpSignatureFilter.kt | 14 +++++++++++++- .../core/service/instance/InstanceService.kt | 2 +- 5 files changed, 24 insertions(+), 7 deletions(-) diff --git a/src/main/kotlin/dev/usbharu/hideout/application/config/SecurityConfig.kt b/src/main/kotlin/dev/usbharu/hideout/application/config/SecurityConfig.kt index a5762bb1..30b505c2 100644 --- a/src/main/kotlin/dev/usbharu/hideout/application/config/SecurityConfig.kt +++ b/src/main/kotlin/dev/usbharu/hideout/application/config/SecurityConfig.kt @@ -6,6 +6,7 @@ import com.nimbusds.jose.jwk.RSAKey import com.nimbusds.jose.jwk.source.ImmutableJWKSet import com.nimbusds.jose.jwk.source.JWKSource import com.nimbusds.jose.proc.SecurityContext +import dev.usbharu.hideout.activitypub.service.objects.user.APUserService import dev.usbharu.hideout.application.external.Transaction import dev.usbharu.hideout.core.infrastructure.springframework.httpsignature.HttpSignatureFilter import dev.usbharu.hideout.core.infrastructure.springframework.httpsignature.HttpSignatureUserDetailsService @@ -113,8 +114,12 @@ class SecurityConfig { } @Bean - fun getHttpSignatureFilter(authenticationManager: AuthenticationManager): HttpSignatureFilter { - val httpSignatureFilter = HttpSignatureFilter(DefaultSignatureHeaderParser()) + fun getHttpSignatureFilter( + authenticationManager: AuthenticationManager, + transaction: Transaction, + apUserService: APUserService + ): HttpSignatureFilter { + val httpSignatureFilter = HttpSignatureFilter(DefaultSignatureHeaderParser(), transaction, apUserService) httpSignatureFilter.setAuthenticationManager(authenticationManager) httpSignatureFilter.setContinueFilterChainOnUnsuccessfulAuthentication(false) val authenticationEntryPointFailureHandler = diff --git a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedquery/InstanceQueryServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedquery/InstanceQueryServiceImpl.kt index 587f57a1..c7d276ef 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedquery/InstanceQueryServiceImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedquery/InstanceQueryServiceImpl.kt @@ -12,5 +12,5 @@ import dev.usbharu.hideout.core.domain.model.instance.Instance as InstanceEntity @Repository class InstanceQueryServiceImpl : InstanceQueryService { override suspend fun findByUrl(url: String): InstanceEntity = Instance.select { Instance.url eq url } - .singleOr { FailedToGetResourcesException("url is doesn't exist") }.toInstance() + .singleOr { FailedToGetResourcesException("$url is doesn't exist", it) }.toInstance() } diff --git a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/InstanceRepositoryImpl.kt b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/InstanceRepositoryImpl.kt index edd79195..a7d8aa9b 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/InstanceRepositoryImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/InstanceRepositoryImpl.kt @@ -79,9 +79,9 @@ object Instance : Table("instance") { val id = long("id") val name = varchar("name", 1000) val description = varchar("description", 5000) - val url = varchar("url", 255) + val url = varchar("url", 255).uniqueIndex() val iconUrl = varchar("icon_url", 255) - val sharedInbox = varchar("shared_inbox", 255).nullable() + val sharedInbox = varchar("shared_inbox", 255).nullable().uniqueIndex() val software = varchar("software", 255) val version = varchar("version", 255) val isBlocked = bool("is_blocked") diff --git a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/springframework/httpsignature/HttpSignatureFilter.kt b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/springframework/httpsignature/HttpSignatureFilter.kt index 8b3c1b11..8d03463c 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/springframework/httpsignature/HttpSignatureFilter.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/springframework/httpsignature/HttpSignatureFilter.kt @@ -1,14 +1,21 @@ package dev.usbharu.hideout.core.infrastructure.springframework.httpsignature +import dev.usbharu.hideout.activitypub.service.objects.user.APUserService +import dev.usbharu.hideout.application.external.Transaction import dev.usbharu.httpsignature.common.HttpHeaders import dev.usbharu.httpsignature.common.HttpMethod import dev.usbharu.httpsignature.common.HttpRequest import dev.usbharu.httpsignature.verify.SignatureHeaderParser import jakarta.servlet.http.HttpServletRequest +import kotlinx.coroutines.runBlocking import org.springframework.security.web.authentication.preauth.AbstractPreAuthenticatedProcessingFilter import java.net.URL -class HttpSignatureFilter(private val httpSignatureHeaderParser: SignatureHeaderParser) : +class HttpSignatureFilter( + private val httpSignatureHeaderParser: SignatureHeaderParser, + private val transaction: Transaction, + private val apUserService: APUserService +) : AbstractPreAuthenticatedProcessingFilter() { override fun getPreAuthenticatedPrincipal(request: HttpServletRequest?): Any? { val headersList = request?.headerNames?.toList().orEmpty() @@ -23,6 +30,11 @@ class HttpSignatureFilter(private val httpSignatureHeaderParser: SignatureHeader } catch (_: RuntimeException) { return "" } + runBlocking { + transaction.transaction { + apUserService.fetchPerson(signature.keyId) + } + } return signature.keyId } diff --git a/src/main/kotlin/dev/usbharu/hideout/core/service/instance/InstanceService.kt b/src/main/kotlin/dev/usbharu/hideout/core/service/instance/InstanceService.kt index 4b0e2640..41459964 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/service/instance/InstanceService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/service/instance/InstanceService.kt @@ -31,7 +31,7 @@ class InstanceServiceImpl( val resolveInstanceUrl = u.protocol + "://" + u.host try { - return instanceQueryService.findByUrl(url) + return instanceQueryService.findByUrl(resolveInstanceUrl) } catch (e: FailedToGetResourcesException) { logger.info("Instance not found. try fetch instance info. url: {}", resolveInstanceUrl) logger.debug("Failed to get resources. url: {}", resolveInstanceUrl, e) From 71a9309c7054978a8cb001294cb89e4db43c379b Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Tue, 21 Nov 2023 16:40:57 +0900 Subject: [PATCH 5/7] =?UTF-8?q?fix:=20user=E3=81=AE=E4=B8=80=E6=84=8F?= =?UTF-8?q?=E6=80=A7=E3=82=92=E4=BF=9D=E8=A8=BC=E3=81=A7=E3=81=8D=E3=82=8B?= =?UTF-8?q?=E3=82=88=E3=81=86=E3=81=AB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/objects/user/APUserService.kt | 30 +++++++++++++++++++ .../application/config/SecurityConfig.kt | 6 ++-- .../exposedrepository/UserRepositoryImpl.kt | 2 +- .../httpsignature/HttpSignatureFilter.kt | 11 +++++-- 4 files changed, 44 insertions(+), 5 deletions(-) diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/objects/user/APUserService.kt b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/objects/user/APUserService.kt index 03de36a3..9e8cb4b8 100644 --- a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/objects/user/APUserService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/objects/user/APUserService.kt @@ -111,6 +111,36 @@ class APUserServiceImpl( val person = apResourceResolveService.resolve(url, null as Long?) val id = person.id ?: throw IllegalActivityPubObjectException("id is null") + try { + val userEntity = userQueryService.findByUrl(id) + return Person( + type = emptyList(), + name = userEntity.name, + id = id, + preferredUsername = userEntity.name, + summary = userEntity.description, + inbox = "$id/inbox", + outbox = "$id/outbox", + url = id, + icon = Image( + type = emptyList(), + name = "$id/icon.png", + mediaType = "image/png", + url = "$id/icon.png" + ), + publicKey = Key( + type = emptyList(), + name = "Public Key", + id = userEntity.keyId, + owner = id, + publicKeyPem = userEntity.publicKey + ), + endpoints = mapOf("sharedInbox" to "${applicationConfig.url}/inbox"), + followers = userEntity.followers, + following = userEntity.following + ) to userEntity + } catch (_: FailedToGetResourcesException) { + } person to userService.createRemoteUser( RemoteUserCreateDto( name = person.preferredUsername diff --git a/src/main/kotlin/dev/usbharu/hideout/application/config/SecurityConfig.kt b/src/main/kotlin/dev/usbharu/hideout/application/config/SecurityConfig.kt index 30b505c2..ecdc3ac9 100644 --- a/src/main/kotlin/dev/usbharu/hideout/application/config/SecurityConfig.kt +++ b/src/main/kotlin/dev/usbharu/hideout/application/config/SecurityConfig.kt @@ -117,9 +117,11 @@ class SecurityConfig { fun getHttpSignatureFilter( authenticationManager: AuthenticationManager, transaction: Transaction, - apUserService: APUserService + apUserService: APUserService, + userQueryService: UserQueryService ): HttpSignatureFilter { - val httpSignatureFilter = HttpSignatureFilter(DefaultSignatureHeaderParser(), transaction, apUserService) + val httpSignatureFilter = + HttpSignatureFilter(DefaultSignatureHeaderParser(), transaction, apUserService, userQueryService) httpSignatureFilter.setAuthenticationManager(authenticationManager) httpSignatureFilter.setContinueFilterChainOnUnsuccessfulAuthentication(false) val authenticationEntryPointFailureHandler = diff --git a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/UserRepositoryImpl.kt b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/UserRepositoryImpl.kt index 5cd94ccf..ecd910a6 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/UserRepositoryImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/UserRepositoryImpl.kt @@ -17,7 +17,7 @@ class UserRepositoryImpl( UserRepository { override suspend fun save(user: User): User { - val singleOrNull = Users.select { Users.id eq user.id or (Users.url eq user.url) }.empty() + val singleOrNull = Users.select { Users.id eq user.id }.empty() if (singleOrNull) { Users.insert { it[id] = user.id diff --git a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/springframework/httpsignature/HttpSignatureFilter.kt b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/springframework/httpsignature/HttpSignatureFilter.kt index 8d03463c..6a68e267 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/springframework/httpsignature/HttpSignatureFilter.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/springframework/httpsignature/HttpSignatureFilter.kt @@ -2,6 +2,8 @@ package dev.usbharu.hideout.core.infrastructure.springframework.httpsignature import dev.usbharu.hideout.activitypub.service.objects.user.APUserService import dev.usbharu.hideout.application.external.Transaction +import dev.usbharu.hideout.core.domain.exception.FailedToGetResourcesException +import dev.usbharu.hideout.core.query.UserQueryService import dev.usbharu.httpsignature.common.HttpHeaders import dev.usbharu.httpsignature.common.HttpMethod import dev.usbharu.httpsignature.common.HttpRequest @@ -14,7 +16,8 @@ import java.net.URL class HttpSignatureFilter( private val httpSignatureHeaderParser: SignatureHeaderParser, private val transaction: Transaction, - private val apUserService: APUserService + private val apUserService: APUserService, + private val userQueryService: UserQueryService ) : AbstractPreAuthenticatedProcessingFilter() { override fun getPreAuthenticatedPrincipal(request: HttpServletRequest?): Any? { @@ -32,7 +35,11 @@ class HttpSignatureFilter( } runBlocking { transaction.transaction { - apUserService.fetchPerson(signature.keyId) + try { + userQueryService.findByKeyId(signature.keyId) + } catch (e: FailedToGetResourcesException) { + apUserService.fetchPerson(signature.keyId) + } } } return signature.keyId From e6e9c841450470f6804f4eea7a0149415ca7e085 Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Tue, 21 Nov 2023 17:03:12 +0900 Subject: [PATCH 6/7] =?UTF-8?q?fix:=20=E3=83=88=E3=83=A9=E3=83=B3=E3=82=B6?= =?UTF-8?q?=E3=82=AF=E3=82=B7=E3=83=A7=E3=83=B3=E3=81=AE=E5=95=8F=E9=A1=8C?= =?UTF-8?q?=E3=82=92=E3=81=82=E3=82=8B=E7=A8=8B=E5=BA=A6=E8=A7=A3=E6=B1=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../infrastructure/exposed/ExposedTransaction.kt | 3 +-- src/main/resources/application.yml | 2 -- src/main/resources/db/migration/V1__Init_DB.sql | 13 +++++++------ 3 files changed, 8 insertions(+), 10 deletions(-) diff --git a/src/main/kotlin/dev/usbharu/hideout/application/infrastructure/exposed/ExposedTransaction.kt b/src/main/kotlin/dev/usbharu/hideout/application/infrastructure/exposed/ExposedTransaction.kt index 4dc8316b..3438d428 100644 --- a/src/main/kotlin/dev/usbharu/hideout/application/infrastructure/exposed/ExposedTransaction.kt +++ b/src/main/kotlin/dev/usbharu/hideout/application/infrastructure/exposed/ExposedTransaction.kt @@ -4,12 +4,11 @@ import dev.usbharu.hideout.application.external.Transaction import kotlinx.coroutines.slf4j.MDCContext import org.jetbrains.exposed.sql.transactions.experimental.newSuspendedTransaction import org.springframework.stereotype.Service -import java.sql.Connection @Service class ExposedTransaction : Transaction { override suspend fun transaction(block: suspend () -> T): T { - return newSuspendedTransaction(MDCContext(), transactionIsolation = Connection.TRANSACTION_SERIALIZABLE) { + return newSuspendedTransaction(MDCContext()) { block() } } diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index c9c2604f..daff34db 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -18,8 +18,6 @@ spring: WRITE_DATES_AS_TIMESTAMPS: false default-property-inclusion: always datasource: - hikari: - transaction-isolation: "TRANSACTION_SERIALIZABLE" driver-class-name: org.postgresql.Driver url: "jdbc:postgresql:hideout2" username: "postgres" diff --git a/src/main/resources/db/migration/V1__Init_DB.sql b/src/main/resources/db/migration/V1__Init_DB.sql index 15a61994..4ea80255 100644 --- a/src/main/resources/db/migration/V1__Init_DB.sql +++ b/src/main/resources/db/migration/V1__Init_DB.sql @@ -3,9 +3,9 @@ create table if not exists instance id bigint primary key, "name" varchar(1000) not null, description varchar(5000) not null, - url varchar(255) not null, + url varchar(255) not null unique, icon_url varchar(255) not null, - shared_inbox varchar(255) null, + shared_inbox varchar(255) null unique, software varchar(255) not null, version varchar(255) not null, is_blocked boolean not null, @@ -21,9 +21,9 @@ create table if not exists users screen_name varchar(300) not null, description varchar(10000) not null, password varchar(255) null, - inbox varchar(1000) not null, - outbox varchar(1000) not null, - url varchar(1000) not null, + inbox varchar(1000) not null unique, + outbox varchar(1000) not null unique, + url varchar(1000) not null unique, public_key varchar(10000) not null, private_key varchar(10000) null, created_at bigint not null, @@ -31,6 +31,7 @@ create table if not exists users "following" varchar(1000) null, followers varchar(1000) null, "instance" bigint null, + unique (name, domain), constraint fk_users_instance__id foreign key ("instance") references instance (id) on delete restrict on update restrict ); create table if not exists follow_requests @@ -73,7 +74,7 @@ create table if not exists posts repost_id bigint null, reply_id bigint null, "sensitive" boolean default false not null, - ap_id varchar(100) not null + ap_id varchar(100) not null unique ); alter table posts add constraint fk_posts_userid__id foreign key (user_id) references users (id) on delete restrict on update restrict; From 3776cf94fbd9747f96b8bcf076c668bb294cede3 Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Tue, 21 Nov 2023 17:18:34 +0900 Subject: [PATCH 7/7] test: fix test --- src/intTest/resources/application.yml | 2 ++ .../service/common/APResourceResolveServiceImpl.kt | 5 ++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/intTest/resources/application.yml b/src/intTest/resources/application.yml index 9760e828..258014ca 100644 --- a/src/intTest/resources/application.yml +++ b/src/intTest/resources/application.yml @@ -17,6 +17,8 @@ hideout: secret-key: "" spring: + flyway: + enabled: false datasource: driver-class-name: org.h2.Driver url: "jdbc:h2:mem:test;MODE=POSTGRESQL;DB_CLOSE_DELAY=-1" diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/common/APResourceResolveServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/common/APResourceResolveServiceImpl.kt index 81b7aec3..85099d84 100644 --- a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/common/APResourceResolveServiceImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/common/APResourceResolveServiceImpl.kt @@ -39,9 +39,8 @@ class APResourceResolveServiceImpl( return (cacheManager.getOrWait(key) as APResolveResponse).objects } - private suspend fun runResolve(url: String, singer: User?, clazz: Class): ResolveResponse { - return APResolveResponse(apRequestService.apGet(url, singer, clazz)) - } + private suspend fun runResolve(url: String, singer: User?, clazz: Class): ResolveResponse = + APResolveResponse(apRequestService.apGet(url, singer, clazz)) private fun genCacheKey(url: String, singerId: Long?): String { if (singerId != null) {