mirror of https://github.com/usbharu/Hideout.git
Compare commits
17 Commits
02abbab7e1
...
ffbcda644d
| Author | SHA1 | Date |
|---|---|---|
|
|
ffbcda644d | |
|
|
72ef4611f2 | |
|
|
c35401c4b7 | |
|
|
c999819bd2 | |
|
|
f767da23f3 | |
|
|
d63503daef | |
|
|
9c96595758 | |
|
|
b1c2b554b0 | |
|
|
8bb6b3d017 | |
|
|
3bddfa854e | |
|
|
1323815abd | |
|
|
e0b1cf6bc0 | |
|
|
84356161a8 | |
|
|
b8756b40a6 | |
|
|
4aa1970c76 | |
|
|
a29cf62cfb | |
|
|
53b26ecf8f |
|
|
@ -182,6 +182,7 @@ dependencies {
|
||||||
implementation("org.apache.tika:tika-core:2.9.1")
|
implementation("org.apache.tika:tika-core:2.9.1")
|
||||||
implementation("net.coobird:thumbnailator:0.4.20")
|
implementation("net.coobird:thumbnailator:0.4.20")
|
||||||
implementation("org.bytedeco:javacv-platform:1.5.9")
|
implementation("org.bytedeco:javacv-platform:1.5.9")
|
||||||
|
implementation("org.flywaydb:flyway-core")
|
||||||
|
|
||||||
implementation("io.ktor:ktor-client-logging-jvm:$ktor_version")
|
implementation("io.ktor:ktor-client-logging-jvm:$ktor_version")
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
insert into "USERS" (ID, NAME, DOMAIN, SCREEN_NAME, DESCRIPTION, PASSWORD, INBOX, OUTBOX, URL, PUBLIC_KEY, PRIVATE_KEY,
|
insert into "USERS" (ID, NAME, DOMAIN, SCREEN_NAME, DESCRIPTION, PASSWORD, INBOX, OUTBOX, URL, PUBLIC_KEY, PRIVATE_KEY,
|
||||||
CREATED_AT, KEY_ID, FOLLOWING, FOLLOWERS)
|
CREATED_AT, KEY_ID, FOLLOWING, FOLLOWERS, INSTANCE)
|
||||||
VALUES (8, 'test-user8', 'example.com', 'Im test-user8.', 'THis account is test-user8.',
|
VALUES (8, 'test-user8', 'example.com', 'Im test-user8.', 'THis account is test-user8.',
|
||||||
'5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8',
|
'5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8',
|
||||||
'https://example.com/users/test-user8/inbox',
|
'https://example.com/users/test-user8/inbox',
|
||||||
|
|
@ -7,10 +7,10 @@ VALUES (8, 'test-user8', 'example.com', 'Im test-user8.', 'THis account is test-
|
||||||
'-----BEGIN PUBLIC KEY-----...-----END PUBLIC KEY-----',
|
'-----BEGIN PUBLIC KEY-----...-----END PUBLIC KEY-----',
|
||||||
'-----BEGIN PRIVATE KEY-----...-----END PRIVATE KEY-----', 12345678,
|
'-----BEGIN PRIVATE KEY-----...-----END PRIVATE KEY-----', 12345678,
|
||||||
'https://example.com/users/test-user8#pubkey', 'https://example.com/users/test-user8/following',
|
'https://example.com/users/test-user8#pubkey', 'https://example.com/users/test-user8/following',
|
||||||
'https://example.com/users/test-user8/followers');
|
'https://example.com/users/test-user8/followers', null);
|
||||||
|
|
||||||
insert into "USERS" (ID, NAME, DOMAIN, SCREEN_NAME, DESCRIPTION, PASSWORD, INBOX, OUTBOX, URL, PUBLIC_KEY, PRIVATE_KEY,
|
insert into "USERS" (ID, NAME, DOMAIN, SCREEN_NAME, DESCRIPTION, PASSWORD, INBOX, OUTBOX, URL, PUBLIC_KEY, PRIVATE_KEY,
|
||||||
CREATED_AT, KEY_ID, FOLLOWING, FOLLOWERS)
|
CREATED_AT, KEY_ID, FOLLOWING, FOLLOWERS, INSTANCE)
|
||||||
VALUES (9, 'test-user9', 'follower.example.com', 'Im test-user9.', 'THis account is test-user9.',
|
VALUES (9, 'test-user9', 'follower.example.com', 'Im test-user9.', 'THis account is test-user9.',
|
||||||
null,
|
null,
|
||||||
'https://follower.example.com/users/test-user9/inbox',
|
'https://follower.example.com/users/test-user9/inbox',
|
||||||
|
|
@ -19,11 +19,11 @@ VALUES (9, 'test-user9', 'follower.example.com', 'Im test-user9.', 'THis account
|
||||||
null, 12345678,
|
null, 12345678,
|
||||||
'https://follower.example.com/users/test-user9#pubkey',
|
'https://follower.example.com/users/test-user9#pubkey',
|
||||||
'https://follower.example.com/users/test-user9/following',
|
'https://follower.example.com/users/test-user9/following',
|
||||||
'https://follower.example.com/users/test-user9/followers');
|
'https://follower.example.com/users/test-user9/followers', null);
|
||||||
|
|
||||||
insert into USERS_FOLLOWERS (USER_ID, FOLLOWER_ID)
|
insert into USERS_FOLLOWERS (USER_ID, FOLLOWER_ID)
|
||||||
VALUES (8, 9);
|
VALUES (8, 9);
|
||||||
|
|
||||||
insert into POSTS (ID, "userId", OVERVIEW, TEXT, "createdAt", VISIBILITY, URL, "repostId", "replyId", SENSITIVE, AP_ID)
|
insert into POSTS (ID, USER_ID, OVERVIEW, TEXT, CREATED_AT, VISIBILITY, URL, REPLY_ID, REPOST_ID, SENSITIVE, AP_ID)
|
||||||
VALUES (1239, 8, null, 'test post', 12345680, 2, 'https://example.com/users/test-user8/posts/1239', null, null, false,
|
VALUES (1239, 8, null, 'test post', 12345680, 2, 'https://example.com/users/test-user8/posts/1239', null, null, false,
|
||||||
'https://example.com/users/test-user8/posts/1239');
|
'https://example.com/users/test-user8/posts/1239');
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
insert into "USERS" (ID, NAME, DOMAIN, SCREEN_NAME, DESCRIPTION, PASSWORD, INBOX, OUTBOX, URL, PUBLIC_KEY, PRIVATE_KEY,
|
insert into "USERS" (ID, NAME, DOMAIN, SCREEN_NAME, DESCRIPTION, PASSWORD, INBOX, OUTBOX, URL, PUBLIC_KEY, PRIVATE_KEY,
|
||||||
CREATED_AT, KEY_ID, FOLLOWING, FOLLOWERS)
|
CREATED_AT, KEY_ID, FOLLOWING, FOLLOWERS, INSTANCE)
|
||||||
VALUES (4, 'test-user4', 'example.com', 'Im test user4.', 'THis account is test user4.',
|
VALUES (4, 'test-user4', 'example.com', 'Im test user4.', 'THis account is test user4.',
|
||||||
'5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8',
|
'5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8',
|
||||||
'https://example.com/users/test-user4/inbox',
|
'https://example.com/users/test-user4/inbox',
|
||||||
|
|
@ -7,10 +7,10 @@ VALUES (4, 'test-user4', 'example.com', 'Im test user4.', 'THis account is test
|
||||||
'-----BEGIN PUBLIC KEY-----...-----END PUBLIC KEY-----',
|
'-----BEGIN PUBLIC KEY-----...-----END PUBLIC KEY-----',
|
||||||
'-----BEGIN PRIVATE KEY-----...-----END PRIVATE KEY-----', 12345678,
|
'-----BEGIN PRIVATE KEY-----...-----END PRIVATE KEY-----', 12345678,
|
||||||
'https://example.com/users/test-user4#pubkey', 'https://example.com/users/test-user4/following',
|
'https://example.com/users/test-user4#pubkey', 'https://example.com/users/test-user4/following',
|
||||||
'https://example.com/users/test-user4/followers');
|
'https://example.com/users/test-user4/followers', null);
|
||||||
|
|
||||||
insert into "USERS" (ID, NAME, DOMAIN, SCREEN_NAME, DESCRIPTION, PASSWORD, INBOX, OUTBOX, URL, PUBLIC_KEY, PRIVATE_KEY,
|
insert into "USERS" (ID, NAME, DOMAIN, SCREEN_NAME, DESCRIPTION, PASSWORD, INBOX, OUTBOX, URL, PUBLIC_KEY, PRIVATE_KEY,
|
||||||
CREATED_AT, KEY_ID, FOLLOWING, FOLLOWERS)
|
CREATED_AT, KEY_ID, FOLLOWING, FOLLOWERS, INSTANCE)
|
||||||
VALUES (5, 'test-user5', 'follower.example.com', 'Im test user5.', 'THis account is test user5.',
|
VALUES (5, 'test-user5', 'follower.example.com', 'Im test user5.', 'THis account is test user5.',
|
||||||
null,
|
null,
|
||||||
'https://follower.example.com/users/test-user5/inbox',
|
'https://follower.example.com/users/test-user5/inbox',
|
||||||
|
|
@ -19,11 +19,12 @@ VALUES (5, 'test-user5', 'follower.example.com', 'Im test user5.', 'THis account
|
||||||
null, 12345678,
|
null, 12345678,
|
||||||
'https://follower.example.com/users/test-user5#pubkey',
|
'https://follower.example.com/users/test-user5#pubkey',
|
||||||
'https://follower.example.com/users/test-user5/following',
|
'https://follower.example.com/users/test-user5/following',
|
||||||
'https://follower.example.com/users/test-user5/followers');
|
'https://follower.example.com/users/test-user5/followers', null);
|
||||||
|
|
||||||
insert into USERS_FOLLOWERS (USER_ID, FOLLOWER_ID)
|
insert into USERS_FOLLOWERS (USER_ID, FOLLOWER_ID)
|
||||||
VALUES (4, 5);
|
VALUES (4, 5);
|
||||||
|
|
||||||
insert into POSTS (ID, "userId", OVERVIEW, TEXT, "createdAt", VISIBILITY, URL, "repostId", "replyId", SENSITIVE, AP_ID)
|
insert into POSTS (ID, "USER_ID", OVERVIEW, TEXT, "CREATED_AT", VISIBILITY, URL, "REPOST_ID", "REPLY_ID", SENSITIVE,
|
||||||
|
AP_ID)
|
||||||
VALUES (1237, 4, null, 'test post', 12345680, 0, 'https://example.com/users/test-user4/posts/1237', null, null, false,
|
VALUES (1237, 4, null, 'test post', 12345680, 0, 'https://example.com/users/test-user4/posts/1237', null, null, false,
|
||||||
'https://example.com/users/test-user4/posts/1237');
|
'https://example.com/users/test-user4/posts/1237');
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
insert into "USERS" (ID, NAME, DOMAIN, SCREEN_NAME, DESCRIPTION, PASSWORD, INBOX, OUTBOX, URL, PUBLIC_KEY, PRIVATE_KEY,
|
insert into "USERS" (ID, NAME, DOMAIN, SCREEN_NAME, DESCRIPTION, PASSWORD, INBOX, OUTBOX, URL, PUBLIC_KEY, PRIVATE_KEY,
|
||||||
CREATED_AT, KEY_ID, FOLLOWING, FOLLOWERS)
|
CREATED_AT, KEY_ID, FOLLOWING, FOLLOWERS, INSTANCE)
|
||||||
VALUES (6, 'test-user6', 'example.com', 'Im test-user6.', 'THis account is test-user6.',
|
VALUES (6, 'test-user6', 'example.com', 'Im test-user6.', 'THis account is test-user6.',
|
||||||
'5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8',
|
'5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8',
|
||||||
'https://example.com/users/test-user6/inbox',
|
'https://example.com/users/test-user6/inbox',
|
||||||
|
|
@ -7,10 +7,10 @@ VALUES (6, 'test-user6', 'example.com', 'Im test-user6.', 'THis account is test-
|
||||||
'-----BEGIN PUBLIC KEY-----...-----END PUBLIC KEY-----',
|
'-----BEGIN PUBLIC KEY-----...-----END PUBLIC KEY-----',
|
||||||
'-----BEGIN PRIVATE KEY-----...-----END PRIVATE KEY-----', 12345678,
|
'-----BEGIN PRIVATE KEY-----...-----END PRIVATE KEY-----', 12345678,
|
||||||
'https://example.com/users/test-user6#pubkey', 'https://example.com/users/test-user6/following',
|
'https://example.com/users/test-user6#pubkey', 'https://example.com/users/test-user6/following',
|
||||||
'https://example.com/users/test-user6/followers');
|
'https://example.com/users/test-user6/followers', null);
|
||||||
|
|
||||||
insert into "USERS" (ID, NAME, DOMAIN, SCREEN_NAME, DESCRIPTION, PASSWORD, INBOX, OUTBOX, URL, PUBLIC_KEY, PRIVATE_KEY,
|
insert into "USERS" (ID, NAME, DOMAIN, SCREEN_NAME, DESCRIPTION, PASSWORD, INBOX, OUTBOX, URL, PUBLIC_KEY, PRIVATE_KEY,
|
||||||
CREATED_AT, KEY_ID, FOLLOWING, FOLLOWERS)
|
CREATED_AT, KEY_ID, FOLLOWING, FOLLOWERS, INSTANCE)
|
||||||
VALUES (7, 'test-user7', 'follower.example.com', 'Im test-user7.', 'THis account is test-user7.',
|
VALUES (7, 'test-user7', 'follower.example.com', 'Im test-user7.', 'THis account is test-user7.',
|
||||||
null,
|
null,
|
||||||
'https://follower.example.com/users/test-user7/inbox',
|
'https://follower.example.com/users/test-user7/inbox',
|
||||||
|
|
@ -19,11 +19,12 @@ VALUES (7, 'test-user7', 'follower.example.com', 'Im test-user7.', 'THis account
|
||||||
null, 12345678,
|
null, 12345678,
|
||||||
'https://follower.example.com/users/test-user7#pubkey',
|
'https://follower.example.com/users/test-user7#pubkey',
|
||||||
'https://follower.example.com/users/test-user7/following',
|
'https://follower.example.com/users/test-user7/following',
|
||||||
'https://follower.example.com/users/test-user7/followers');
|
'https://follower.example.com/users/test-user7/followers', null);
|
||||||
|
|
||||||
insert into USERS_FOLLOWERS (USER_ID, FOLLOWER_ID)
|
insert into USERS_FOLLOWERS (USER_ID, FOLLOWER_ID)
|
||||||
VALUES (6, 7);
|
VALUES (6, 7);
|
||||||
|
|
||||||
insert into POSTS (ID, "userId", OVERVIEW, TEXT, "createdAt", VISIBILITY, URL, "repostId", "replyId", SENSITIVE, AP_ID)
|
insert into POSTS (ID, "USER_ID", OVERVIEW, TEXT, "CREATED_AT", VISIBILITY, URL, "REPOST_ID", "REPLY_ID", SENSITIVE,
|
||||||
|
AP_ID)
|
||||||
VALUES (1238, 6, null, 'test post', 12345680, 1, 'https://example.com/users/test-user6/posts/1238', null, null, false,
|
VALUES (1238, 6, null, 'test post', 12345680, 1, 'https://example.com/users/test-user6/posts/1238', null, null, false,
|
||||||
'https://example.com/users/test-user6/posts/1238');
|
'https://example.com/users/test-user6/posts/1238');
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
insert into "USERS" (ID, NAME, DOMAIN, SCREEN_NAME, DESCRIPTION, PASSWORD, INBOX, OUTBOX, URL, PUBLIC_KEY, PRIVATE_KEY,
|
insert into "USERS" (ID, NAME, DOMAIN, SCREEN_NAME, DESCRIPTION, PASSWORD, INBOX, OUTBOX, URL, PUBLIC_KEY, PRIVATE_KEY,
|
||||||
CREATED_AT, KEY_ID, FOLLOWING, FOLLOWERS)
|
CREATED_AT, KEY_ID, FOLLOWING, FOLLOWERS, INSTANCE)
|
||||||
VALUES (11, 'test-user11', 'example.com', 'Im test-user11.', 'THis account is test-user11.',
|
VALUES (11, 'test-user11', 'example.com', 'Im test-user11.', 'THis account is test-user11.',
|
||||||
'5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8',
|
'5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8',
|
||||||
'https://example.com/users/test-user11/inbox',
|
'https://example.com/users/test-user11/inbox',
|
||||||
|
|
@ -7,9 +7,10 @@ VALUES (11, 'test-user11', 'example.com', 'Im test-user11.', 'THis account is te
|
||||||
'-----BEGIN PUBLIC KEY-----...-----END PUBLIC KEY-----',
|
'-----BEGIN PUBLIC KEY-----...-----END PUBLIC KEY-----',
|
||||||
'-----BEGIN PRIVATE KEY-----...-----END PRIVATE KEY-----', 12345678,
|
'-----BEGIN PRIVATE KEY-----...-----END PRIVATE KEY-----', 12345678,
|
||||||
'https://example.com/users/test-user11#pubkey', 'https://example.com/users/test-user11/following',
|
'https://example.com/users/test-user11#pubkey', 'https://example.com/users/test-user11/following',
|
||||||
'https://example.com/users/test-user11/followers');
|
'https://example.com/users/test-user11/followers', null);
|
||||||
|
|
||||||
insert into POSTS (ID, "userId", OVERVIEW, TEXT, "createdAt", VISIBILITY, URL, "repostId", "replyId", SENSITIVE, AP_ID)
|
insert into POSTS (ID, "USER_ID", OVERVIEW, TEXT, "CREATED_AT", VISIBILITY, URL, "REPOST_ID", "REPLY_ID", SENSITIVE,
|
||||||
|
AP_ID)
|
||||||
VALUES (1242, 11, null, 'test post', 12345680, 0, 'https://example.com/users/test-user11/posts/1242', null, null, false,
|
VALUES (1242, 11, null, 'test post', 12345680, 0, 'https://example.com/users/test-user11/posts/1242', null, null, false,
|
||||||
'https://example.com/users/test-user11/posts/1242');
|
'https://example.com/users/test-user11/posts/1242');
|
||||||
|
|
||||||
|
|
@ -17,6 +18,6 @@ insert into MEDIA (ID, NAME, URL, REMOTE_URL, THUMBNAIL_URL, TYPE, BLURHASH, MIM
|
||||||
VALUES (1, 'test-media', 'https://example.com/media/test-media.png', null, null, 0, null, 'image/png', null),
|
VALUES (1, 'test-media', 'https://example.com/media/test-media.png', null, null, 0, null, 'image/png', null),
|
||||||
(2, 'test-media2', 'https://example.com/media/test-media2.png', null, null, 0, null, 'image/png', null);
|
(2, 'test-media2', 'https://example.com/media/test-media2.png', null, null, 0, null, 'image/png', null);
|
||||||
|
|
||||||
insert into POSTSMEDIA(POST_ID, MEDIA_ID)
|
insert into POSTS_MEDIA(POST_ID, MEDIA_ID)
|
||||||
VALUES (1242, 1),
|
VALUES (1242, 1),
|
||||||
(1242, 2);
|
(1242, 2);
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
insert into "USERS" (ID, NAME, DOMAIN, SCREEN_NAME, DESCRIPTION, PASSWORD, INBOX, OUTBOX, URL, PUBLIC_KEY, PRIVATE_KEY,
|
insert into "USERS" (ID, NAME, DOMAIN, SCREEN_NAME, DESCRIPTION, PASSWORD, INBOX, OUTBOX, URL, PUBLIC_KEY, PRIVATE_KEY,
|
||||||
CREATED_AT, KEY_ID, FOLLOWING, FOLLOWERS)
|
CREATED_AT, KEY_ID, FOLLOWING, FOLLOWERS, INSTANCE)
|
||||||
VALUES (10, 'test-user10', 'example.com', 'Im test-user10.', 'THis account is test-user10.',
|
VALUES (10, 'test-user10', 'example.com', 'Im test-user10.', 'THis account is test-user10.',
|
||||||
'5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8',
|
'5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8',
|
||||||
'https://example.com/users/test-user10/inbox',
|
'https://example.com/users/test-user10/inbox',
|
||||||
|
|
@ -7,9 +7,10 @@ VALUES (10, 'test-user10', 'example.com', 'Im test-user10.', 'THis account is te
|
||||||
'-----BEGIN PUBLIC KEY-----...-----END PUBLIC KEY-----',
|
'-----BEGIN PUBLIC KEY-----...-----END PUBLIC KEY-----',
|
||||||
'-----BEGIN PRIVATE KEY-----...-----END PRIVATE KEY-----', 12345678,
|
'-----BEGIN PRIVATE KEY-----...-----END PRIVATE KEY-----', 12345678,
|
||||||
'https://example.com/users/test-user10#pubkey', 'https://example.com/users/test-user10/following',
|
'https://example.com/users/test-user10#pubkey', 'https://example.com/users/test-user10/following',
|
||||||
'https://example.com/users/test-user10/followers');
|
'https://example.com/users/test-user10/followers', null);
|
||||||
|
|
||||||
insert into POSTS (ID, "userId", OVERVIEW, TEXT, "createdAt", VISIBILITY, URL, "repostId", "replyId", SENSITIVE, AP_ID)
|
insert into POSTS (ID, "USER_ID", OVERVIEW, TEXT, "CREATED_AT", VISIBILITY, URL, "REPOST_ID", "REPLY_ID", SENSITIVE,
|
||||||
|
AP_ID)
|
||||||
VALUES (1240, 10, null, 'test post', 12345680, 0, 'https://example.com/users/test-user10/posts/1240', null, null, false,
|
VALUES (1240, 10, null, 'test post', 12345680, 0, 'https://example.com/users/test-user10/posts/1240', null, null, false,
|
||||||
'https://example.com/users/test-user10/posts/1240'),
|
'https://example.com/users/test-user10/posts/1240'),
|
||||||
(1241, 10, null, 'test post', 12345680, 0, 'https://example.com/users/test-user10/posts/1241', null, 1240, false,
|
(1241, 10, null, 'test post', 12345680, 0, 'https://example.com/users/test-user10/posts/1241', null, 1240, false,
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
insert into "USERS" (ID, NAME, DOMAIN, SCREEN_NAME, DESCRIPTION, PASSWORD, INBOX, OUTBOX, URL, PUBLIC_KEY, PRIVATE_KEY,
|
insert into "USERS" (ID, NAME, DOMAIN, SCREEN_NAME, DESCRIPTION, PASSWORD, INBOX, OUTBOX, URL, PUBLIC_KEY, PRIVATE_KEY,
|
||||||
CREATED_AT, KEY_ID, FOLLOWING, FOLLOWERS)
|
CREATED_AT, KEY_ID, FOLLOWING, FOLLOWERS, INSTANCE)
|
||||||
VALUES (3, 'test-user3', 'example.com', 'Im test user3.', 'THis account is test user3.',
|
VALUES (3, 'test-user3', 'example.com', 'Im test user3.', 'THis account is test user3.',
|
||||||
'5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8',
|
'5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8',
|
||||||
'https://example.com/users/test-user3/inbox',
|
'https://example.com/users/test-user3/inbox',
|
||||||
|
|
@ -7,8 +7,9 @@ VALUES (3, 'test-user3', 'example.com', 'Im test user3.', 'THis account is test
|
||||||
'-----BEGIN PUBLIC KEY-----...-----END PUBLIC KEY-----',
|
'-----BEGIN PUBLIC KEY-----...-----END PUBLIC KEY-----',
|
||||||
'-----BEGIN PRIVATE KEY-----...-----END PRIVATE KEY-----', 12345678,
|
'-----BEGIN PRIVATE KEY-----...-----END PRIVATE KEY-----', 12345678,
|
||||||
'https://example.com/users/test-user3#pubkey', 'https://example.com/users/test-user3/following',
|
'https://example.com/users/test-user3#pubkey', 'https://example.com/users/test-user3/following',
|
||||||
'https://example.com/users/test-user3/followers');
|
'https://example.com/users/test-user3/followers', null);
|
||||||
|
|
||||||
insert into POSTS (ID, "userId", OVERVIEW, TEXT, "createdAt", VISIBILITY, URL, "repostId", "replyId", SENSITIVE, AP_ID)
|
insert into POSTS (ID, "USER_ID", OVERVIEW, TEXT, "CREATED_AT", VISIBILITY, URL, "REPOST_ID", "REPLY_ID", SENSITIVE,
|
||||||
|
AP_ID)
|
||||||
VALUES (1236, 3, null, 'test post', 12345680, 2, 'https://example.com/users/test-user3/posts/1236', null, null, false,
|
VALUES (1236, 3, null, 'test post', 12345680, 2, 'https://example.com/users/test-user3/posts/1236', null, null, false,
|
||||||
'https://example.com/users/test-user3/posts/1236')
|
'https://example.com/users/test-user3/posts/1236')
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,14 @@
|
||||||
insert into "USERS" (ID, NAME, DOMAIN, SCREEN_NAME, DESCRIPTION, PASSWORD, INBOX, OUTBOX, URL, PUBLIC_KEY, PRIVATE_KEY,
|
insert into "USERS" (ID, NAME, DOMAIN, SCREEN_NAME, DESCRIPTION, PASSWORD, INBOX, OUTBOX, URL, PUBLIC_KEY, PRIVATE_KEY,
|
||||||
CREATED_AT, KEY_ID, FOLLOWING, FOLLOWERS)
|
CREATED_AT, KEY_ID, FOLLOWING, FOLLOWERS, INSTANCE)
|
||||||
VALUES (1, 'test-user', 'example.com', 'Im test user.', 'THis account is test user.',
|
VALUES (1, 'test-user', 'example.com', 'Im test user.', 'THis account is test user.',
|
||||||
'5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8', 'https://example.com/users/test-user/inbox',
|
'5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8', 'https://example.com/users/test-user/inbox',
|
||||||
'https://example.com/users/test-user/outbox', 'https://example.com/users/test-user',
|
'https://example.com/users/test-user/outbox', 'https://example.com/users/test-user',
|
||||||
'-----BEGIN PUBLIC KEY-----...-----END PUBLIC KEY-----',
|
'-----BEGIN PUBLIC KEY-----...-----END PUBLIC KEY-----',
|
||||||
'-----BEGIN PRIVATE KEY-----...-----END PRIVATE KEY-----', 12345678,
|
'-----BEGIN PRIVATE KEY-----...-----END PRIVATE KEY-----', 12345678,
|
||||||
'https://example.com/users/test-user#pubkey', 'https://example.com/users/test-user/following',
|
'https://example.com/users/test-user#pubkey', 'https://example.com/users/test-user/following',
|
||||||
'https://example.com/users/test-users/followers');
|
'https://example.com/users/test-users/followers', null);
|
||||||
|
|
||||||
insert into POSTS (ID, "userId", OVERVIEW, TEXT, "createdAt", VISIBILITY, URL, "repostId", "replyId", SENSITIVE, AP_ID)
|
insert into POSTS (ID, "USER_ID", OVERVIEW, TEXT, "CREATED_AT", VISIBILITY, URL, "REPOST_ID", "REPLY_ID", SENSITIVE,
|
||||||
|
AP_ID)
|
||||||
VALUES (1234, 1, null, 'test post', 12345680, 0, 'https://example.com/users/test-user/posts/1234', null, null, false,
|
VALUES (1234, 1, null, 'test post', 12345680, 0, 'https://example.com/users/test-user/posts/1234', null, null, false,
|
||||||
'https://example.com/users/test-user/posts/1234')
|
'https://example.com/users/test-user/posts/1234')
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
insert into "USERS" (ID, NAME, DOMAIN, SCREEN_NAME, DESCRIPTION, PASSWORD, INBOX, OUTBOX, URL, PUBLIC_KEY, PRIVATE_KEY,
|
insert into "USERS" (ID, NAME, DOMAIN, SCREEN_NAME, DESCRIPTION, PASSWORD, INBOX, OUTBOX, URL, PUBLIC_KEY, PRIVATE_KEY,
|
||||||
CREATED_AT, KEY_ID, FOLLOWING, FOLLOWERS)
|
CREATED_AT, KEY_ID, FOLLOWING, FOLLOWERS, INSTANCE)
|
||||||
VALUES (2, 'test-user2', 'example.com', 'Im test user2.', 'THis account is test user2.',
|
VALUES (2, 'test-user2', 'example.com', 'Im test user2.', 'THis account is test user2.',
|
||||||
'5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8',
|
'5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8',
|
||||||
'https://example.com/users/test-user2/inbox',
|
'https://example.com/users/test-user2/inbox',
|
||||||
|
|
@ -7,8 +7,9 @@ VALUES (2, 'test-user2', 'example.com', 'Im test user2.', 'THis account is test
|
||||||
'-----BEGIN PUBLIC KEY-----...-----END PUBLIC KEY-----',
|
'-----BEGIN PUBLIC KEY-----...-----END PUBLIC KEY-----',
|
||||||
'-----BEGIN PRIVATE KEY-----...-----END PRIVATE KEY-----', 12345678,
|
'-----BEGIN PRIVATE KEY-----...-----END PRIVATE KEY-----', 12345678,
|
||||||
'https://example.com/users/test-user2#pubkey', 'https://example.com/users/test-user2/following',
|
'https://example.com/users/test-user2#pubkey', 'https://example.com/users/test-user2/following',
|
||||||
'https://example.com/users/test-user2/followers');
|
'https://example.com/users/test-user2/followers', null);
|
||||||
|
|
||||||
insert into POSTS (ID, "userId", OVERVIEW, TEXT, "createdAt", VISIBILITY, URL, "repostId", "replyId", SENSITIVE, AP_ID)
|
insert into POSTS (ID, "USER_ID", OVERVIEW, TEXT, "CREATED_AT", VISIBILITY, URL, "REPOST_ID", "REPLY_ID", SENSITIVE,
|
||||||
|
AP_ID)
|
||||||
VALUES (1235, 2, null, 'test post', 12345680, 1, 'https://example.com/users/test-user2/posts/1235', null, null, false,
|
VALUES (1235, 2, null, 'test post', 12345680, 1, 'https://example.com/users/test-user2/posts/1235', null, null, false,
|
||||||
'https://example.com/users/test-user2/posts/1235')
|
'https://example.com/users/test-user2/posts/1235')
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
insert into "USERS" (ID, NAME, DOMAIN, SCREEN_NAME, DESCRIPTION, PASSWORD, INBOX, OUTBOX, URL, PUBLIC_KEY, PRIVATE_KEY,
|
insert into "USERS" (ID, NAME, DOMAIN, SCREEN_NAME, DESCRIPTION, PASSWORD, INBOX, OUTBOX, URL, PUBLIC_KEY, PRIVATE_KEY,
|
||||||
CREATED_AT, KEY_ID, FOLLOWING, FOLLOWERS)
|
CREATED_AT, KEY_ID, FOLLOWING, FOLLOWERS, INSTANCE)
|
||||||
VALUES (1, 'test-user', 'example.com', 'Im test user.', 'THis account is test user.',
|
VALUES (1, 'test-user', 'example.com', 'Im test user.', 'THis account is test user.',
|
||||||
'5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8', 'https://example.com/users/test-user/inbox',
|
'5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8', 'https://example.com/users/test-user/inbox',
|
||||||
'https://example.com/users/test-user/outbox', 'https://example.com/users/test-user',
|
'https://example.com/users/test-user/outbox', 'https://example.com/users/test-user',
|
||||||
'-----BEGIN PUBLIC KEY-----...-----END PUBLIC KEY-----',
|
'-----BEGIN PUBLIC KEY-----...-----END PUBLIC KEY-----',
|
||||||
'-----BEGIN PRIVATE KEY-----...-----END PRIVATE KEY-----', 12345678,
|
'-----BEGIN PRIVATE KEY-----...-----END PRIVATE KEY-----', 12345678,
|
||||||
'https://example.com/users/test-user#pubkey', 'https://example.com/users/test-user/following',
|
'https://example.com/users/test-user#pubkey', 'https://example.com/users/test-user/following',
|
||||||
'https://example.com/users/test-users/followers');
|
'https://example.com/users/test-users/followers', null);
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
package dev.usbharu.hideout.activitypub.domain.model.objects
|
package dev.usbharu.hideout.activitypub.domain.model.objects
|
||||||
|
|
||||||
|
@Suppress("VariableNaming")
|
||||||
open class ObjectValue : Object {
|
open class ObjectValue : Object {
|
||||||
|
|
||||||
var `object`: String? = null
|
var `object`: String? = null
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,10 @@ package dev.usbharu.hideout.activitypub.service.common
|
||||||
import dev.usbharu.hideout.activitypub.domain.model.objects.Object
|
import dev.usbharu.hideout.activitypub.domain.model.objects.Object
|
||||||
import dev.usbharu.hideout.core.domain.model.user.User
|
import dev.usbharu.hideout.core.domain.model.user.User
|
||||||
import dev.usbharu.hideout.core.domain.model.user.UserRepository
|
import dev.usbharu.hideout.core.domain.model.user.UserRepository
|
||||||
|
import dev.usbharu.hideout.core.service.resource.CacheManager
|
||||||
|
import dev.usbharu.hideout.core.service.resource.ResolveResponse
|
||||||
import org.springframework.stereotype.Service
|
import org.springframework.stereotype.Service
|
||||||
|
import java.io.InputStream
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
class APResourceResolveServiceImpl(
|
class APResourceResolveServiceImpl(
|
||||||
|
|
@ -25,7 +28,7 @@ class APResourceResolveServiceImpl(
|
||||||
cacheManager.putCache(key) {
|
cacheManager.putCache(key) {
|
||||||
runResolve(url, singerId?.let { userRepository.findById(it) }, clazz)
|
runResolve(url, singerId?.let { userRepository.findById(it) }, clazz)
|
||||||
}
|
}
|
||||||
return cacheManager.getOrWait(key) as T
|
return (cacheManager.getOrWait(key) as APResolveResponse<T>).objects
|
||||||
}
|
}
|
||||||
|
|
||||||
private suspend fun <T : Object> internalResolve(url: String, singer: User?, clazz: Class<T>): T {
|
private suspend fun <T : Object> internalResolve(url: String, singer: User?, clazz: Class<T>): T {
|
||||||
|
|
@ -33,11 +36,12 @@ class APResourceResolveServiceImpl(
|
||||||
cacheManager.putCache(key) {
|
cacheManager.putCache(key) {
|
||||||
runResolve(url, singer, clazz)
|
runResolve(url, singer, clazz)
|
||||||
}
|
}
|
||||||
return cacheManager.getOrWait(key) as T
|
return (cacheManager.getOrWait(key) as APResolveResponse<T>).objects
|
||||||
}
|
}
|
||||||
|
|
||||||
private suspend fun <T : Object> runResolve(url: String, singer: User?, clazz: Class<T>): Object =
|
private suspend fun <T : Object> runResolve(url: String, singer: User?, clazz: Class<T>): ResolveResponse {
|
||||||
apRequestService.apGet(url, singer, clazz)
|
return APResolveResponse(apRequestService.apGet(url, singer, clazz))
|
||||||
|
}
|
||||||
|
|
||||||
private fun genCacheKey(url: String, singerId: Long?): String {
|
private fun genCacheKey(url: String, singerId: Long?): String {
|
||||||
if (singerId != null) {
|
if (singerId != null) {
|
||||||
|
|
@ -45,4 +49,30 @@ class APResourceResolveServiceImpl(
|
||||||
}
|
}
|
||||||
return url
|
return url
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private class APResolveResponse<T : Object>(val objects: T) : ResolveResponse {
|
||||||
|
override suspend fun body(): InputStream {
|
||||||
|
TODO("Not yet implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun bodyAsText(): String {
|
||||||
|
TODO("Not yet implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun bodyAsBytes(): ByteArray {
|
||||||
|
TODO("Not yet implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun header(): Map<String, List<String>> {
|
||||||
|
TODO("Not yet implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun status(): Int {
|
||||||
|
TODO("Not yet implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun statusMessage(): String {
|
||||||
|
TODO("Not yet implemented")
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,9 +0,0 @@
|
||||||
package dev.usbharu.hideout.activitypub.service.common
|
|
||||||
|
|
||||||
import dev.usbharu.hideout.activitypub.domain.model.objects.Object
|
|
||||||
|
|
||||||
interface CacheManager {
|
|
||||||
|
|
||||||
suspend fun putCache(key: String, block: suspend () -> Object)
|
|
||||||
suspend fun getOrWait(key: String): Object
|
|
||||||
}
|
|
||||||
|
|
@ -124,7 +124,8 @@ class APUserServiceImpl(
|
||||||
?: throw IllegalActivityPubObjectException("publicKey is null"),
|
?: throw IllegalActivityPubObjectException("publicKey is null"),
|
||||||
keyId = person.publicKey?.id ?: throw IllegalActivityPubObjectException("publicKey keyId is null"),
|
keyId = person.publicKey?.id ?: throw IllegalActivityPubObjectException("publicKey keyId is null"),
|
||||||
following = person.following,
|
following = person.following,
|
||||||
followers = person.followers
|
followers = person.followers,
|
||||||
|
sharedInbox = person.endpoints["sharedInbox"]
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
package dev.usbharu.hideout.core.domain.model.instance
|
||||||
|
|
||||||
|
import java.time.Instant
|
||||||
|
|
||||||
|
data class Instance(
|
||||||
|
val id: Long,
|
||||||
|
val name: String,
|
||||||
|
val description: String,
|
||||||
|
val url: String,
|
||||||
|
val iconUrl: String,
|
||||||
|
val sharedInbox: String?,
|
||||||
|
val software: String,
|
||||||
|
val version: String,
|
||||||
|
val isBlocked: Boolean,
|
||||||
|
val isMuted: Boolean,
|
||||||
|
val moderationNote: String,
|
||||||
|
val createdAt: Instant
|
||||||
|
)
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
package dev.usbharu.hideout.core.domain.model.instance
|
||||||
|
|
||||||
|
interface InstanceRepository {
|
||||||
|
suspend fun generateId(): Long
|
||||||
|
suspend fun save(instance: Instance): Instance
|
||||||
|
suspend fun findById(id: Long): Instance
|
||||||
|
suspend fun delete(instance: Instance)
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
package dev.usbharu.hideout.core.domain.model.instance
|
||||||
|
|
||||||
|
class Nodeinfo {
|
||||||
|
|
||||||
|
var links: List<Links> = emptyList()
|
||||||
|
|
||||||
|
private constructor()
|
||||||
|
}
|
||||||
|
|
||||||
|
class Links {
|
||||||
|
var rel: String? = null
|
||||||
|
var href: String? = null
|
||||||
|
|
||||||
|
private constructor()
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,23 @@
|
||||||
|
package dev.usbharu.hideout.core.domain.model.instance
|
||||||
|
|
||||||
|
@Suppress("ClassNaming")
|
||||||
|
class Nodeinfo2_0 {
|
||||||
|
var metadata: Metadata? = null
|
||||||
|
var software: Software? = null
|
||||||
|
|
||||||
|
constructor()
|
||||||
|
}
|
||||||
|
|
||||||
|
class Metadata {
|
||||||
|
var nodeName: String? = null
|
||||||
|
var nodeDescription: String? = null
|
||||||
|
|
||||||
|
constructor()
|
||||||
|
}
|
||||||
|
|
||||||
|
class Software {
|
||||||
|
var name: String? = null
|
||||||
|
var version: String? = null
|
||||||
|
|
||||||
|
constructor()
|
||||||
|
}
|
||||||
|
|
@ -21,16 +21,18 @@ data class User private constructor(
|
||||||
val createdAt: Instant,
|
val createdAt: Instant,
|
||||||
val keyId: String,
|
val keyId: String,
|
||||||
val followers: String? = null,
|
val followers: String? = null,
|
||||||
val following: String? = null
|
val following: String? = null,
|
||||||
|
val instance: Long? = null
|
||||||
) {
|
) {
|
||||||
override fun toString(): String =
|
override fun toString(): String =
|
||||||
"User(id=$id, name='$name', domain='$domain', screenName='$screenName', description='$description'," +
|
"User(id=$id, name='$name', domain='$domain', screenName='$screenName', description='$description'," +
|
||||||
" password=$password, inbox='$inbox', outbox='$outbox', url='$url', publicKey='$publicKey'," +
|
" password=$password, inbox='$inbox', outbox='$outbox', url='$url', publicKey='$publicKey', " +
|
||||||
" privateKey=$privateKey, createdAt=$createdAt, keyId='$keyId', followers=$followers," +
|
"privateKey=$privateKey, createdAt=$createdAt, keyId='$keyId', followers=$followers," +
|
||||||
" following=$following)"
|
" following=$following, instance=$instance)"
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
class UserBuilder(private val characterLimit: CharacterLimit, private val applicationConfig: ApplicationConfig) {
|
class UserBuilder(private val characterLimit: CharacterLimit, private val applicationConfig: ApplicationConfig) {
|
||||||
|
|
||||||
private val logger = LoggerFactory.getLogger(UserBuilder::class.java)
|
private val logger = LoggerFactory.getLogger(UserBuilder::class.java)
|
||||||
|
|
||||||
@Suppress("LongParameterList", "FunctionMinLength", "LongMethod")
|
@Suppress("LongParameterList", "FunctionMinLength", "LongMethod")
|
||||||
|
|
@ -49,7 +51,8 @@ data class User private constructor(
|
||||||
createdAt: Instant,
|
createdAt: Instant,
|
||||||
keyId: String,
|
keyId: String,
|
||||||
following: String? = null,
|
following: String? = null,
|
||||||
followers: String? = null
|
followers: String? = null,
|
||||||
|
instance: Long? = null
|
||||||
): User {
|
): User {
|
||||||
// idは0未満ではいけない
|
// idは0未満ではいけない
|
||||||
require(id >= 0) { "id must be greater than or equal to 0." }
|
require(id >= 0) { "id must be greater than or equal to 0." }
|
||||||
|
|
@ -141,7 +144,8 @@ data class User private constructor(
|
||||||
createdAt = createdAt,
|
createdAt = createdAt,
|
||||||
keyId = keyId,
|
keyId = keyId,
|
||||||
followers = followers,
|
followers = followers,
|
||||||
following = following
|
following = following,
|
||||||
|
instance = instance
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,8 @@ class UserResultRowMapper(private val userBuilder: User.UserBuilder) : ResultRow
|
||||||
createdAt = Instant.ofEpochMilli((resultRow[Users.createdAt])),
|
createdAt = Instant.ofEpochMilli((resultRow[Users.createdAt])),
|
||||||
keyId = resultRow[Users.keyId],
|
keyId = resultRow[Users.keyId],
|
||||||
followers = resultRow[Users.followers],
|
followers = resultRow[Users.followers],
|
||||||
following = resultRow[Users.following]
|
following = resultRow[Users.following],
|
||||||
|
instance = resultRow[Users.instance]
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,8 @@ class FollowerQueryServiceImpl(private val userBuilder: User.UserBuilder) : Foll
|
||||||
followers[Users.createdAt],
|
followers[Users.createdAt],
|
||||||
followers[Users.keyId],
|
followers[Users.keyId],
|
||||||
followers[Users.following],
|
followers[Users.following],
|
||||||
followers[Users.followers]
|
followers[Users.followers],
|
||||||
|
followers[Users.instance]
|
||||||
)
|
)
|
||||||
.select { Users.id eq id }
|
.select { Users.id eq id }
|
||||||
.map {
|
.map {
|
||||||
|
|
@ -57,7 +58,8 @@ class FollowerQueryServiceImpl(private val userBuilder: User.UserBuilder) : Foll
|
||||||
createdAt = Instant.ofEpochMilli(it[followers[Users.createdAt]]),
|
createdAt = Instant.ofEpochMilli(it[followers[Users.createdAt]]),
|
||||||
keyId = it[followers[Users.keyId]],
|
keyId = it[followers[Users.keyId]],
|
||||||
followers = it[followers[Users.followers]],
|
followers = it[followers[Users.followers]],
|
||||||
following = it[followers[Users.following]]
|
following = it[followers[Users.following]],
|
||||||
|
instance = it[followers[Users.instance]]
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -89,7 +91,8 @@ class FollowerQueryServiceImpl(private val userBuilder: User.UserBuilder) : Foll
|
||||||
followers[Users.createdAt],
|
followers[Users.createdAt],
|
||||||
followers[Users.keyId],
|
followers[Users.keyId],
|
||||||
followers[Users.following],
|
followers[Users.following],
|
||||||
followers[Users.followers]
|
followers[Users.followers],
|
||||||
|
followers[Users.instance]
|
||||||
)
|
)
|
||||||
.select { Users.name eq name and (Users.domain eq domain) }
|
.select { Users.name eq name and (Users.domain eq domain) }
|
||||||
.map {
|
.map {
|
||||||
|
|
@ -108,7 +111,8 @@ class FollowerQueryServiceImpl(private val userBuilder: User.UserBuilder) : Foll
|
||||||
createdAt = Instant.ofEpochMilli(it[followers[Users.createdAt]]),
|
createdAt = Instant.ofEpochMilli(it[followers[Users.createdAt]]),
|
||||||
keyId = it[followers[Users.keyId]],
|
keyId = it[followers[Users.keyId]],
|
||||||
followers = it[followers[Users.followers]],
|
followers = it[followers[Users.followers]],
|
||||||
following = it[followers[Users.following]]
|
following = it[followers[Users.following]],
|
||||||
|
instance = it[followers[Users.instance]]
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -140,7 +144,8 @@ class FollowerQueryServiceImpl(private val userBuilder: User.UserBuilder) : Foll
|
||||||
followers[Users.createdAt],
|
followers[Users.createdAt],
|
||||||
followers[Users.keyId],
|
followers[Users.keyId],
|
||||||
followers[Users.following],
|
followers[Users.following],
|
||||||
followers[Users.followers]
|
followers[Users.followers],
|
||||||
|
followers[Users.instance]
|
||||||
)
|
)
|
||||||
.select { followers[Users.id] eq id }
|
.select { followers[Users.id] eq id }
|
||||||
.map {
|
.map {
|
||||||
|
|
@ -159,7 +164,8 @@ class FollowerQueryServiceImpl(private val userBuilder: User.UserBuilder) : Foll
|
||||||
createdAt = Instant.ofEpochMilli(it[followers[Users.createdAt]]),
|
createdAt = Instant.ofEpochMilli(it[followers[Users.createdAt]]),
|
||||||
keyId = it[followers[Users.keyId]],
|
keyId = it[followers[Users.keyId]],
|
||||||
followers = it[followers[Users.followers]],
|
followers = it[followers[Users.followers]],
|
||||||
following = it[followers[Users.following]]
|
following = it[followers[Users.following]],
|
||||||
|
instance = it[followers[Users.instance]]
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -191,7 +197,8 @@ class FollowerQueryServiceImpl(private val userBuilder: User.UserBuilder) : Foll
|
||||||
followers[Users.createdAt],
|
followers[Users.createdAt],
|
||||||
followers[Users.keyId],
|
followers[Users.keyId],
|
||||||
followers[Users.following],
|
followers[Users.following],
|
||||||
followers[Users.followers]
|
followers[Users.followers],
|
||||||
|
followers[Users.instance]
|
||||||
)
|
)
|
||||||
.select { followers[Users.name] eq name and (followers[Users.domain] eq domain) }
|
.select { followers[Users.name] eq name and (followers[Users.domain] eq domain) }
|
||||||
.map {
|
.map {
|
||||||
|
|
@ -210,7 +217,8 @@ class FollowerQueryServiceImpl(private val userBuilder: User.UserBuilder) : Foll
|
||||||
createdAt = Instant.ofEpochMilli(it[followers[Users.createdAt]]),
|
createdAt = Instant.ofEpochMilli(it[followers[Users.createdAt]]),
|
||||||
keyId = it[followers[Users.keyId]],
|
keyId = it[followers[Users.keyId]],
|
||||||
followers = it[followers[Users.followers]],
|
followers = it[followers[Users.followers]],
|
||||||
following = it[followers[Users.following]]
|
following = it[followers[Users.following]],
|
||||||
|
instance = it[followers[Users.instance]]
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,16 @@
|
||||||
|
package dev.usbharu.hideout.core.infrastructure.exposedquery
|
||||||
|
|
||||||
|
import dev.usbharu.hideout.core.domain.exception.FailedToGetResourcesException
|
||||||
|
import dev.usbharu.hideout.core.infrastructure.exposedrepository.Instance
|
||||||
|
import dev.usbharu.hideout.core.infrastructure.exposedrepository.toInstance
|
||||||
|
import dev.usbharu.hideout.core.query.InstanceQueryService
|
||||||
|
import dev.usbharu.hideout.util.singleOr
|
||||||
|
import org.jetbrains.exposed.sql.select
|
||||||
|
import org.springframework.stereotype.Repository
|
||||||
|
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()
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,93 @@
|
||||||
|
package dev.usbharu.hideout.core.infrastructure.exposedrepository
|
||||||
|
|
||||||
|
import dev.usbharu.hideout.application.service.id.IdGenerateService
|
||||||
|
import dev.usbharu.hideout.core.domain.exception.FailedToGetResourcesException
|
||||||
|
import dev.usbharu.hideout.core.domain.model.instance.InstanceRepository
|
||||||
|
import dev.usbharu.hideout.util.singleOr
|
||||||
|
import org.jetbrains.exposed.sql.*
|
||||||
|
import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq
|
||||||
|
import org.jetbrains.exposed.sql.javatime.timestamp
|
||||||
|
import org.springframework.stereotype.Repository
|
||||||
|
import dev.usbharu.hideout.core.domain.model.instance.Instance as InstanceEntity
|
||||||
|
|
||||||
|
@Repository
|
||||||
|
class InstanceRepositoryImpl(private val idGenerateService: IdGenerateService) : InstanceRepository {
|
||||||
|
override suspend fun generateId(): Long = idGenerateService.generateId()
|
||||||
|
|
||||||
|
override suspend fun save(instance: InstanceEntity): InstanceEntity {
|
||||||
|
if (Instance.select { Instance.id.eq(instance.id) }.empty()) {
|
||||||
|
Instance.insert {
|
||||||
|
it[id] = instance.id
|
||||||
|
it[name] = instance.name
|
||||||
|
it[description] = instance.description
|
||||||
|
it[url] = instance.url
|
||||||
|
it[iconUrl] = instance.iconUrl
|
||||||
|
it[sharedInbox] = instance.sharedInbox
|
||||||
|
it[software] = instance.software
|
||||||
|
it[version] = instance.version
|
||||||
|
it[isBlocked] = instance.isBlocked
|
||||||
|
it[isMuted] = instance.isMuted
|
||||||
|
it[moderationNote] = instance.moderationNote
|
||||||
|
it[createdAt] = instance.createdAt
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Instance.update({ Instance.id eq instance.id }) {
|
||||||
|
it[name] = instance.name
|
||||||
|
it[description] = instance.description
|
||||||
|
it[url] = instance.url
|
||||||
|
it[iconUrl] = instance.iconUrl
|
||||||
|
it[sharedInbox] = instance.sharedInbox
|
||||||
|
it[software] = instance.software
|
||||||
|
it[version] = instance.version
|
||||||
|
it[isBlocked] = instance.isBlocked
|
||||||
|
it[isMuted] = instance.isMuted
|
||||||
|
it[moderationNote] = instance.moderationNote
|
||||||
|
it[createdAt] = instance.createdAt
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return instance
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun findById(id: Long): InstanceEntity {
|
||||||
|
return Instance.select { Instance.id eq id }
|
||||||
|
.singleOr { FailedToGetResourcesException("id: $id doesn't exist.") }.toInstance()
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun delete(instance: InstanceEntity) {
|
||||||
|
Instance.deleteWhere { Instance.id eq instance.id }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun ResultRow.toInstance(): InstanceEntity {
|
||||||
|
return InstanceEntity(
|
||||||
|
id = this[Instance.id],
|
||||||
|
name = this[Instance.name],
|
||||||
|
description = this[Instance.description],
|
||||||
|
url = this[Instance.url],
|
||||||
|
iconUrl = this[Instance.iconUrl],
|
||||||
|
sharedInbox = this[Instance.sharedInbox],
|
||||||
|
software = this[Instance.software],
|
||||||
|
version = this[Instance.version],
|
||||||
|
isBlocked = this[Instance.isBlocked],
|
||||||
|
isMuted = this[Instance.isMuted],
|
||||||
|
moderationNote = this[Instance.moderationNote],
|
||||||
|
createdAt = this[Instance.createdAt]
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
object Instance : Table("instance") {
|
||||||
|
val id = long("id")
|
||||||
|
val name = varchar("name", 1000)
|
||||||
|
val description = varchar("description", 5000)
|
||||||
|
val url = varchar("url", 255)
|
||||||
|
val iconUrl = varchar("icon_url", 255)
|
||||||
|
val sharedInbox = varchar("shared_inbox", 255).nullable()
|
||||||
|
val software = varchar("software", 255)
|
||||||
|
val version = varchar("version", 255)
|
||||||
|
val isBlocked = bool("is_blocked")
|
||||||
|
val isMuted = bool("is_muted")
|
||||||
|
val moderationNote = varchar("moderation_note", 10000)
|
||||||
|
val createdAt = timestamp("created_at")
|
||||||
|
|
||||||
|
override val primaryKey: PrimaryKey = PrimaryKey(id)
|
||||||
|
}
|
||||||
|
|
@ -75,20 +75,20 @@ class PostRepositoryImpl(
|
||||||
|
|
||||||
object Posts : Table() {
|
object Posts : Table() {
|
||||||
val id: Column<Long> = long("id")
|
val id: Column<Long> = long("id")
|
||||||
val userId: Column<Long> = long("userId").references(Users.id)
|
val userId: Column<Long> = long("user_id").references(Users.id)
|
||||||
val overview: Column<String?> = varchar("overview", 100).nullable()
|
val overview: Column<String?> = varchar("overview", 100).nullable()
|
||||||
val text: Column<String> = varchar("text", 3000)
|
val text: Column<String> = varchar("text", 3000)
|
||||||
val createdAt: Column<Long> = long("createdAt")
|
val createdAt: Column<Long> = long("created_at")
|
||||||
val visibility: Column<Int> = integer("visibility").default(0)
|
val visibility: Column<Int> = integer("visibility").default(0)
|
||||||
val url: Column<String> = varchar("url", 500)
|
val url: Column<String> = varchar("url", 500)
|
||||||
val repostId: Column<Long?> = long("repostId").references(id).nullable()
|
val repostId: Column<Long?> = long("repost_id").references(id).nullable()
|
||||||
val replyId: Column<Long?> = long("replyId").references(id).nullable()
|
val replyId: Column<Long?> = long("reply_id").references(id).nullable()
|
||||||
val sensitive: Column<Boolean> = bool("sensitive").default(false)
|
val sensitive: Column<Boolean> = bool("sensitive").default(false)
|
||||||
val apId: Column<String> = varchar("ap_id", 100).uniqueIndex()
|
val apId: Column<String> = varchar("ap_id", 100).uniqueIndex()
|
||||||
override val primaryKey: PrimaryKey = PrimaryKey(id)
|
override val primaryKey: PrimaryKey = PrimaryKey(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
object PostsMedia : Table() {
|
object PostsMedia : Table("posts_media") {
|
||||||
val postId = long("post_id").references(Posts.id, ReferenceOption.CASCADE, ReferenceOption.CASCADE)
|
val postId = long("post_id").references(Posts.id, ReferenceOption.CASCADE, ReferenceOption.CASCADE)
|
||||||
val mediaId = long("media_id").references(Media.id, ReferenceOption.CASCADE, ReferenceOption.CASCADE)
|
val mediaId = long("media_id").references(Media.id, ReferenceOption.CASCADE, ReferenceOption.CASCADE)
|
||||||
override val primaryKey = PrimaryKey(postId, mediaId)
|
override val primaryKey = PrimaryKey(postId, mediaId)
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,7 @@ class UserRepositoryImpl(
|
||||||
it[keyId] = user.keyId
|
it[keyId] = user.keyId
|
||||||
it[following] = user.following
|
it[following] = user.following
|
||||||
it[followers] = user.followers
|
it[followers] = user.followers
|
||||||
|
it[instance] = user.instance
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Users.update({ Users.id eq user.id }) {
|
Users.update({ Users.id eq user.id }) {
|
||||||
|
|
@ -52,6 +53,7 @@ class UserRepositoryImpl(
|
||||||
it[keyId] = user.keyId
|
it[keyId] = user.keyId
|
||||||
it[following] = user.following
|
it[following] = user.following
|
||||||
it[followers] = user.followers
|
it[followers] = user.followers
|
||||||
|
it[instance] = user.instance
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return user
|
return user
|
||||||
|
|
@ -98,6 +100,7 @@ object Users : Table("users") {
|
||||||
val keyId = varchar("key_id", length = 1000)
|
val keyId = varchar("key_id", length = 1000)
|
||||||
val following = varchar("following", length = 1000).nullable()
|
val following = varchar("following", length = 1000).nullable()
|
||||||
val followers = varchar("followers", length = 1000).nullable()
|
val followers = varchar("followers", length = 1000).nullable()
|
||||||
|
val instance = long("instance").references(Instance.id).nullable()
|
||||||
|
|
||||||
override val primaryKey: PrimaryKey = PrimaryKey(id)
|
override val primaryKey: PrimaryKey = PrimaryKey(id)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
package dev.usbharu.hideout.core.query
|
||||||
|
|
||||||
|
import dev.usbharu.hideout.core.domain.model.instance.Instance
|
||||||
|
|
||||||
|
interface InstanceQueryService {
|
||||||
|
suspend fun findByUrl(url: String): Instance
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
package dev.usbharu.hideout.core.service.instance
|
||||||
|
|
||||||
|
data class InstanceCreateDto(
|
||||||
|
val name: String?,
|
||||||
|
val description: String?,
|
||||||
|
val url: String,
|
||||||
|
val iconUrl: String,
|
||||||
|
val sharedInbox: String?,
|
||||||
|
val software: String?,
|
||||||
|
val version: String?,
|
||||||
|
)
|
||||||
|
|
@ -0,0 +1,114 @@
|
||||||
|
package dev.usbharu.hideout.core.service.instance
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper
|
||||||
|
import dev.usbharu.hideout.core.domain.exception.FailedToGetResourcesException
|
||||||
|
import dev.usbharu.hideout.core.domain.model.instance.Instance
|
||||||
|
import dev.usbharu.hideout.core.domain.model.instance.InstanceRepository
|
||||||
|
import dev.usbharu.hideout.core.domain.model.instance.Nodeinfo
|
||||||
|
import dev.usbharu.hideout.core.domain.model.instance.Nodeinfo2_0
|
||||||
|
import dev.usbharu.hideout.core.query.InstanceQueryService
|
||||||
|
import dev.usbharu.hideout.core.service.resource.ResourceResolveService
|
||||||
|
import org.slf4j.LoggerFactory
|
||||||
|
import org.springframework.beans.factory.annotation.Qualifier
|
||||||
|
import org.springframework.stereotype.Service
|
||||||
|
import java.net.URL
|
||||||
|
import java.time.Instant
|
||||||
|
|
||||||
|
interface InstanceService {
|
||||||
|
suspend fun fetchInstance(url: String, sharedInbox: String? = null): Instance
|
||||||
|
suspend fun createNewInstance(instanceCreateDto: InstanceCreateDto): Instance
|
||||||
|
}
|
||||||
|
|
||||||
|
@Service
|
||||||
|
class InstanceServiceImpl(
|
||||||
|
private val instanceRepository: InstanceRepository,
|
||||||
|
private val resourceResolveService: ResourceResolveService,
|
||||||
|
@Qualifier("activitypub") private val objectMapper: ObjectMapper,
|
||||||
|
private val instanceQueryService: InstanceQueryService
|
||||||
|
) : InstanceService {
|
||||||
|
override suspend fun fetchInstance(url: String, sharedInbox: String?): Instance {
|
||||||
|
val u = URL(url)
|
||||||
|
val resolveInstanceUrl = u.protocol + "://" + u.host
|
||||||
|
|
||||||
|
try {
|
||||||
|
return instanceQueryService.findByUrl(url)
|
||||||
|
} catch (e: FailedToGetResourcesException) {
|
||||||
|
logger.info("Instance not found. try fetch instance info. url: {}", resolveInstanceUrl)
|
||||||
|
logger.debug("Failed to get resources. url: {}", resolveInstanceUrl, e)
|
||||||
|
}
|
||||||
|
|
||||||
|
val nodeinfoJson = resourceResolveService.resolve("$resolveInstanceUrl/.well-known/nodeinfo").bodyAsText()
|
||||||
|
val nodeinfo = objectMapper.readValue(nodeinfoJson, Nodeinfo::class.java)
|
||||||
|
val nodeinfoPathMap = nodeinfo.links.associate { it.rel to it.href }
|
||||||
|
|
||||||
|
for ((key, value) in nodeinfoPathMap) {
|
||||||
|
when (key) {
|
||||||
|
"http://nodeinfo.diaspora.software/ns/schema/2.0" -> {
|
||||||
|
val nodeinfo20 = objectMapper.readValue(
|
||||||
|
resourceResolveService.resolve(value!!).bodyAsText(),
|
||||||
|
Nodeinfo2_0::class.java
|
||||||
|
)
|
||||||
|
|
||||||
|
val instanceCreateDto = InstanceCreateDto(
|
||||||
|
name = nodeinfo20.metadata?.nodeName,
|
||||||
|
description = nodeinfo20.metadata?.nodeDescription,
|
||||||
|
url = resolveInstanceUrl,
|
||||||
|
iconUrl = resolveInstanceUrl + "/favicon.ico",
|
||||||
|
sharedInbox = sharedInbox,
|
||||||
|
software = nodeinfo20.software?.name,
|
||||||
|
version = nodeinfo20.software?.version
|
||||||
|
)
|
||||||
|
return createNewInstance(instanceCreateDto)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: 多分2.0と2.1で互換性有るのでそのまま使うけどなおす
|
||||||
|
"http://nodeinfo.diaspora.software/ns/schema/2.1" -> {
|
||||||
|
val nodeinfo20 = objectMapper.readValue(
|
||||||
|
resourceResolveService.resolve(value!!).bodyAsText(),
|
||||||
|
Nodeinfo2_0::class.java
|
||||||
|
)
|
||||||
|
|
||||||
|
val instanceCreateDto = InstanceCreateDto(
|
||||||
|
name = nodeinfo20.metadata?.nodeName,
|
||||||
|
description = nodeinfo20.metadata?.nodeDescription,
|
||||||
|
url = resolveInstanceUrl,
|
||||||
|
iconUrl = resolveInstanceUrl + "/favicon.ico",
|
||||||
|
sharedInbox = sharedInbox,
|
||||||
|
software = nodeinfo20.software?.name,
|
||||||
|
version = nodeinfo20.software?.version
|
||||||
|
)
|
||||||
|
return createNewInstance(instanceCreateDto)
|
||||||
|
}
|
||||||
|
|
||||||
|
else -> {
|
||||||
|
TODO()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
throw IllegalStateException("Nodeinfo aren't found.")
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun createNewInstance(instanceCreateDto: InstanceCreateDto): Instance {
|
||||||
|
val instance = Instance(
|
||||||
|
id = instanceRepository.generateId(),
|
||||||
|
name = instanceCreateDto.name ?: instanceCreateDto.url,
|
||||||
|
description = instanceCreateDto.description.orEmpty(),
|
||||||
|
url = instanceCreateDto.url,
|
||||||
|
iconUrl = instanceCreateDto.iconUrl,
|
||||||
|
sharedInbox = instanceCreateDto.sharedInbox,
|
||||||
|
software = instanceCreateDto.software ?: "unknown",
|
||||||
|
version = instanceCreateDto.version ?: "unknown",
|
||||||
|
isBlocked = false,
|
||||||
|
isMuted = false,
|
||||||
|
moderationNote = "",
|
||||||
|
createdAt = Instant.now()
|
||||||
|
)
|
||||||
|
instanceRepository.save(instance)
|
||||||
|
return instance
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private val logger = LoggerFactory.getLogger(InstanceServiceImpl::class.java)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -24,7 +24,7 @@ open class MediaServiceImpl(
|
||||||
private val remoteMediaDownloadService: RemoteMediaDownloadService,
|
private val remoteMediaDownloadService: RemoteMediaDownloadService,
|
||||||
private val renameService: MediaFileRenameService
|
private val renameService: MediaFileRenameService
|
||||||
) : MediaService {
|
) : MediaService {
|
||||||
@Suppress("LongMethod")
|
@Suppress("LongMethod", "NestedBlockDepth")
|
||||||
override suspend fun uploadLocalMedia(mediaRequest: MediaRequest): EntityMedia {
|
override suspend fun uploadLocalMedia(mediaRequest: MediaRequest): EntityMedia {
|
||||||
val fileName = mediaRequest.file.name
|
val fileName = mediaRequest.file.name
|
||||||
logger.info(
|
logger.info(
|
||||||
|
|
@ -95,6 +95,7 @@ open class MediaServiceImpl(
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: 仮の処理として保存したように動かす
|
// TODO: 仮の処理として保存したように動かす
|
||||||
|
@Suppress("LongMethod", "NestedBlockDepth")
|
||||||
override suspend fun uploadRemoteMedia(remoteMedia: RemoteMedia): Media {
|
override suspend fun uploadRemoteMedia(remoteMedia: RemoteMedia): Media {
|
||||||
logger.info("MEDIA Remote media. filename:${remoteMedia.name} url:${remoteMedia.url}")
|
logger.info("MEDIA Remote media. filename:${remoteMedia.name} url:${remoteMedia.url}")
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,6 @@
|
||||||
|
package dev.usbharu.hideout.core.service.resource
|
||||||
|
|
||||||
|
interface CacheManager {
|
||||||
|
suspend fun putCache(key: String, block: suspend () -> ResolveResponse)
|
||||||
|
suspend fun getOrWait(key: String): ResolveResponse
|
||||||
|
}
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
package dev.usbharu.hideout.activitypub.service.common
|
package dev.usbharu.hideout.core.service.resource
|
||||||
|
|
||||||
import dev.usbharu.hideout.activitypub.domain.model.objects.Object
|
|
||||||
import dev.usbharu.hideout.util.LruCache
|
import dev.usbharu.hideout.util.LruCache
|
||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
import kotlinx.coroutines.sync.Mutex
|
import kotlinx.coroutines.sync.Mutex
|
||||||
|
|
@ -11,10 +10,10 @@ import java.time.Instant
|
||||||
@Service
|
@Service
|
||||||
class InMemoryCacheManager : CacheManager {
|
class InMemoryCacheManager : CacheManager {
|
||||||
private val cacheKey = LruCache<String, Long>(15)
|
private val cacheKey = LruCache<String, Long>(15)
|
||||||
private val valueStore = mutableMapOf<String, Object>()
|
private val valueStore = mutableMapOf<String, ResolveResponse>()
|
||||||
private val keyMutex = Mutex()
|
private val keyMutex = Mutex()
|
||||||
|
|
||||||
override suspend fun putCache(key: String, block: suspend () -> Object) {
|
override suspend fun putCache(key: String, block: suspend () -> ResolveResponse) {
|
||||||
val needRunBlock: Boolean
|
val needRunBlock: Boolean
|
||||||
keyMutex.withLock {
|
keyMutex.withLock {
|
||||||
cacheKey.filter { Instant.ofEpochMilli(it.value).plusSeconds(300) <= Instant.now() }
|
cacheKey.filter { Instant.ofEpochMilli(it.value).plusSeconds(300) <= Instant.now() }
|
||||||
|
|
@ -38,7 +37,7 @@ class InMemoryCacheManager : CacheManager {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun getOrWait(key: String): Object {
|
override suspend fun getOrWait(key: String): ResolveResponse {
|
||||||
while (valueStore.contains(key).not()) {
|
while (valueStore.contains(key).not()) {
|
||||||
if (cacheKey.containsKey(key).not()) {
|
if (cacheKey.containsKey(key).not()) {
|
||||||
throw IllegalStateException("Invalid cache key.")
|
throw IllegalStateException("Invalid cache key.")
|
||||||
|
|
@ -0,0 +1,31 @@
|
||||||
|
package dev.usbharu.hideout.core.service.resource
|
||||||
|
|
||||||
|
import io.ktor.client.statement.*
|
||||||
|
import io.ktor.util.*
|
||||||
|
import io.ktor.utils.io.jvm.javaio.*
|
||||||
|
import java.io.InputStream
|
||||||
|
|
||||||
|
class KtorResolveResponse(val ktorHttpResponse: HttpResponse) : ResolveResponse {
|
||||||
|
|
||||||
|
private lateinit var _bodyAsText: String
|
||||||
|
private lateinit var _bodyAsBytes: ByteArray
|
||||||
|
|
||||||
|
override suspend fun body(): InputStream = ktorHttpResponse.bodyAsChannel().toInputStream()
|
||||||
|
override suspend fun bodyAsText(): String {
|
||||||
|
if (!this::_bodyAsText.isInitialized) {
|
||||||
|
_bodyAsText = ktorHttpResponse.bodyAsText()
|
||||||
|
}
|
||||||
|
return _bodyAsText
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun bodyAsBytes(): ByteArray {
|
||||||
|
if (!this::_bodyAsBytes.isInitialized) {
|
||||||
|
_bodyAsBytes = ktorHttpResponse.readBytes()
|
||||||
|
}
|
||||||
|
return _bodyAsBytes
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun header(): Map<String, List<String>> = ktorHttpResponse.headers.toMap()
|
||||||
|
override suspend fun status(): Int = ktorHttpResponse.status.value
|
||||||
|
override suspend fun statusMessage(): String = ktorHttpResponse.status.description
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,24 @@
|
||||||
|
package dev.usbharu.hideout.core.service.resource
|
||||||
|
|
||||||
|
import io.ktor.client.*
|
||||||
|
import io.ktor.client.request.*
|
||||||
|
import org.springframework.stereotype.Service
|
||||||
|
|
||||||
|
@Service
|
||||||
|
open class KtorResourceResolveService(private val httpClient: HttpClient, private val cacheManager: CacheManager) :
|
||||||
|
ResourceResolveService {
|
||||||
|
override suspend fun resolve(url: String): ResolveResponse {
|
||||||
|
cacheManager.putCache(getCacheKey(url)) {
|
||||||
|
runResolve(url)
|
||||||
|
}
|
||||||
|
return cacheManager.getOrWait(getCacheKey(url))
|
||||||
|
}
|
||||||
|
|
||||||
|
protected suspend fun runResolve(url: String): ResolveResponse {
|
||||||
|
val httpResponse = httpClient.get(url)
|
||||||
|
|
||||||
|
return KtorResolveResponse(httpResponse)
|
||||||
|
}
|
||||||
|
|
||||||
|
protected suspend fun getCacheKey(url: String) = url
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,12 @@
|
||||||
|
package dev.usbharu.hideout.core.service.resource
|
||||||
|
|
||||||
|
import java.io.InputStream
|
||||||
|
|
||||||
|
interface ResolveResponse {
|
||||||
|
suspend fun body(): InputStream
|
||||||
|
suspend fun bodyAsText(): String
|
||||||
|
suspend fun bodyAsBytes(): ByteArray
|
||||||
|
suspend fun header(): Map<String, List<String>>
|
||||||
|
suspend fun status(): Int
|
||||||
|
suspend fun statusMessage(): String
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
package dev.usbharu.hideout.core.service.resource
|
||||||
|
|
||||||
|
interface ResourceResolveService {
|
||||||
|
suspend fun resolve(url: String): ResolveResponse
|
||||||
|
}
|
||||||
|
|
@ -11,5 +11,6 @@ data class RemoteUserCreateDto(
|
||||||
val publicKey: String,
|
val publicKey: String,
|
||||||
val keyId: String,
|
val keyId: String,
|
||||||
val followers: String?,
|
val followers: String?,
|
||||||
val following: String?
|
val following: String?,
|
||||||
|
val sharedInbox: String?
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,9 @@ import dev.usbharu.hideout.core.domain.model.user.UserRepository
|
||||||
import dev.usbharu.hideout.core.query.FollowerQueryService
|
import dev.usbharu.hideout.core.query.FollowerQueryService
|
||||||
import dev.usbharu.hideout.core.query.UserQueryService
|
import dev.usbharu.hideout.core.query.UserQueryService
|
||||||
import dev.usbharu.hideout.core.service.follow.SendFollowDto
|
import dev.usbharu.hideout.core.service.follow.SendFollowDto
|
||||||
|
import dev.usbharu.hideout.core.service.instance.InstanceService
|
||||||
import org.jetbrains.exposed.exceptions.ExposedSQLException
|
import org.jetbrains.exposed.exceptions.ExposedSQLException
|
||||||
|
import org.slf4j.LoggerFactory
|
||||||
import org.springframework.stereotype.Service
|
import org.springframework.stereotype.Service
|
||||||
import java.time.Instant
|
import java.time.Instant
|
||||||
|
|
||||||
|
|
@ -20,7 +22,8 @@ class UserServiceImpl(
|
||||||
private val userQueryService: UserQueryService,
|
private val userQueryService: UserQueryService,
|
||||||
private val followerQueryService: FollowerQueryService,
|
private val followerQueryService: FollowerQueryService,
|
||||||
private val userBuilder: User.UserBuilder,
|
private val userBuilder: User.UserBuilder,
|
||||||
private val applicationConfig: ApplicationConfig
|
private val applicationConfig: ApplicationConfig,
|
||||||
|
private val instanceService: InstanceService
|
||||||
) :
|
) :
|
||||||
UserService {
|
UserService {
|
||||||
|
|
||||||
|
|
@ -49,12 +52,20 @@ class UserServiceImpl(
|
||||||
createdAt = Instant.now(),
|
createdAt = Instant.now(),
|
||||||
following = "$userUrl/following",
|
following = "$userUrl/following",
|
||||||
followers = "$userUrl/followers",
|
followers = "$userUrl/followers",
|
||||||
keyId = "$userUrl#pubkey"
|
keyId = "$userUrl#pubkey",
|
||||||
|
instance = null
|
||||||
)
|
)
|
||||||
return userRepository.save(userEntity)
|
return userRepository.save(userEntity)
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun createRemoteUser(user: RemoteUserCreateDto): User {
|
override suspend fun createRemoteUser(user: RemoteUserCreateDto): User {
|
||||||
|
val instance = try {
|
||||||
|
instanceService.fetchInstance(user.url, user.sharedInbox)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
logger.warn("FAILED to fetch instance. url: {}", user.url, e)
|
||||||
|
null
|
||||||
|
}
|
||||||
|
|
||||||
val nextId = userRepository.nextId()
|
val nextId = userRepository.nextId()
|
||||||
val userEntity = userBuilder.of(
|
val userEntity = userBuilder.of(
|
||||||
id = nextId,
|
id = nextId,
|
||||||
|
|
@ -69,7 +80,8 @@ class UserServiceImpl(
|
||||||
createdAt = Instant.now(),
|
createdAt = Instant.now(),
|
||||||
followers = user.followers,
|
followers = user.followers,
|
||||||
following = user.following,
|
following = user.following,
|
||||||
keyId = user.keyId
|
keyId = user.keyId,
|
||||||
|
instance = instance?.id
|
||||||
)
|
)
|
||||||
return try {
|
return try {
|
||||||
userRepository.save(userEntity)
|
userRepository.save(userEntity)
|
||||||
|
|
@ -106,4 +118,8 @@ class UserServiceImpl(
|
||||||
followerQueryService.removeFollower(id, followerId)
|
followerQueryService.removeFollower(id, followerId)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private val logger = LoggerFactory.getLogger(UserServiceImpl::class.java)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ spring:
|
||||||
default-property-inclusion: always
|
default-property-inclusion: always
|
||||||
datasource:
|
datasource:
|
||||||
driver-class-name: org.h2.Driver
|
driver-class-name: org.h2.Driver
|
||||||
url: "jdbc:h2:./test-dev3;MODE=POSTGRESQL;TRACE_LEVEL_FILE=4"
|
url: "jdbc:h2:./test-dev4;MODE=POSTGRESQL;TRACE_LEVEL_FILE=4"
|
||||||
username: ""
|
username: ""
|
||||||
password: ""
|
password: ""
|
||||||
# data:
|
# data:
|
||||||
|
|
@ -37,9 +37,6 @@ spring:
|
||||||
h2:
|
h2:
|
||||||
console:
|
console:
|
||||||
enabled: true
|
enabled: true
|
||||||
exposed:
|
|
||||||
generate-ddl: true
|
|
||||||
excluded-packages: dev.usbharu.hideout.core.infrastructure.kjobexposed
|
|
||||||
server:
|
server:
|
||||||
tomcat:
|
tomcat:
|
||||||
basedir: tomcat
|
basedir: tomcat
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,188 @@
|
||||||
|
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
|
||||||
|
);
|
||||||
|
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
|
||||||
|
);
|
||||||
|
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
|
||||||
|
);
|
||||||
|
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
|
||||||
|
);
|
||||||
|
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
|
||||||
|
);
|
||||||
|
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
|
||||||
|
);
|
||||||
|
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)
|
||||||
|
);
|
||||||
|
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
|
||||||
|
);
|
||||||
|
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
|
||||||
|
);
|
||||||
|
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
|
||||||
|
);
|
||||||
|
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
|
||||||
|
);
|
||||||
|
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)
|
||||||
|
);
|
||||||
|
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
|
||||||
|
)
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
package dev.usbharu.hideout.activitypub.service.common
|
package dev.usbharu.hideout.activitypub.service.common
|
||||||
|
|
||||||
import dev.usbharu.hideout.core.domain.model.user.UserRepository
|
import dev.usbharu.hideout.core.domain.model.user.UserRepository
|
||||||
|
import dev.usbharu.hideout.core.service.resource.InMemoryCacheManager
|
||||||
import kotlinx.coroutines.async
|
import kotlinx.coroutines.async
|
||||||
import kotlinx.coroutines.awaitAll
|
import kotlinx.coroutines.awaitAll
|
||||||
import kotlinx.coroutines.test.runTest
|
import kotlinx.coroutines.test.runTest
|
||||||
|
|
|
||||||
|
|
@ -41,6 +41,7 @@ class UserServiceTest {
|
||||||
mock(),
|
mock(),
|
||||||
userBuilder,
|
userBuilder,
|
||||||
testApplicationConfig,
|
testApplicationConfig,
|
||||||
|
mock()
|
||||||
)
|
)
|
||||||
userService.createLocalUser(UserCreateDto("test", "testUser", "XXXXXXXXXXXXX", "test"))
|
userService.createLocalUser(UserCreateDto("test", "testUser", "XXXXXXXXXXXXX", "test"))
|
||||||
verify(userRepository, times(1)).save(any())
|
verify(userRepository, times(1)).save(any())
|
||||||
|
|
@ -67,7 +68,7 @@ class UserServiceTest {
|
||||||
onBlocking { nextId() } doReturn 113345L
|
onBlocking { nextId() } doReturn 113345L
|
||||||
}
|
}
|
||||||
val userService =
|
val userService =
|
||||||
UserServiceImpl(userRepository, mock(), mock(), mock(), mock(), userBuilder, testApplicationConfig)
|
UserServiceImpl(userRepository, mock(), mock(), mock(), mock(), userBuilder, testApplicationConfig, mock())
|
||||||
val user = RemoteUserCreateDto(
|
val user = RemoteUserCreateDto(
|
||||||
name = "test",
|
name = "test",
|
||||||
domain = "remote.example.com",
|
domain = "remote.example.com",
|
||||||
|
|
@ -79,7 +80,8 @@ class UserServiceTest {
|
||||||
publicKey = "-----BEGIN PUBLIC KEY-----...-----END PUBLIC KEY-----",
|
publicKey = "-----BEGIN PUBLIC KEY-----...-----END PUBLIC KEY-----",
|
||||||
keyId = "a",
|
keyId = "a",
|
||||||
following = "",
|
following = "",
|
||||||
followers = ""
|
followers = "",
|
||||||
|
sharedInbox = null
|
||||||
)
|
)
|
||||||
userService.createRemoteUser(user)
|
userService.createRemoteUser(user)
|
||||||
verify(userRepository, times(1)).save(any())
|
verify(userRepository, times(1)).save(any())
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue