315 Commits

Author SHA1 Message Date
usbharu 1ac8a93619 refactor: 使用されてないApplicationServiceを削除 2024-09-06 18:46:29 +09:00
usbharu a284f4359e test: TestActorFactory.ktをiconとbannerに対応 2024-09-06 18:45:11 +09:00
usbharu 3a49b2ce9a test: GetActorDetailApplicationServiceTest.ktを追加 2024-09-06 18:44:36 +09:00
usbharu 5ae4d1577a refactor: ifEmptyを使用するように 2024-09-06 18:44:10 +09:00
usbharu 20a762b8f4 Merge pull request #585 from usbharu/ssr-client
noscript用の簡易SSRクライアントを追加
2024-09-06 17:50:36 +09:00
usbharu da106a6922 style: fix lint 2024-09-06 17:47:11 +09:00
usbharu ee23ce8b82 Merge branch 'develop' into ssr-client 2024-09-06 17:42:38 +09:00
usbharu 4acc1653d1 fix: errorのときもindexになってしまうためerrorのときのみ除外するように 2024-09-06 17:42:06 +09:00
usbharu 4d86cc0e41 feat: レイアウト等を統一し、ヘッダーを追加 2024-09-06 17:41:27 +09:00
renovate[bot] 92b6418202 fix(deps): update dependency software.amazon.awssdk:s3 to v2.27.20 2024-09-05 22:51:06 +00:00
usbharu f86a224ed2 style: fix lint (CI) 2024-09-05 15:39:25 +00:00
usbharu 5036e01c89 style: fix lint (CI) 2024-09-05 15:35:56 +00:00
usbharu ed41c025cf Merge branch 'develop' into ssr-client 2024-09-06 00:30:28 +09:00
usbharu c8a8e77021 feat: OGP用のクラスを追加 2024-09-05 15:31:10 +09:00
usbharu 48d325deed feat: OGP用のクラスを追加 2024-09-05 14:15:45 +09:00
usbharu df6d2940ed feat: privateなときは登録フォームへのリンクを出さないように
登録自体はまだできる
2024-09-05 12:59:25 +09:00
usbharu aa34fb0370 feat: /auth配下をMastodonと統一 2024-09-05 12:33:53 +09:00
usbharu 7b77b097ca feat: ログイン用ページをMastodonと統一 2024-09-05 11:55:35 +09:00
renovate[bot] fc8cb156da fix(deps): update dependency software.amazon.awssdk:s3 to v2.27.19 2024-09-04 23:14:46 +00:00
usbharu 15cb1375c8 feat: 一部のnoscriptタグを削除 2024-09-04 19:12:42 +09:00
usbharu 4f9c431d9b feat: クエリパラメータでSSRを使用するかを切り替えれるように
SSRを使用するかの設定はセッショに保存され、次のアクセスから設定する必要はなくなる
サーバーはとりあえずSPA用のindexページを送信し、noscriptを検知してクエリパラメータ付きのページに遷移する
2024-09-04 18:55:10 +09:00
usbharu fec59ab622 fix: クエリパラメータのパラメータ名の形式を修正
fix #577
2024-09-04 16:50:27 +09:00
usbharu 975fd5160b feat: 投稿に直接返信できるように 2024-09-04 16:26:47 +09:00
usbharu 57afdcdd7b wip 2024-09-04 15:48:48 +09:00
renovate[bot] ec565039d1 fix(deps): update dependency org.mongodb:mongodb-driver-kotlin-coroutine to v5.1.4 2024-09-04 02:15:30 +00:00
renovate[bot] 4c5344426b fix(deps): update dependency software.amazon.awssdk:s3 to v2.27.18 2024-09-03 21:53:56 +00:00
renovate[bot] 0cf8185e50 fix(deps): update dependency org.flywaydb:flyway-database-postgresql to v10.17.3 2024-09-02 13:37:16 +00:00
renovate[bot] 140351f5e7 fix(deps): update dependency software.amazon.awssdk:s3 to v2.27.17 2024-08-31 02:11:05 +00:00
renovate[bot] 9c445fba8c chore(deps): update madrapps/jacoco-report action to v1.7.0 2024-08-30 20:10:25 +00:00
renovate[bot] 79a10a27fc fix(deps): update exposed to v0.54.0 2024-08-30 14:18:31 +00:00
renovate[bot] baba7e8c0e fix(deps): update dependency software.amazon.awssdk:s3 to v2.27.16 2024-08-29 22:35:59 +00:00
usbharu 0463ad6b69 wip 2024-08-29 14:02:16 +09:00
renovate[bot] c94bb81fb2 fix(deps): update protobuf to v4.28.0 2024-08-29 02:24:08 +00:00
renovate[bot] 8f3008b96c fix(deps): update dependency software.amazon.awssdk:s3 to v2.27.15 2024-08-28 23:26:44 +00:00
renovate[bot] e9bac27608 fix(deps): update dependency io.swagger.core.v3:swagger-annotations to v2.2.23 2024-08-28 12:14:00 +00:00
renovate[bot] 37de9ccd00 fix(deps): update dependency software.amazon.awssdk:s3 to v2.27.14 2024-08-28 01:46:45 +00:00
renovate[bot] efb07f5927 fix(deps): update protobuf to v4.27.4 2024-08-27 23:06:39 +00:00
usbharu 992cc18c62 feat: /users/:idを追加 2024-08-27 10:43:08 +09:00
renovate[bot] b7caf11e3e fix(deps): update dependency software.amazon.awssdk:s3 to v2.27.13 2024-08-27 00:41:27 +00:00
renovate[bot] f0d8ee979d chore(deps): update mongo docker tag to v7.0.14 2024-08-26 22:30:03 +00:00
usbharu c48694ab0b feat: /auth/sign_up を改良 2024-08-26 17:50:03 +09:00
usbharu 533582534f feat: messagesをホットリロードに対応 2024-08-26 17:47:41 +09:00
usbharu bd219b62e1 Merge pull request #568 from usbharu/develop-env
開発時の体験を向上
2024-08-26 15:51:02 +09:00
usbharu 92a9bbcfdb chore: GitHub ActionsでLinterの自動適用後に更にCIが起動するように 2024-08-26 15:47:22 +09:00
usbharu 623e56bb91 style: fix lint (CI) 2024-08-26 06:31:51 +00:00
usbharu 3b8156e16d chore: 開発時にホットリロード等ができるように 2024-08-26 15:24:12 +09:00
usbharu a60b709cb0 chore: .gitignoreにhttp-client.private.env.jsonを追加 2024-08-26 13:34:56 +09:00
usbharu 1115590ab2 chore: httpクライアントの整備
http-client.private.env.jsonを/api/v1/appsを実行した結果と以下の内容を合わせて作成することで使える
{
  "dev": {
    "client_id": "",
    "client_secret": "",
    "host": "localhost:8081"
  }
}
2024-08-26 13:34:20 +09:00
usbharu 456df222f2 feat: 設定ファイルの内容を自動的に生成するように 2024-08-26 13:32:00 +09:00
usbharu e054e47453 chore: 開発環境用の設定ファイルを追加 2024-08-24 18:21:13 +09:00
usbharu dd9749a536 Merge pull request #567 from usbharu/refactor
ログを改善
2024-08-24 15:49:15 +09:00
usbharu ac5d6800e1 style: fix lint (CI) 2024-08-24 04:22:10 +00:00
usbharu eed5e8a75a revert: MDCに対応してなかったので削除 2024-08-24 13:17:25 +09:00
usbharu 0c9faa509b feat: mdcを出力するように 2024-08-24 12:57:33 +09:00
usbharu e4947ce5a9 feat: ログを改善 2024-08-24 12:22:31 +09:00
usbharu 9b60099ad9 refactor: Thymeleafの警告をなくした 2024-08-24 12:13:21 +09:00
usbharu 7362d20565 fix: 起動しなかったので修正 2024-08-24 12:04:47 +09:00
usbharu 457b6a12be refactor: userdetailのtoStringを改良 2024-08-24 12:04:31 +09:00
usbharu c872a837eb refactor: SnowflakeIdGenerateServiceを改良 2024-08-24 11:31:36 +09:00
usbharu 4dcec9e806 Merge pull request #562 from usbharu/subscriber
Subscriberの初期化をinit関数でするように
2024-08-24 11:07:49 +09:00
usbharu 8e0aedf0db Merge branch 'develop' into subscriber 2024-08-24 11:03:23 +09:00
renovate[bot] 406668e958 fix(deps): update dependency software.amazon.awssdk:s3 to v2.27.12 2024-08-24 02:01:28 +00:00
usbharu 9663cba4af style: fix lint (CI) 2024-08-24 02:00:49 +00:00
usbharu e2c633a917 feat: init関数を使用して初期化するように 2024-08-24 10:54:16 +09:00
usbharu d5805089f5 feat: Subscriberにinit関数を追加 2024-08-24 10:53:44 +09:00
usbharu f9c10eeb7a Merge pull request #561 from usbharu/detekt
Detektをhideout-mastodonにも適用するように
2024-08-24 00:32:04 +09:00
usbharu 896e7de1ec style: fix lint (CI) 2024-08-23 15:20:28 +00:00
usbharu 486268609b Merge branch 'develop' into detekt 2024-08-24 00:16:19 +09:00
usbharu 2f0b5915fc Merge pull request #558 from usbharu/fix-actor-url
Actorのurlを修正 MediaにオーナーのActorIdを追加
2024-08-24 00:13:03 +09:00
usbharu ca92ce71b6 chore: hideout-mastodonもチェックするように 2024-08-24 00:11:54 +09:00
usbharu de56fa0547 style: fix lint 2024-08-23 23:56:47 +09:00
usbharu da1235f95c chore: hideout-mastodonにDetektを追加 2024-08-23 23:51:25 +09:00
usbharu fd0d6b9625 style: fix lint 2024-08-23 23:39:27 +09:00
usbharu 76abc69c6c style: fix lint (CI) 2024-08-23 13:49:15 +00:00
usbharu e15380c96c feat: MediaにオーナーのActorIdを追加 2024-08-23 22:43:11 +09:00
usbharu aa476256ac Merge branch 'develop' into fix-actor-url 2024-08-23 22:28:40 +09:00
usbharu 7e8d066144 fix: Actorのurlがoutboxのurlとなっていたのを修正 2024-08-23 22:22:16 +09:00
usbharu e21552df97 Merge pull request #557 from usbharu/docker
docker-compose.ymlを整備
2024-08-23 22:20:14 +09:00
usbharu fb3f3ddd4b Merge branch 'develop' into docker 2024-08-23 22:15:46 +09:00
renovate[bot] d4b9b67f08 chore(deps): update plugin spring-boot to v3.3.3 2024-08-23 02:10:35 +00:00
renovate[bot] 1d131e71c5 fix(deps): update dependency software.amazon.awssdk:s3 to v2.27.11 2024-08-22 22:19:16 +00:00
renovate[bot] 7cb3a48e46 fix(deps): update dependency org.postgresql:postgresql to v42.7.4 2024-08-22 17:47:22 +00:00
renovate[bot] b3d4ad8546 fix(deps): update dependency org.flywaydb:flyway-database-postgresql to v10.17.2 2024-08-22 13:36:39 +00:00
renovate[bot] ddc559807a fix(deps): update dependency org.jetbrains.kotlin:kotlin-test-junit to v2.0.20 2024-08-22 08:58:25 +00:00
renovate[bot] 7120e82827 fix(deps): update dependency software.amazon.awssdk:s3 to v2.27.10 2024-08-21 21:32:49 +00:00
renovate[bot] 15b8e65d2d fix(deps): update dependency software.amazon.awssdk:s3 to v2.27.9 2024-08-21 01:18:05 +00:00
renovate[bot] 6758105394 fix(deps): update dependency software.amazon.awssdk:s3 to v2.27.8 2024-08-19 21:41:29 +00:00
renovate[bot] b248258808 chore(deps): update plugin openapi-generator to v7.8.0 2024-08-19 09:59:54 +00:00
usbharu 9efbf457a4 chore: docker-compose.ymlを整備 2024-08-18 16:59:09 +09:00
usbharu 65d8502a18 Merge pull request #547 from usbharu/timeline2
ホームタイムラインを見れるように
2024-08-17 20:09:26 +09:00
usbharu 29ff1269ce style: fix lint (CI) 2024-08-17 10:52:33 +00:00
usbharu 3105c6cf65 Merge branch 'develop' into timeline2 2024-08-17 19:49:05 +09:00
usbharu 11e2eb1e10 feat: ページングが動くように 2024-08-17 18:21:32 +09:00
renovate[bot] 3d638a4d63 fix(deps): update dependency software.amazon.awssdk:s3 to v2.27.7 2024-08-16 22:20:03 +00:00
renovate[bot] 77f72178dc fix(deps): update dependency software.amazon.awssdk:s3 to v2.27.6 2024-08-16 17:38:31 +00:00
usbharu d53cdca9e5 feat: ホームタイムラインが読めるように 2024-08-16 15:10:53 +09:00
usbharu e1787423e8 feat: 自分自身をホームタイムラインに追加するように 2024-08-16 15:02:32 +09:00
usbharu e9d776f71a feat: トランザクションの問題で正常にドメインイベントを受け取ったあとの処理を実行できなかった問題を修正 2024-08-16 14:25:26 +09:00
renovate[bot] 707e4aef65 chore(deps): update plugin license-report to v2.9 2024-08-15 20:31:52 +00:00
usbharu 8d244b74c1 feat: ローカルユーザー追加時に自動でホームタイムライン等を作成するように 2024-08-16 02:49:48 +09:00
usbharu 711084e366 feat: タイムラインを読めるように 2024-08-15 18:22:56 +09:00
renovate[bot] 31bee9b15a fix(deps): update dependency software.amazon.awssdk:s3 to v2.27.5 2024-08-15 04:33:21 +00:00
usbharu 88a61ba97f feat: タイムラインを読めるように 2024-08-15 00:02:26 +09:00
renovate[bot] 04a0059fb2 chore(deps): update dependency gradle to v8.10 2024-08-14 13:46:21 +00:00
renovate[bot] 1df1aae880 fix(deps): update dependency software.amazon.awssdk:s3 to v2.27.4 2024-08-13 23:38:38 +00:00
usbharu 60d71e1eb2 Merge pull request #539 from usbharu/ci-gradle
chore: ciを改善
2024-08-13 21:20:33 +09:00
usbharu 6c91b77eeb chore: no-daemon 2024-08-13 21:13:54 +09:00
usbharu f6fec05667 chore: detektの設定を更新 2024-08-13 21:09:31 +09:00
usbharu b2d59f619b chore: version catalogに統一 2024-08-13 21:06:59 +09:00
usbharu 6f11d1cd4e Merge branch 'develop' into ci-gradle 2024-08-13 20:17:38 +09:00
renovate[bot] c71ad2a28e fix(deps): update dependency org.flywaydb:flyway-database-postgresql to v10.17.1 2024-08-13 11:16:54 +00:00
usbharu 6d997e8012 style: fix lint (CI) 2024-08-13 11:16:14 +00:00
usbharu d5f08ef710 chore: ciを改善 2024-08-13 20:11:00 +09:00
usbharu 17bf2aade6 Merge pull request #536 from usbharu/ssr-front
OGPとnoscript時の簡易表示に対応
2024-08-13 15:48:33 +09:00
usbharu 4e8581ca94 test: 終わらないテストが発生したのでテストごと消した 2024-08-13 15:37:51 +09:00
usbharu 2db668e6ff Merge branch 'develop' into ssr-front 2024-08-13 14:26:14 +09:00
renovate[bot] 475efbe99a fix(deps): update dependency software.amazon.awssdk:s3 to v2.27.3 2024-08-13 03:35:22 +00:00
usbharu 91573c0b2e feat: 投稿フォームを追加 2024-08-13 12:31:02 +09:00
renovate[bot] 3794ac2d3c fix(deps): update dependency com.h2database:h2 to v2.3.232 2024-08-13 02:07:26 +00:00
usbharu 1fc6a1fa38 feat: wip 投稿フォーム作成 2024-08-12 23:22:38 +09:00
usbharu 2bc9b17cdc feat: 画像読み込みに対応 2024-08-12 22:13:16 +09:00
usbharu be07a89b7f feat: ogpに対応 2024-08-12 22:04:42 +09:00
usbharu f4d30e837e feat: 投稿詳細ページを作成 2024-08-12 21:38:07 +09:00
usbharu ced41e64fd fix: メディア付き投稿に失敗する問題を修正 2024-08-12 13:28:03 +09:00
usbharu 42b9d4e64b Merge pull request #532 from usbharu/auth3
Mastodon APIから利用されるQuery Service等にも認可処理を追加
2024-08-11 18:13:51 +09:00
usbharu 7f1f566924 Merge branch 'develop' into auth3 2024-08-11 18:09:03 +09:00
usbharu 7ec997c1d5 fix: よくない修正だったのでロールバック 2024-08-11 16:33:22 +09:00
usbharu 94f790d039 test: 権限チェックのテストを追加 2024-08-11 16:07:10 +09:00
usbharu ed3b3f07fb fix: 自分自身の投稿が見えないようになっていた問題を修正 2024-08-11 13:10:10 +09:00
usbharu 146b907c69 feat: QueryServiceの認可処理を追加して起動できるように 2024-08-11 12:33:37 +09:00
usbharu 540fe0eaa5 feat: 権限チェック等を追加 2024-08-11 01:22:43 +09:00
usbharu 1a3fc05dad feat: ローカルユーザーのみ使用できる部分を変更 2024-08-11 00:30:24 +09:00
usbharu 507c1d8932 refactor: principalのactorIdを使用するように 2024-08-11 00:28:32 +09:00
renovate[bot] 4fb32d7928 fix(deps): update dependency software.amazon.awssdk:s3 to v2.27.2 2024-08-10 15:24:55 +00:00
usbharu e082b0b7b9 Merge pull request #530 from usbharu/use-owl-jar
OWLをビルド済みライブラリをとして読み込むように
2024-08-10 19:48:32 +09:00
usbharu 700a8d8ed1 Merge branch 'develop' into use-owl-jar 2024-08-10 19:45:42 +09:00
usbharu cb408fd192 Merge pull request #524 from usbharu/renovate/actions-github-script-7.x
chore(deps): update actions/github-script action to v7
2024-08-10 19:44:43 +09:00
usbharu 2e38c64a3d chore: 構成キャッシュをしないように 2024-08-10 19:44:35 +09:00
usbharu 4a665029ec chore: 2024-08-10 19:40:09 +09:00
usbharu a1b4631a13 chore: 2024-08-10 19:38:36 +09:00
renovate[bot] 86c8fb0bad chore(deps): update actions/github-script action to v7 2024-08-10 08:08:43 +00:00
usbharu 96e2f9b420 Merge pull request #527 from usbharu/master
Master
2024-08-10 17:07:47 +09:00
usbharu ecd59cd886 Merge pull request #526 from usbharu/release
[OWL] Release 0.0.1
2024-08-10 17:03:13 +09:00
usbharu 0983f39a17 chore: snapshot 2024-08-10 17:01:26 +09:00
usbharu 0d671b2557 chore: トークン忘れてた2 2024-08-10 16:58:09 +09:00
usbharu 7b1e99095b chore: トークン忘れてた 2024-08-10 16:56:13 +09:00
usbharu 0b4a47f22a [OWL] Release 0.0.1 2024-08-10 16:48:25 +09:00
usbharu a70eb9864c chore: バージョン指定を一括でできるように 2024-08-10 16:47:46 +09:00
usbharu 11030e3a63 Merge pull request #525 from usbharu/develop
[OWL] Release 0.0.1
2024-08-10 16:46:20 +09:00
usbharu d8d6d053f7 Merge pull request #523 from usbharu/owl-release
Owl release
2024-08-10 16:34:15 +09:00
usbharu ed6a590450 chore: needsが設定できていなかった問題を修正 2024-08-10 16:31:55 +09:00
usbharu afffe046ef ??? 2024-08-10 16:30:33 +09:00
usbharu afbeee38a6 ?? 2024-08-10 16:28:47 +09:00
usbharu 67b37bce10 ? 2024-08-10 16:27:16 +09:00
usbharu 852ba5e415 chore: 構成キャッシュがあるとmaven-publishが動かないので削除 2024-08-10 16:24:12 +09:00
usbharu eaf0d4d7fb chore: これだから型のない言語はダメだ 2024-08-10 16:08:44 +09:00
usbharu 1a19afa4db ?????? 2024-08-10 16:06:57 +09:00
usbharu 556644d7e3 ????? 2024-08-10 16:05:56 +09:00
usbharu 19872ce50f ???? 2024-08-10 16:04:48 +09:00
usbharu e45dd333d7 ??? 2024-08-10 16:00:33 +09:00
usbharu 46e31c9878 ?? 2024-08-10 15:59:17 +09:00
usbharu 575554a36c chore: リリース先を追加 2024-08-10 15:55:00 +09:00
usbharu ef57349f95 chore: リリース先を追加 2024-08-10 15:51:03 +09:00
usbharu b7cc88d533 style 2024-08-10 15:43:20 +09:00
usbharu 41c506fa97 style 2024-08-10 15:41:38 +09:00
usbharu e706b2eb17 chore: テスト 2024-08-10 15:30:11 +09:00
usbharu 0b13fce03c wip 2024-08-10 14:52:26 +09:00
usbharu 1fbe3356fc wip 2024-08-10 14:49:41 +09:00
usbharu 53a4953c07 wip 2024-08-10 14:46:50 +09:00
usbharu 8a86c54edf wip 2024-08-10 14:44:05 +09:00
usbharu 80f33f7563 wip 2024-08-10 14:39:59 +09:00
usbharu ba46dcabcc wip 2024-08-10 14:39:00 +09:00
usbharu 5ab29d1449 wip 2024-08-10 14:37:57 +09:00
usbharu 2fecd697b6 wip 2024-08-10 14:37:03 +09:00
usbharu 8d9a6e5426 fix: git diffが失敗する問題を修正 2024-08-10 14:34:09 +09:00
usbharu 06a7b035e4 ????????????? 2024-08-10 14:23:20 +09:00
usbharu e4215df83f ????????????? 2024-08-10 14:17:03 +09:00
usbharu a6c6b110cf ????????????? 2024-08-10 14:15:51 +09:00
usbharu 7ebb29100d chore: fix base_ref 2024-08-10 14:12:27 +09:00
usbharu 3fcd7ae917 chore: fix base_ref 2024-08-10 14:11:15 +09:00
usbharu 6062230e78 chore: diff test 2024-08-10 13:53:10 +09:00
usbharu ceb206289c chore: build-test 2024-08-10 12:18:52 +09:00
usbharu e9f263bab1 Merge pull request #516 from usbharu/auth2
認可処理とテストを追加
2024-08-10 00:34:30 +09:00
usbharu d829b58f8c Merge branch 'develop' into auth2 2024-08-10 00:08:58 +09:00
usbharu 3ab86fc511 テストを追加 2024-08-09 23:06:43 +09:00
renovate[bot] 35a40727df fix(deps): update dependency software.amazon.awssdk:s3 to v2.27.1 2024-08-09 01:06:36 +00:00
usbharu 29d356efac Merge remote-tracking branch 'origin/auth2' into auth2 2024-08-09 10:01:00 +09:00
usbharu 7db82462fa wip 2024-08-09 10:00:40 +09:00
renovate[bot] 15c5cc89cd fix(deps): update dependency org.slf4j:slf4j-api to v2.0.15 2024-08-08 15:44:02 +00:00
usbharu cf71c17464 Merge branch 'develop' into auth2 2024-08-09 00:37:39 +09:00
usbharu 2cfc8bc0d8 test: テストを追加 2024-08-09 00:16:14 +09:00
renovate[bot] 71c1b74975 fix(deps): update dependency org.mongodb:mongodb-driver-kotlin-coroutine to v5.1.3 2024-08-08 14:40:23 +00:00
usbharu f7de5b03f1 test: お引越しのテストを追加 2024-08-08 17:29:05 +09:00
renovate[bot] 322db23411 fix(deps): update grpc-java monorepo to v1.66.0 2024-08-08 07:38:26 +00:00
renovate[bot] 2f284c415d fix(deps): update dependency software.amazon.awssdk:s3 to v2.27.0 2024-08-08 00:45:24 +00:00
usbharu f96c16b2a3 test: タイムラインのテストを追加 2024-08-07 18:47:24 +09:00
usbharu 85ea4c9c09 Merge pull request #508 from usbharu/renovate/kotlin
chore(deps): update kotlin to v2.0.10 - autoclosed
2024-08-07 15:58:25 +09:00
usbharu f87b92df10 Merge branch 'develop' into renovate/kotlin 2024-08-07 15:53:42 +09:00
usbharu 046350ef84 wip 2024-08-07 12:13:52 +09:00
usbharu 4fd97b6182 feat: Postのアクセス制御を追加 2024-08-07 11:41:05 +09:00
renovate[bot] ac0d1d6fc0 fix(deps): update dependency software.amazon.awssdk:s3 to v2.26.31 2024-08-07 01:25:45 +00:00
renovate[bot] 6c9244839c fix(deps): update dependency org.slf4j:slf4j-api to v2.0.14 2024-08-06 22:00:23 +00:00
renovate[bot] 54cf58af55 fix(deps): update dependency org.jetbrains.kotlin:kotlin-test-junit to v2.0.10 2024-08-06 11:29:03 +00:00
renovate[bot] f61b64535a chore(deps): update kotlin to v2.0.10 2024-08-06 11:24:26 +00:00
usbharu 0825be76b3 test: テストを追加 2024-08-06 17:43:14 +09:00
usbharu c056b7598b feat: 新しい認可システムを組み込み 2024-08-06 13:00:00 +09:00
renovate[bot] e0203c5aef fix(deps): update dependency software.amazon.awssdk:s3 to v2.26.30 2024-08-05 21:31:18 +00:00
usbharu 716bf190b5 Merge pull request #505 from usbharu/auth
認可システムの改善
2024-08-06 00:16:10 +09:00
usbharu deb0a05629 Merge remote-tracking branch 'origin/auth' into auth 2024-08-06 00:13:08 +09:00
usbharu cb886fc763 test: テストを修正 2024-08-06 00:12:59 +09:00
usbharu 488ca1018d Merge branch 'develop' into auth 2024-08-06 00:05:52 +09:00
usbharu f5fc4fd0ee feat: 多少の改善にはなっただろうか 2024-08-06 00:04:32 +09:00
usbharu 547ce1ae19 Merge pull request #504 from usbharu/renovate/gradle-actions-4.x
chore(deps): update gradle/actions action to v4
2024-08-04 16:51:50 +09:00
renovate[bot] 497f42af0c chore(deps): update gradle/actions action to v4 2024-08-03 23:11:59 +00:00
usbharu 884983f3e4 認可(Spring Security以外全部)を破壊 2024-08-03 16:37:55 +09:00
renovate[bot] 1cf06be012 fix(deps): update dependency software.amazon.awssdk:s3 to v2.26.29 2024-08-03 05:09:05 +00:00
renovate[bot] c9478f68b3 fix(deps): update dependency software.amazon.awssdk:s3 to v2.26.27 2024-08-03 04:37:43 +00:00
renovate[bot] 09feb573ad fix(deps): update dependency com.google.protobuf:protobuf-kotlin to v4.27.3 2024-08-01 20:01:42 +00:00
renovate[bot] 7f0ce7cf69 fix(deps): update dependency com.google.protobuf:protoc to v4.27.3 2024-08-01 16:19:49 +00:00
renovate[bot] cb0f06065c fix(deps): update exposed 2024-08-01 16:13:29 +00:00
usbharu b3a9be96c5 Merge pull request #475 from usbharu/timeline
タイムラインの実装
2024-07-30 10:58:26 +09:00
usbharu 8d0f87c84c Merge branch 'refs/heads/develop' into timeline 2024-07-30 10:52:24 +09:00
usbharu d9bd21661c feat: ページングに対応 2024-07-30 10:50:51 +09:00
renovate[bot] 2f84525f66 fix(deps): update dependency software.amazon.awssdk:s3 to v2.26.26 2024-07-29 23:01:28 +00:00
usbharu fcd6ebc518 feat: ページングに対応 2024-07-30 01:09:00 +09:00
usbharu 982a29f1e0 feat: ページングに対応 2024-07-30 01:01:26 +09:00
usbharu 175c0b38da Merge branch 'refs/heads/develop' into timeline 2024-07-30 00:36:35 +09:00
usbharu cc76cb18fe Merge pull request #497 from usbharu/github-action
chore: キャッシュを消した
2024-07-30 00:33:36 +09:00
usbharu afec1ed8ea chore: キャッシュを保存するように 2024-07-30 00:19:50 +09:00
usbharu 316e786fc4 chore: jetbrainsのを参考に改良2修正 2024-07-30 00:09:46 +09:00
usbharu 2fe5b1c278 chore: jetbrainsのを参考に改良2 2024-07-30 00:06:09 +09:00
usbharu ef281f1028 chore: jetbrainsのを参考に改良 2024-07-29 23:43:55 +09:00
usbharu d888a1fbbc chore: キャッシュを消した 2024-07-29 23:18:37 +09:00
usbharu 96be4e5577 Merge branch 'refs/heads/develop' into timeline 2024-07-29 22:52:42 +09:00
renovate[bot] 34768bdcf0 fix(deps): update dependency org.flywaydb:flyway-database-postgresql to v10.17.0 2024-07-29 11:02:57 +00:00
usbharu 1a17561f1e Merge pull request #495 from usbharu/k2
chore: k2に
2024-07-29 16:32:12 +09:00
usbharu 086f58bec6 chore: k2に 2024-07-29 16:26:41 +09:00
usbharu f0c4eb93f8 Merge pull request #494 from usbharu/koin-annotation
Koin annotation
2024-07-29 16:19:12 +09:00
usbharu 0461656738 fix: モジュールが読み込まれない場合があったので修正 2024-07-29 16:14:01 +09:00
usbharu da22a2a29f chore: Koin-Annotationを使用しないように 2024-07-29 16:12:07 +09:00
usbharu 1198d7e551 Merge pull request #493 from usbharu/java-21
chore: java toolchain のバージョンを21に
2024-07-29 15:43:51 +09:00
usbharu 58d55ae8dc chore: java toolchain のバージョンを21に 2024-07-29 15:37:28 +09:00
usbharu 92e3f7c13d Merge pull request #491 from usbharu/perf-spring-boot
perf: Spring Boot起動速度を向上
2024-07-29 15:25:13 +09:00
usbharu d975690f12 Merge branch 'develop' into perf-spring-boot 2024-07-29 15:22:53 +09:00
usbharu 97bbd1a407 perf: Spring Boot起動速度を向上 2024-07-29 15:13:02 +09:00
usbharu e70f104b5c wip 2024-07-29 00:15:40 +09:00
renovate[bot] cde57081ad fix(deps): update dependency software.amazon.awssdk:s3 to v2.26.25 2024-07-26 00:53:42 +00:00
renovate[bot] d044ba909c fix(deps): update dependency software.amazon.awssdk:s3 to v2.26.24 2024-07-24 21:36:50 +00:00
renovate[bot] ee4a0e4296 fix(deps): update dependency software.amazon.awssdk:s3 to v2.26.23 2024-07-23 22:27:29 +00:00
renovate[bot] 0d75682ed7 chore(deps): update plugin com.google.devtools.ksp to v1.9.25-1.0.20 2024-07-23 18:26:58 +00:00
renovate[bot] c864407c9e fix(deps): update dependency software.amazon.awssdk:s3 to v2.26.22 2024-07-22 22:21:01 +00:00
usbharu e728b0f990 feat: アカウント作成時に自動でホームタイムラインを作成するように 2024-07-20 17:16:28 +09:00
usbharu 8e84c8e59c style: fix lint 2024-07-20 16:23:59 +09:00
usbharu edae599978 test: テストを修正 2024-07-20 16:19:34 +09:00
usbharu d0ff47525f feat: タイムラインを読み込めるように 2024-07-20 16:11:35 +09:00
usbharu efbf2b0af7 feat: DB自動修復を追加 2024-07-20 11:23:16 +09:00
usbharu 841289700b feat: Mongodbでタイムラインを構築できるように 2024-07-20 11:22:43 +09:00
renovate[bot] f47b8b3c5b chore(deps): update plugin kover to v0.8.3 2024-07-19 17:19:02 +00:00
usbharu c32e264575 feat: 起動できる状態に 2024-07-20 01:27:30 +09:00
usbharu b61282a058 feat: ページネーションを実装 2024-07-20 00:41:16 +09:00
usbharu 3057d9cc5a feat: DefaultTimelineStore 2024-07-19 23:49:14 +09:00
renovate[bot] d24d34787b chore(deps): update plugin org.jetbrains.kotlin.jvm to v1.9.25 2024-07-19 12:14:08 +00:00
renovate[bot] 0ba8771468 fix(deps): update dependency software.amazon.awssdk:s3 to v2.26.21 2024-07-19 09:46:32 +00:00
renovate[bot] a7eb36ba80 chore(deps): update plugin spring-boot to v3.3.2 2024-07-18 20:09:18 +00:00
renovate[bot] 22a1ff5986 fix(deps): update dependency org.flywaydb:flyway-database-postgresql to v10.16.0 2024-07-18 14:47:55 +00:00
usbharu a3f8629561 Merge pull request #476 from usbharu/renovate/gradle-gradle-build-action-digest
chore(deps): update gradle/gradle-build-action digest to ac2d340
2024-07-16 10:12:00 +09:00
usbharu 3b5d80e539 Merge branch 'develop' into renovate/gradle-gradle-build-action-digest 2024-07-16 09:46:25 +09:00
renovate[bot] 353c3a532d chore(deps): update gradle/gradle-build-action action to v3.5.0 2024-07-16 00:44:03 +00:00
usbharu 965ce437a3 Merge branch 'develop' into renovate/gradle-gradle-build-action-digest 2024-07-16 09:40:28 +09:00
renovate[bot] 7799bc2821 fix(deps): update dependency com.h2database:h2 to v2.3.230 2024-07-15 23:02:36 +00:00
renovate[bot] 5566773e77 chore(deps): update gradle/gradle-build-action digest to ac2d340 2024-07-15 22:58:01 +00:00
usbharu b4c62fbd43 feat: タイムラインを実装 2024-07-15 17:30:28 +09:00
usbharu 5303b13b08 feat: タイムラインを実装 2024-07-14 21:11:22 +09:00
usbharu a550ddd5c3 feat: タイムラインの実装に必要なものを定義 2024-07-14 16:35:20 +09:00
usbharu 0143038707 feat: AbstractTimelineStoreを作成 2024-07-14 16:21:56 +09:00
renovate[bot] 92ca9343aa fix(deps): update dependency software.amazon.awssdk:s3 to v2.26.20 2024-07-13 00:33:35 +00:00
renovate[bot] 183ce0ee52 fix(deps): update grpc-java monorepo to v1.65.1 2024-07-12 00:54:01 +00:00
renovate[bot] 1247ea3302 chore(deps): update dependency gradle to v8.9 2024-07-11 15:55:57 +00:00
renovate[bot] 6ea0bcd2d1 fix(deps): update dependency software.amazon.awssdk:s3 to v2.26.19 2024-07-10 21:54:14 +00:00
renovate[bot] b52d869a6c fix(deps): update dependency org.jsoup:jsoup to v1.18.1 2024-07-10 11:14:53 +00:00
renovate[bot] 99b69b9b92 fix(deps): update dependency org.mongodb:mongodb-driver-kotlin-coroutine to v5.1.2 2024-07-10 01:26:59 +00:00
renovate[bot] 93b380c40a fix(deps): update dependency software.amazon.awssdk:s3 to v2.26.18 2024-07-10 00:32:11 +00:00
renovate[bot] f23977a40c fix(deps): update dependency org.mockito.kotlin:mockito-kotlin to v5.4.0 2024-07-09 10:11:19 +00:00
renovate[bot] 02e9ea80a7 fix(deps): update dependency software.amazon.awssdk:s3 to v2.26.17 2024-07-08 21:52:21 +00:00
usbharu 0d39e779c4 refactor: タイムラインの実装方式を変更 2024-07-06 18:30:02 +09:00
usbharu a4a3f4c0c4 refactor: タイムラインの実装方式を変更 2024-07-06 16:41:47 +09:00
renovate[bot] 2f565dbb3a fix(deps): update dependency software.amazon.awssdk:s3 to v2.26.16 2024-07-05 23:26:56 +00:00
renovate[bot] afb843421a fix(deps): update jackson to v2.17.2 2024-07-05 18:53:02 +00:00
renovate[bot] f575ac4918 fix(deps): update dependency software.amazon.awssdk:s3 to v2.26.15 2024-07-03 22:50:41 +00:00
renovate[bot] 8133799d13 fix(deps): update dependency software.amazon.awssdk:s3 to v2.26.14 2024-07-02 21:15:30 +00:00
renovate[bot] 5d2e1682c8 fix(deps): update dependency org.flywaydb:flyway-database-postgresql to v10.15.2 2024-07-02 16:14:15 +00:00
renovate[bot] 8542ba7ab7 fix(deps): update dependency software.amazon.awssdk:s3 to v2.26.13 2024-07-02 14:31:58 +00:00
renovate[bot] 935b1053fd chore(deps): update plugin openapi-generator to v7.7.0 2024-07-02 10:07:27 +00:00
usbharu faee779cfb feat: Timelineの構築に必要なものを追加 2024-06-30 13:48:43 +09:00
usbharu ed872610f7 feat: Timelineの構築に必要なものを追加 2024-06-29 19:25:19 +09:00
usbharu 3f92ccab98 Merge remote-tracking branch 'origin/timeline' into timeline 2024-06-29 12:32:05 +09:00
usbharu 6188463a68 feat: Timelineの構築に必要なものを追加 2024-06-29 12:31:58 +09:00
usbharu c0f03560d5 feat: TimelinePostCreateSubscriberが機能するように 2024-06-29 12:31:57 +09:00
usbharu c74aba652e feat: ドメインイベントを受け取れるように 2024-06-29 12:31:57 +09:00
usbharu 0803877c8b Merge pull request #455 from usbharu/dependabot/github_actions/dot-github/workflows/github_actions-20315eca73
chore(deps): bump gradle/gradle-build-action from 2.3.3 to 3.4.2 in /.github/workflows in the github_actions group across 1 directory
2024-06-29 11:46:52 +09:00
usbharu 31f72787f8 Merge branch 'develop' into dependabot/github_actions/dot-github/workflows/github_actions-20315eca73 2024-06-29 11:44:25 +09:00
renovate[bot] eabe341ece chore(deps): update gradle/gradle-build-action action to v2.4.2 [security] 2024-06-29 02:36:39 +00:00
dependabot[bot] 001d5bc863 chore(deps): bump gradle/gradle-build-action
Bumps the github_actions group with 1 update in the /.github/workflows directory: [gradle/gradle-build-action](https://github.com/gradle/gradle-build-action).


Updates `gradle/gradle-build-action` from 2.3.3 to 3.4.2
- [Release notes](https://github.com/gradle/gradle-build-action/releases)
- [Commits](https://github.com/gradle/gradle-build-action/compare/v2.3.3...v3.4.2)

---
updated-dependencies:
- dependency-name: gradle/gradle-build-action
  dependency-type: direct:production
  dependency-group: github_actions
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-06-29 02:31:09 +00:00
renovate[bot] 5f41feda61 chore(deps): update gradle/gradle-build-action action to v2.3.3 2024-06-29 02:30:35 +00:00
renovate[bot] ac4d03200a fix(deps): update dependency software.amazon.awssdk:s3 to v2.26.12 2024-06-28 22:59:35 +00:00
usbharu 5320be6c9a feat: TimelinePostCreateSubscriberが機能するように 2024-06-29 00:02:50 +09:00
usbharu dba4d85ff3 Merge pull request #446 from usbharu/renovate/serialization
fix(deps): update serialization to v1.7.1
2024-06-28 23:32:32 +09:00
usbharu f4db384a5a Merge branch 'develop' into renovate/serialization 2024-06-28 23:29:42 +09:00
renovate[bot] 5ac0b3f14d fix(deps): update dependency software.amazon.awssdk:s3 to v2.26.11 2024-06-28 14:17:02 +00:00
renovate[bot] 379e41f506 fix(deps): update serialization to v1.7.1 2024-06-28 14:14:01 +00:00
renovate[bot] b1135e6794 chore(deps): update plugin kover to v0.8.2 2024-06-28 10:42:34 +00:00
usbharu 88775f50fe Merge branch 'refs/heads/develop' into timeline 2024-06-28 18:10:08 +09:00
renovate[bot] dbd7e55940 fix(deps): update dependency org.junit.jupiter:junit-jupiter to v5.10.3 2024-06-28 08:53:58 +00:00
usbharu dd0c93a0b4 Merge pull request #451 from usbharu/chore-renovate
Renovateのautomergeを有効化
2024-06-28 17:50:58 +09:00
usbharu bf2d7986cc feat: ドメインイベントを受け取れるように 2024-06-27 01:00:13 +09:00
334 changed files with 7989 additions and 1742 deletions
+8
View File
@@ -0,0 +1,8 @@
{
"projects": {
"./hideout-activitypub": "hideout-activitypub",
"./hideout-core": "hideout-core",
"./hideout-mastodon": "hideout-mastodon",
"./owl": "owl"
}
}
@@ -0,0 +1,82 @@
name: master-publish-package.yaml
on:
pull_request:
branches:
- "master"
- "release-test-master"
jobs:
release-diff-check:
name: Release diff check
runs-on: ubuntu-latest
outputs:
diff: ${{ steps.check-diff.outputs.result }}
steps:
- name: Checkout
uses: actions/checkout@v4
- name: fetch git
run: git fetch --depth 1 origin
- name: Check diff
id: check-diff
uses: actions/github-script@v7
with:
result-encoding: 'json'
script: |
const fs = require('fs')
const {execSync} = require('child_process');
const jsonData = JSON.parse(fs.readFileSync('./.github/monorepo.json', 'utf8'));
const baseRef = context.payload.pull_request.base.ref
console.log(baseRef)
var tags = []
for (let [key, value] of Object.entries(jsonData.projects)) {
console.log(execSync("git branch", {encoding: 'utf8'}))
const command = "git diff origin/" + baseRef + " -- HEAD --name-only --relative=" + key + "\n";
const output = execSync(command, {encoding: 'utf8'});
console.log(output)
if (output.trim() === '') {
tags.push(value)
}
}
return tags
- name: show diff
env:
DIFF: ${{ steps.check-diff.outputs.result }}
run: echo "$DIFF"
publish-package:
runs-on: ubuntu-latest
needs: release-diff-check
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Gradle Wrapper Validation
uses: gradle/actions/wrapper-validation@v4
- name: Set up JDK 21
uses: actions/setup-java@v4
with:
java-version: '21'
distribution: 'temurin'
- name: Setup Gradle
uses: gradle/actions/setup-gradle@v4
with:
cache-read-only: false
gradle-home-cache-cleanup: true
- name: Publish OWL Local
if: ${{ github.base_ref == 'release-test-master' && contains( needs.release-diff-check.outputs.diff, 'owl') }}
run: ./owl/gradlew :owl:publishMavenPublicationToMavenLocal
- name: Publish OWL Gitea
if: ${{ github.base_ref == 'master' && contains( needs.release-diff-check.outputs.diff , 'owl')}}
run: ./owl/gradlew :owl:publishMavenPublicationToGiteaRepository
env:
USERNAME: ${{ github.actor }}
TOKEN: ${{ secrets.GITHUB_TOKEN }}
GITEA: ${{ secrets.GITEA }}
+36 -177
View File
@@ -2,6 +2,8 @@ name: PullRequest Merge Check
on:
pull_request:
paths-ignore:
- 'owl/**'
branches:
- "develop"
types:
@@ -9,7 +11,9 @@ on:
- reopened # default
- synchronize # default
- ready_for_review # 必要
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
permissions:
contents: read
@@ -25,49 +29,26 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Gradle Wrapper Cache
uses: actions/cache@v4.0.2
with:
path: ~/.gradle/wrapper
key: gradle-wrapper-${{ hashFiles('gradle/wrapper/gradle-wrapper.properties') }}
token: ${{ secrets.PAT }}
- name: Dependencies Cache
uses: actions/cache@v4.0.2
with:
path: |
~/.gradle/cache/jars-*
~/.gradle/caches/transforms-*
~/.gradle/caches/modules-*
key: gradle-dependencies-${{ hashFiles('**/*.gradle.kts') }}
restore-keys: gradle-dependencies-
- name: Cache
uses: actions/cache@v4.0.2
with:
path: |
~/.gradle/caches/build-cache-*
~/.gradle/caches/[0-9]*.*
.gradle
key: ${{ runner.os }}-gradle-build-${{ github.workflow }}-${{ github.sha }}
restore-keys: ${{ runner.os }}-gradle-build-${{ github.workflow }}-
- name: Build Cache
uses: actions/cache@v4.0.2
with:
path: |
build
key: gradle-build-${{ hashFiles('**/*.gradle.kts') }}-${{ hashFiles('**/*.kt') }}-${{ github.sha }}
- name: Gradle Wrapper Validation
uses: gradle/actions/wrapper-validation@v4
- name: Set up JDK 21
uses: actions/setup-java@v4
with:
java-version: '21'
distribution: 'temurin'
- name: Build
uses: gradle/gradle-build-action@v3.4.2
- name: Setup Gradle
uses: gradle/actions/setup-gradle@v4
with:
arguments: :hideout-core:testClasses
cache-read-only: false
gradle-home-cache-cleanup: true
- name: Build
run: ./gradlew classes --no-daemon
unit-test:
name: Unit Test
@@ -76,39 +57,8 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Gradle Wrapper Cache
uses: actions/cache@v4.0.2
with:
path: ~/.gradle/wrapper
key: gradle-wrapper-${{ hashFiles('gradle/wrapper/gradle-wrapper.properties') }}
- name: Dependencies Cache
uses: actions/cache@v4.0.2
with:
path: |
~/.gradle/cache/jars-*
~/.gradle/caches/transforms-*
~/.gradle/caches/modules-*
key: gradle-dependencies-${{ hashFiles('**/*.gradle.kts') }}
restore-keys: gradle-dependencies-
- name: Cache
uses: actions/cache@v4.0.2
with:
path: |
~/.gradle/caches/build-cache-*
~/.gradle/caches/[0-9]*.*
.gradle
key: ${{ runner.os }}-gradle-build-${{ github.workflow }}-${{ github.sha }}
restore-keys: ${{ runner.os }}-gradle-build-${{ github.workflow }}-
- name: Build Cache
uses: actions/cache@v4.0.2
with:
path: |
build
key: gradle-build-${{ hashFiles('**/*.gradle.kts') }}-${{ hashFiles('src') }}-${{ github.sha }}
token: ${{ secrets.PAT }}
- name: Set up JDK 21
uses: actions/setup-java@v4
@@ -116,74 +66,19 @@ jobs:
java-version: '21'
distribution: 'temurin'
- name: Setup Gradle
uses: gradle/actions/setup-gradle@v4
with:
cache-read-only: false
gradle-home-cache-cleanup: true
- name: Unit Test
uses: gradle/gradle-build-action@v3.4.2
with:
arguments: :hideout-core:test
- name: Save Test Report
if: always()
uses: actions/cache/save@v4
with:
path: build/test-results
key: unit-test-report-${{ github.sha }}
coverage:
name: Coverage
needs: [ setup ]
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Gradle Wrapper Cache
uses: actions/cache@v4.0.2
with:
path: ~/.gradle/wrapper
key: gradle-wrapper-${{ hashFiles('gradle/wrapper/gradle-wrapper.properties') }}
- name: Dependencies Cache
uses: actions/cache@v4.0.2
with:
path: |
~/.gradle/cache/jars-*
~/.gradle/caches/transforms-*
~/.gradle/caches/modules-*
key: gradle-dependencies-${{ hashFiles('**/*.gradle.kts') }}
restore-keys: gradle-dependencies-
- name: Cache
uses: actions/cache@v4.0.2
with:
path: |
~/.gradle/caches/build-cache-*
~/.gradle/caches/[0-9]*.*
.gradle
key: ${{ runner.os }}-gradle-build-${{ github.workflow }}-${{ github.sha }}
restore-keys: ${{ runner.os }}-gradle-build-${{ github.workflow }}-
- name: Build Cache
uses: actions/cache@v4.0.2
with:
path: |
build
key: gradle-build-${{ hashFiles('**/*.gradle.kts') }}-${{ hashFiles('src') }}-${{ github.sha }}
- name: Set up JDK 21
uses: actions/setup-java@v4
with:
java-version: '21'
distribution: 'temurin'
- name: Run Kover
uses: gradle/gradle-build-action@v3.4.2
with:
arguments: :hideout-core:koverXmlReport --rerun-tasks
run: ./hideout-core/gradlew :hideout-core:koverXmlReport
- name: Add coverage report to PR
if: always()
id: kover
uses: madrapps/jacoco-report@v1.6.1
uses: madrapps/jacoco-report@v1.7.0
with:
paths: |
${{ github.workspace }}/hideout-core/build/reports/kover/report.xml
@@ -194,18 +89,6 @@ jobs:
min-coverage-changed-files: 80
coverage-counter-type: LINE
report-tests:
name: Report Tests
if: success() || failure()
needs: [ unit-test ]
runs-on: ubuntu-latest
steps:
- name: Restore Test Report
uses: actions/cache/restore@v4
with:
path: build/test-results
key: unit-test-report-${{ github.sha }}
- name: JUnit Test Report
uses: mikepenz/action-junit-report@v4
with:
@@ -215,42 +98,14 @@ jobs:
name: Lint
needs: [ setup ]
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Gradle Wrapper Cache
uses: actions/cache@v4.0.2
with:
path: ~/.gradle/wrapper
key: gradle-wrapper-${{ hashFiles('gradle/wrapper/gradle-wrapper.properties') }}
- name: Dependencies Cache
uses: actions/cache@v4.0.2
with:
path: |
~/.gradle/cache/jars-*
~/.gradle/caches/transforms-*
~/.gradle/caches/modules-*
key: gradle-dependencies-${{ hashFiles('**/*.gradle.kts') }}
restore-keys: gradle-dependencies-
- name: Cache
uses: actions/cache@v4.0.2
with:
path: |
~/.gradle/caches/build-cache-*
~/.gradle/caches/[0-9]*.*
.gradle
key: ${{ runner.os }}-gradle-build-${{ github.workflow }}-${{ github.sha }}
restore-keys: ${{ runner.os }}-gradle-build-${{ github.workflow }}-
- name: Build Cache
uses: actions/cache@v4.0.2
with:
path: |
build
key: gradle-build-${{ hashFiles('**/*.gradle.kts') }}-${{ hashFiles('src') }}-${{ github.sha }}
ref: ${{ github.head_ref }}
token: '${{ secrets.PAT }}'
- name: Set up JDK 21
uses: actions/setup-java@v4
@@ -258,10 +113,14 @@ jobs:
java-version: '21'
distribution: 'temurin'
- name: Build with Gradle
uses: gradle/gradle-build-action@66535aaf56f831b35e3a8481c9c99b665b84dd45
- name: Setup Gradle
uses: gradle/actions/setup-gradle@v4
with:
arguments: :hideout-core:detektMain
cache-read-only: false
gradle-home-cache-cleanup: true
- name: Build with Gradle
run: ./gradlew :hideout-core:detektMain :hideout-mastodon:detektMain
- name: Auto Commit
if: ${{ always() }}
+1
View File
@@ -48,3 +48,4 @@ out/
/hideout-core/files/
/hideout-core/.kotlin/sessions/
/hideout-mastodon/.kotlin/sessions/
/http-client.private.env.json
+2 -1
View File
@@ -66,4 +66,5 @@ tasks.register("run") {
springBoot {
mainClass = "dev.usbharu.hideout.SpringApplicationKt"
}
}
+16
View File
@@ -0,0 +1,16 @@
version: "3"
services:
db:
image: postgres:16
ports:
- "5432:5432"
environment:
POSTGRES_USER: "postgres"
POSTGRES_PASSWORD: "password"
POSTGRES_DB: "hideout"
mongodb:
image: mongo:7.0.14
ports:
- "27017:27017"
+1 -3
View File
@@ -1,6 +1,4 @@
org.gradle.parallel=true
org.gradle.configureondemand=true
org.gradle.caching=true
org.gradle.jvmargs=-Xmx4096m -XX:+HeapDumpOnOutOfMemoryError -XX:+UseParallelGC --add-opens=java.base/java.util.concurrent.locks=ALL-UNNAMED
org.gradle.configuration-cache=true
org.gradle.configuration-cache.problems=warn
org.gradle.jvmargs=-Xmx4096m -XX:+HeapDumpOnOutOfMemoryError -XX:+UseParallelGC --add-opens=java.base/java.util.concurrent.locks=ALL-UNNAMED
Binary file not shown.
+1 -1
View File
@@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.8-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.10-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
Vendored
+4 -1
View File
@@ -15,6 +15,8 @@
# See the License for the specific language governing permissions and
# limitations under the License.
#
# SPDX-License-Identifier: Apache-2.0
#
##############################################################################
#
@@ -84,7 +86,8 @@ done
# shellcheck disable=SC2034
APP_BASE_NAME=${0##*/}
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit
APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s
' "$PWD" ) || exit
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD=maximum
Vendored
+2
View File
@@ -13,6 +13,8 @@
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
@rem SPDX-License-Identifier: Apache-2.0
@rem
@if "%DEBUG%"=="" @echo off
@rem ##########################################################################
+1 -1
View File
@@ -1,5 +1,5 @@
plugins {
kotlin("jvm") version "1.9.24"
kotlin("jvm") version "1.9.25"
}
group = "dev.usbharu"
Binary file not shown.
@@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.8-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.10-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
+4 -1
View File
@@ -15,6 +15,8 @@
# See the License for the specific language governing permissions and
# limitations under the License.
#
# SPDX-License-Identifier: Apache-2.0
#
##############################################################################
#
@@ -84,7 +86,8 @@ done
# shellcheck disable=SC2034
APP_BASE_NAME=${0##*/}
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit
APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s
' "$PWD" ) || exit
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD=maximum
+2
View File
@@ -13,6 +13,8 @@
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
@rem SPDX-License-Identifier: Apache-2.0
@rem
@if "%DEBUG%"=="" @echo off
@rem ##########################################################################
+13 -11
View File
@@ -12,7 +12,6 @@ plugins {
alias(libs.plugins.kotlin.spring)
alias(libs.plugins.kover)
alias(libs.plugins.license.report)
}
apply {
@@ -75,6 +74,7 @@ val os = org.gradle.nativeplatform.platform.internal
dependencies {
developmentOnly(libs.h2db)
developmentOnly("org.springframework.boot:spring-boot-devtools")
detektPlugins(libs.detekt.formatting)
implementation(libs.bundles.exposed)
@@ -86,14 +86,13 @@ dependencies {
implementation(libs.bundles.owl.broker)
implementation(libs.bundles.spring.boot.oauth2)
implementation(libs.bundles.spring.boot.data.mongodb)
implementation(libs.bundles.spring.boot.data.mongodb)
implementation("org.springframework.boot:spring-boot-starter-actuator")
implementation("org.springframework.boot:spring-boot-starter-web")
implementation("org.springframework.boot:spring-boot-starter-security")
implementation("org.springframework.boot:spring-boot-starter-thymeleaf")
implementation("org.springframework.boot:spring-boot-starter-log4j2")
implementation("org.springframework.boot:spring-boot-starter-validation")
annotationProcessor("org.springframework:spring-context-indexer")
implementation(libs.blurhash)
implementation(libs.aws.s3)
@@ -105,7 +104,7 @@ dependencies {
implementation(libs.flyway.core)
runtimeOnly(libs.flyway.postgresql)
implementation("dev.usbharu:owl-common-serialize-jackson:0.0.1")
implementation(libs.owl.common.serialize.jackson)
implementation(libs.javacv) {
exclude(module = "opencv")
@@ -124,8 +123,8 @@ dependencies {
implementation(variantOf(libs.javacv.ffmpeg) { classifier("linux-x86_64") })
}
implementation("dev.usbharu:http-signature:1.0.0")
implementation("dev.usbharu:emoji-kt:2.0.0")
implementation(libs.http.signature)
implementation(libs.emoji.kt)
@@ -134,16 +133,13 @@ dependencies {
testImplementation(libs.coroutines.test)
testImplementation(libs.ktor.client.mock)
testImplementation(libs.h2db)
testImplementation("org.mockito.kotlin:mockito-kotlin:5.3.1")
testImplementation("org.mockito:mockito-inline:5.2.0")
testImplementation("nl.jqno.equalsverifier:equalsverifier:3.16.1")
testImplementation("com.jparams:to-string-verifier:1.4.8")
testImplementation(libs.mockito.kotlin)
}
detekt {
parallel = true
config = files("../detekt.yml")
config.setFrom(files("../detekt.yml"))
buildUponDefaultConfig = true
basePath = "${rootDir.absolutePath}/src/main/kotlin"
autoCorrect = true
@@ -157,6 +153,12 @@ configurations.matching { it.name == "detekt" }.all {
}
}
//tasks{
// bootRun {
// sourceResources(sourceSets.main.get())
// }
//}
tasks.withType<io.gitlab.arturbosch.detekt.Detekt> {
exclude("**/generated/**")
doFirst {
+1 -3
View File
@@ -17,6 +17,4 @@ kotlin.code.style=official
org.gradle.parallel=true
org.gradle.configureondemand=true
org.gradle.caching=true
org.gradle.jvmargs=-Xmx4096m -XX:+HeapDumpOnOutOfMemoryError -XX:+UseParallelGC
org.gradle.configuration-cache=true
org.gradle.configuration-cache.problems=warn
org.gradle.jvmargs=-Xmx4096m -XX:+HeapDumpOnOutOfMemoryError -XX:+UseParallelGC
Binary file not shown.
+1 -1
View File
@@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.8-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.10-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
Vendored Regular → Executable
+4 -1
View File
@@ -15,6 +15,8 @@
# See the License for the specific language governing permissions and
# limitations under the License.
#
# SPDX-License-Identifier: Apache-2.0
#
##############################################################################
#
@@ -84,7 +86,8 @@ done
# shellcheck disable=SC2034
APP_BASE_NAME=${0##*/}
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit
APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s
' "$PWD" ) || exit
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD=maximum
+2
View File
@@ -13,6 +13,8 @@
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
@rem SPDX-License-Identifier: Apache-2.0
@rem
@if "%DEBUG%"=="" @echo off
@rem ##########################################################################
+5 -1
View File
@@ -3,11 +3,15 @@ plugins {
}
rootProject.name = "hideout-core"
includeBuild("../owl")
//ローカルで変更した時、リリースまではアンコメント リリース後はコメントアウト
//includeBuild("../owl")
dependencyResolutionManagement {
repositories {
mavenCentral()
maven {
url = uri("https://git.usbharu.dev/api/packages/usbharu/maven")
}
}
versionCatalogs {
@@ -0,0 +1,38 @@
package dev.usbharu.hideout.core.application.actor
import dev.usbharu.hideout.core.domain.model.actor.Actor
import java.net.URI
data class ActorDetail(
val id: Long,
val name: String,
val screenName: String,
val host: String,
val remoteUrl: String?,
val locked: Boolean,
val description: String,
val postsCount: Int,
val iconUrl: URI?,
val bannerURL: URI?,
val followingCount: Int?,
val followersCount: Int?,
) {
companion object {
fun of(actor: Actor, iconUrl: URI?, bannerURL: URI?): ActorDetail {
return ActorDetail(
id = actor.id.id,
name = actor.name.name,
screenName = actor.screenName.screenName,
host = actor.url.host,
remoteUrl = actor.url.toString(),
locked = actor.locked,
description = actor.description.description,
postsCount = actor.postsCount.postsCount,
iconUrl = iconUrl,
bannerURL = bannerURL,
followingCount = actor.followingCount?.relationshipCount,
followersCount = actor.followersCount?.relationshipCount,
)
}
}
}
@@ -0,0 +1,5 @@
package dev.usbharu.hideout.core.application.actor
import dev.usbharu.hideout.core.domain.model.actor.ActorId
data class DeleteLocalActor(val actorId: ActorId)
@@ -1,37 +0,0 @@
/*
* Copyright (C) 2024 usbharu
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package dev.usbharu.hideout.core.application.actor
import dev.usbharu.hideout.core.application.shared.Transaction
import dev.usbharu.hideout.core.domain.model.actor.ActorId
import dev.usbharu.hideout.core.domain.model.actor.ActorRepository
import org.springframework.stereotype.Service
@Service
class DeleteLocalActorApplicationService(
private val transaction: Transaction,
private val actorRepository: ActorRepository,
) {
suspend fun delete(actorId: Long, executor: ActorId) {
transaction.transaction {
val id = ActorId(actorId)
val findById = actorRepository.findById(id)!!
findById.delete()
actorRepository.delete(findById)
}
}
}
@@ -0,0 +1,8 @@
package dev.usbharu.hideout.core.application.actor
import dev.usbharu.hideout.core.domain.model.support.acct.Acct
data class GetActorDetail(
val actorName: Acct? = null,
val id: Long? = null
)
@@ -0,0 +1,47 @@
package dev.usbharu.hideout.core.application.actor
import dev.usbharu.hideout.core.application.shared.AbstractApplicationService
import dev.usbharu.hideout.core.application.shared.Transaction
import dev.usbharu.hideout.core.config.ApplicationConfig
import dev.usbharu.hideout.core.domain.model.actor.ActorId
import dev.usbharu.hideout.core.domain.model.actor.ActorRepository
import dev.usbharu.hideout.core.domain.model.media.MediaRepository
import dev.usbharu.hideout.core.domain.model.support.principal.Principal
import org.slf4j.LoggerFactory
import org.springframework.stereotype.Component
@Component
class GetActorDetailApplicationService(
private val actorRepository: ActorRepository,
private val mediaRepository: MediaRepository,
private val applicationConfig: ApplicationConfig,
transaction: Transaction
) :
AbstractApplicationService<GetActorDetail, ActorDetail>(
transaction,
logger
) {
override suspend fun internalExecute(command: GetActorDetail, principal: Principal): ActorDetail {
val actor = if (command.id != null) {
actorRepository.findById(ActorId(command.id))
?: throw IllegalArgumentException("Actor ${command.id} not found.")
} else if (command.actorName != null) {
val host = command.actorName.host.ifEmpty {
applicationConfig.url.host
}
actorRepository.findByNameAndDomain(command.actorName.userpart, host)
?: throw IllegalArgumentException("Actor ${command.actorName} not found.")
} else {
throw IllegalArgumentException("id and actorName are null.")
}
val iconUrl = actor.icon?.let { mediaRepository.findById(it)?.url }
val bannerUrl = actor.banner?.let { mediaRepository.findById(it)?.url }
return ActorDetail.of(actor, iconUrl, bannerUrl)
}
companion object {
private val logger = LoggerFactory.getLogger(GetActorDetailApplicationService::class.java)
}
}
@@ -16,11 +16,13 @@
package dev.usbharu.hideout.core.application.actor
import dev.usbharu.hideout.core.application.exception.InternalServerException
import dev.usbharu.hideout.core.application.shared.AbstractApplicationService
import dev.usbharu.hideout.core.application.shared.CommandExecutor
import dev.usbharu.hideout.core.application.shared.Transaction
import dev.usbharu.hideout.core.domain.model.actor.ActorRepository
import dev.usbharu.hideout.core.domain.model.emoji.CustomEmojiRepository
import dev.usbharu.hideout.core.domain.model.support.principal.Principal
import dev.usbharu.hideout.core.domain.model.userdetails.UserDetailId
import dev.usbharu.hideout.core.domain.model.userdetails.UserDetailRepository
import org.slf4j.LoggerFactory
import org.springframework.stereotype.Service
@@ -33,10 +35,11 @@ class GetUserDetailApplicationService(
transaction: Transaction,
) :
AbstractApplicationService<GetUserDetail, UserDetail>(transaction, Companion.logger) {
override suspend fun internalExecute(command: GetUserDetail, executor: CommandExecutor): UserDetail {
val userDetail = userDetailRepository.findById(command.id)
?: throw IllegalArgumentException("actor does not exist")
val actor = actorRepository.findById(userDetail.actorId)!!
override suspend fun internalExecute(command: GetUserDetail, principal: Principal): UserDetail {
val userDetail = userDetailRepository.findById(UserDetailId(command.id))
?: throw IllegalArgumentException("User ${command.id} does not exist")
val actor = actorRepository.findById(userDetail.actorId)
?: throw InternalServerException("Actor ${userDetail.actorId} not found")
val emojis = customEmojiRepository.findByIds(actor.emojis.map { it.emojiId })
@@ -0,0 +1,3 @@
package dev.usbharu.hideout.core.application.actor
data class MigrationLocalActor(val from: Long, val to: Long)
@@ -16,39 +16,61 @@
package dev.usbharu.hideout.core.application.actor
import dev.usbharu.hideout.core.application.exception.InternalServerException
import dev.usbharu.hideout.core.application.exception.PermissionDeniedException
import dev.usbharu.hideout.core.application.shared.LocalUserAbstractApplicationService
import dev.usbharu.hideout.core.application.shared.Transaction
import dev.usbharu.hideout.core.domain.model.actor.ActorId
import dev.usbharu.hideout.core.domain.model.actor.ActorRepository
import dev.usbharu.hideout.core.domain.model.support.principal.LocalUser
import dev.usbharu.hideout.core.domain.model.userdetails.UserDetailRepository
import dev.usbharu.hideout.core.domain.service.actor.local.AccountMigrationCheck.*
import dev.usbharu.hideout.core.domain.service.actor.local.LocalActorMigrationCheckDomainService
import org.slf4j.LoggerFactory
import org.springframework.stereotype.Service
@Service
class MigrationLocalActorApplicationService(
private val transaction: Transaction,
private val actorRepository: ActorRepository,
private val localActorMigrationCheckDomainService: LocalActorMigrationCheckDomainService,
) {
suspend fun migration(from: Long, to: Long, executor: ActorId) {
transaction.transaction<Unit> {
val fromActorId = ActorId(from)
val toActorId = ActorId(to)
transaction: Transaction,
private val userDetailRepository: UserDetailRepository,
) : LocalUserAbstractApplicationService<MigrationLocalActor, Unit>(transaction, logger) {
val fromActor = actorRepository.findById(fromActorId)!!
val toActor = actorRepository.findById(toActorId)!!
override suspend fun internalExecute(command: MigrationLocalActor, principal: LocalUser) {
if (command.from != principal.actorId.id) {
throw PermissionDeniedException()
}
val canAccountMigration = localActorMigrationCheckDomainService.canAccountMigration(fromActor, toActor)
val userDetail = userDetailRepository.findById(principal.userDetailId)
?: throw InternalServerException("User detail ${principal.userDetailId} not found.")
val fromActorId = ActorId(command.from)
val toActorId = ActorId(command.to)
val fromActor =
actorRepository.findById(fromActorId) ?: throw IllegalArgumentException("Actor ${command.from} not found.")
val toActor =
actorRepository.findById(toActorId) ?: throw IllegalArgumentException("Actor ${command.to} not found.")
val canAccountMigration =
localActorMigrationCheckDomainService.canAccountMigration(userDetail, fromActor, toActor)
if (canAccountMigration.canMigration) {
fromActor.moveTo = toActorId
actorRepository.save(fromActor)
} else {
when (canAccountMigration) {
is AlreadyMoved -> TODO()
is CanAccountMigration -> {
fromActor.moveTo = toActorId
actorRepository.save(fromActor)
}
is CircularReferences -> TODO()
is SelfReferences -> TODO()
is AlsoKnownAsNotFound -> TODO()
is AlreadyMoved -> throw IllegalArgumentException(canAccountMigration.message)
is CanAccountMigration -> throw InternalServerException()
is CircularReferences -> throw IllegalArgumentException(canAccountMigration.message)
is SelfReferences -> throw IllegalArgumentException("Self references are not supported")
is AlsoKnownAsNotFound -> throw IllegalArgumentException(canAccountMigration.message)
is MigrationCoolDown -> throw IllegalArgumentException(canAccountMigration.message)
}
}
}
companion object {
private val logger = LoggerFactory.getLogger(MigrationLocalActorApplicationService::class.java)
}
}
@@ -16,12 +16,13 @@
package dev.usbharu.hideout.core.application.actor
import dev.usbharu.hideout.core.application.exception.InternalServerException
import dev.usbharu.hideout.core.application.shared.AbstractApplicationService
import dev.usbharu.hideout.core.application.shared.CommandExecutor
import dev.usbharu.hideout.core.application.shared.Transaction
import dev.usbharu.hideout.core.config.ApplicationConfig
import dev.usbharu.hideout.core.domain.model.actor.ActorRepository
import dev.usbharu.hideout.core.domain.model.instance.InstanceRepository
import dev.usbharu.hideout.core.domain.model.support.principal.Principal
import dev.usbharu.hideout.core.domain.model.userdetails.UserDetail
import dev.usbharu.hideout.core.domain.model.userdetails.UserDetailId
import dev.usbharu.hideout.core.domain.model.userdetails.UserDetailRepository
@@ -46,12 +47,12 @@ class RegisterLocalActorApplicationService(
private val idGenerateService: IdGenerateService,
) : AbstractApplicationService<RegisterLocalActor, URI>(transaction, Companion.logger) {
override suspend fun internalExecute(command: RegisterLocalActor, executor: CommandExecutor): URI {
override suspend fun internalExecute(command: RegisterLocalActor, principal: Principal): URI {
if (actorDomainService.usernameAlreadyUse(command.name)) {
// todo 適切な例外を考える
throw Exception("Username already exists")
throw IllegalArgumentException("Username already exists")
}
val instance = instanceRepository.findByUrl(applicationConfig.url.toURI())!!
val instance = instanceRepository.findByUrl(applicationConfig.url.toURI())
?: throw InternalServerException("Local instance not found.")
val actor = actorFactoryImpl.createLocal(
command.name,
@@ -63,12 +64,15 @@ class RegisterLocalActorApplicationService(
id = UserDetailId(idGenerateService.generateId()),
actorId = actor.id,
password = userDetailDomainService.hashPassword(command.password),
autoAcceptFolloweeFollowRequest = false,
lastMigration = null,
homeTimelineId = null
)
userDetailRepository.save(userDetail)
return actor.url
}
companion object {
val logger = LoggerFactory.getLogger(RegisterLocalActorApplicationService::class.java)
private val logger = LoggerFactory.getLogger(RegisterLocalActorApplicationService::class.java)
}
}
@@ -1,8 +0,0 @@
package dev.usbharu.hideout.core.application.actor
import org.springframework.stereotype.Service
@Service
interface SetAlsoKnownAsLocalActorApplicationService {
suspend fun setAlsoKnownAs(actorId: Long, alsoKnownAs: List<Long>)
}
@@ -0,0 +1,46 @@
/*
* Copyright (C) 2024 usbharu
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package dev.usbharu.hideout.core.application.actor
import dev.usbharu.hideout.core.application.exception.InternalServerException
import dev.usbharu.hideout.core.application.exception.PermissionDeniedException
import dev.usbharu.hideout.core.application.shared.LocalUserAbstractApplicationService
import dev.usbharu.hideout.core.application.shared.Transaction
import dev.usbharu.hideout.core.domain.model.actor.ActorRepository
import dev.usbharu.hideout.core.domain.model.support.principal.LocalUser
import org.slf4j.LoggerFactory
import org.springframework.stereotype.Service
@Service
class StartDeleteLocalActorApplicationService(
transaction: Transaction,
private val actorRepository: ActorRepository,
) : LocalUserAbstractApplicationService<DeleteLocalActor, Unit>(transaction, logger) {
override suspend fun internalExecute(command: DeleteLocalActor, principal: LocalUser) {
if (command.actorId != principal.actorId) {
throw PermissionDeniedException()
}
val findById = actorRepository.findById(command.actorId)
?: throw InternalServerException("Actor ${command.actorId} Not found")
findById.delete()
actorRepository.save(findById)
}
companion object {
private val logger = LoggerFactory.getLogger(StartDeleteLocalActorApplicationService::class.java)
}
}
@@ -1,37 +0,0 @@
/*
* Copyright (C) 2024 usbharu
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package dev.usbharu.hideout.core.application.actor
import dev.usbharu.hideout.core.application.shared.Transaction
import dev.usbharu.hideout.core.domain.model.actor.ActorId
import dev.usbharu.hideout.core.domain.model.actor.ActorRepository
import org.springframework.stereotype.Service
@Service
class SuspendLocalActorApplicationService(
private val transaction: Transaction,
private val actorRepository: ActorRepository,
) {
suspend fun suspend(actorId: Long, executor: ActorId) {
transaction.transaction {
val id = ActorId(actorId)
val findById = actorRepository.findById(id)!!
findById.suspend = true
}
}
}
@@ -1,36 +0,0 @@
/*
* Copyright (C) 2024 usbharu
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package dev.usbharu.hideout.core.application.actor
import dev.usbharu.hideout.core.application.shared.Transaction
import dev.usbharu.hideout.core.domain.model.actor.ActorId
import dev.usbharu.hideout.core.domain.model.actor.ActorRepository
import org.springframework.stereotype.Service
@Service
class UnsuspendLocalActorApplicationService(
private val transaction: Transaction,
private val actorRepository: ActorRepository,
) {
suspend fun unsuspend(actorId: Long, executor: Long) {
transaction.transaction {
val findById = actorRepository.findById(ActorId(actorId))!!
findById.suspend = false
}
}
}
@@ -16,14 +16,17 @@
package dev.usbharu.hideout.core.application.application
import dev.usbharu.hideout.core.application.shared.AbstractApplicationService
import dev.usbharu.hideout.core.application.shared.Transaction
import dev.usbharu.hideout.core.domain.model.application.Application
import dev.usbharu.hideout.core.domain.model.application.ApplicationId
import dev.usbharu.hideout.core.domain.model.application.ApplicationName
import dev.usbharu.hideout.core.domain.model.application.ApplicationRepository
import dev.usbharu.hideout.core.domain.model.support.principal.Principal
import dev.usbharu.hideout.core.domain.service.userdetail.PasswordEncoder
import dev.usbharu.hideout.core.domain.shared.id.IdGenerateService
import dev.usbharu.hideout.core.infrastructure.springframework.oauth2.SecureTokenGenerator
import org.slf4j.LoggerFactory
import org.springframework.security.oauth2.core.AuthorizationGrantType
import org.springframework.security.oauth2.core.ClientAuthenticationMethod
import org.springframework.security.oauth2.server.authorization.client.RegisteredClient
@@ -39,53 +42,56 @@ class RegisterApplicationApplicationService(
private val passwordEncoder: PasswordEncoder,
private val secureTokenGenerator: SecureTokenGenerator,
private val registeredClientRepository: RegisteredClientRepository,
private val transaction: Transaction,
transaction: Transaction,
private val applicationRepository: ApplicationRepository,
) {
suspend fun register(registerApplication: RegisterApplication): RegisteredApplication {
return transaction.transaction {
val id = idGenerateService.generateId()
val clientSecret = secureTokenGenerator.generate()
val registeredClient = RegisteredClient
.withId(id.toString())
.clientId(id.toString())
.clientSecret(passwordEncoder.encode(clientSecret))
.clientName(registerApplication.name)
.clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_POST)
.clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_JWT)
.clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC)
.authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
.authorizationGrantType(AuthorizationGrantType.CLIENT_CREDENTIALS)
.apply {
if (registerApplication.useRefreshToken) {
authorizationGrantType(AuthorizationGrantType.REFRESH_TOKEN)
} else {
tokenSettings(
TokenSettings
.builder()
.accessTokenTimeToLive(Duration.ofSeconds(31536000000))
.build()
)
}
}
.redirectUris { set ->
set.addAll(registerApplication.redirectUris.map { it.toString() })
}
.clientSettings(ClientSettings.builder().requireAuthorizationConsent(true).build())
.scopes { it.addAll(registerApplication.scopes) }
.build()
registeredClientRepository.save(registeredClient)
) : AbstractApplicationService<RegisterApplication, RegisteredApplication>(transaction, logger) {
val application = Application(ApplicationId(id), ApplicationName(registerApplication.name))
override suspend fun internalExecute(command: RegisterApplication, principal: Principal): RegisteredApplication {
val id = idGenerateService.generateId()
val clientSecret = secureTokenGenerator.generate()
val registeredClient = RegisteredClient
.withId(id.toString())
.clientId(id.toString())
.clientSecret(passwordEncoder.encode(clientSecret))
.clientName(command.name)
.clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_POST)
.clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_JWT)
.clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC)
.authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
.authorizationGrantType(AuthorizationGrantType.CLIENT_CREDENTIALS)
.apply {
if (command.useRefreshToken) {
authorizationGrantType(AuthorizationGrantType.REFRESH_TOKEN)
} else {
tokenSettings(
TokenSettings
.builder()
.accessTokenTimeToLive(Duration.ofSeconds(31536000000))
.build()
)
}
}
.redirectUris { set ->
set.addAll(command.redirectUris.map { it.toString() })
}
.clientSettings(ClientSettings.builder().requireAuthorizationConsent(true).build())
.scopes { it.addAll(command.scopes) }
.build()
registeredClientRepository.save(registeredClient)
applicationRepository.save(application)
RegisteredApplication(
id = id,
name = registerApplication.name,
clientSecret = clientSecret,
clientId = id.toString(),
redirectUris = registerApplication.redirectUris
)
}
val application = Application(ApplicationId(id), ApplicationName(command.name))
applicationRepository.save(application)
return RegisteredApplication(
id = id,
name = command.name,
clientSecret = clientSecret,
clientId = id.toString(),
redirectUris = command.redirectUris
)
}
companion object {
private val logger = LoggerFactory.getLogger(RegisterApplicationApplicationService::class.java)
}
}
@@ -0,0 +1,10 @@
package dev.usbharu.hideout.core.application.domainevent.subscribers
import dev.usbharu.hideout.core.domain.shared.domainevent.DomainEvent
import dev.usbharu.hideout.core.domain.shared.domainevent.DomainEventBody
interface DomainEventSubscriber {
fun <T : DomainEventBody> subscribe(eventName: String, domainEventConsumer: DomainEventConsumer<T>)
}
typealias DomainEventConsumer<T> = suspend (DomainEvent<T>) -> Unit
@@ -0,0 +1,5 @@
package dev.usbharu.hideout.core.application.domainevent.subscribers
data class RegisterHomeTimeline(
val userDetailId: Long
)
@@ -0,0 +1,21 @@
package dev.usbharu.hideout.core.application.domainevent.subscribers
import dev.usbharu.hideout.core.domain.event.userdetail.UserDetailEvent
import dev.usbharu.hideout.core.domain.event.userdetail.UserDetailEventBody
import dev.usbharu.hideout.core.domain.model.support.principal.Anonymous
import org.springframework.stereotype.Component
@Component
class RegisterLocalUserSetHomeTimelineSubscriber(
private val domainEventSubscriber: DomainEventSubscriber,
private val userRegisterHomeTimelineApplicationService: UserRegisterHomeTimelineApplicationService
) : Subscriber {
override fun init() {
domainEventSubscriber.subscribe<UserDetailEventBody>(UserDetailEvent.CREATE.eventName) {
userRegisterHomeTimelineApplicationService.execute(
RegisterHomeTimeline(it.body.getUserDetail().id),
Anonymous
)
}
}
}
@@ -0,0 +1,21 @@
package dev.usbharu.hideout.core.application.domainevent.subscribers
import dev.usbharu.hideout.core.application.timeline.SetTimelineToTimelineStoreApplicationService
import dev.usbharu.hideout.core.application.timeline.SetTimleineStore
import dev.usbharu.hideout.core.domain.event.timeline.TimelineEvent
import dev.usbharu.hideout.core.domain.event.timeline.TimelineEventBody
import dev.usbharu.hideout.core.domain.model.support.principal.Anonymous
import org.springframework.stereotype.Component
@Component
class RegisterTimelineSetTimelineStoreSubscriber(
private val domainEventSubscriber: DomainEventSubscriber,
private val setTimelineToTimelineStoreApplicationService: SetTimelineToTimelineStoreApplicationService
) : Subscriber {
override fun init() {
domainEventSubscriber.subscribe<TimelineEventBody>(TimelineEvent.CREATE.eventName) {
setTimelineToTimelineStoreApplicationService.execute(SetTimleineStore(it.body.getTimelineId()), Anonymous)
}
}
}
@@ -0,0 +1,5 @@
package dev.usbharu.hideout.core.application.domainevent.subscribers
interface Subscriber {
fun init()
}
@@ -0,0 +1,12 @@
package dev.usbharu.hideout.core.application.domainevent.subscribers
import org.springframework.boot.ApplicationArguments
import org.springframework.boot.ApplicationRunner
import org.springframework.stereotype.Component
@Component
class SubscriberRunner(private val subscribers: List<Subscriber>) : ApplicationRunner {
override fun run(args: ApplicationArguments?) {
subscribers.forEach { it.init() }
}
}
@@ -0,0 +1,20 @@
package dev.usbharu.hideout.core.application.domainevent.subscribers
import dev.usbharu.hideout.core.application.timeline.AddPost
import dev.usbharu.hideout.core.application.timeline.TimelineAddPostApplicationService
import dev.usbharu.hideout.core.domain.event.post.PostEvent
import dev.usbharu.hideout.core.domain.event.post.PostEventBody
import dev.usbharu.hideout.core.domain.model.support.principal.Anonymous
import org.springframework.stereotype.Component
@Component
class TimelinePostCreateSubscriber(
private val timelineAddPostApplicationService: TimelineAddPostApplicationService,
private val domainEventSubscriber: DomainEventSubscriber,
) : Subscriber {
override fun init() {
domainEventSubscriber.subscribe<PostEventBody>(PostEvent.CREATE.eventName) {
timelineAddPostApplicationService.execute(AddPost(it.body.getPostId()), Anonymous)
}
}
}
@@ -0,0 +1,52 @@
package dev.usbharu.hideout.core.application.domainevent.subscribers
import dev.usbharu.hideout.core.application.exception.InternalServerException
import dev.usbharu.hideout.core.application.timeline.AddTimelineRelationship
import dev.usbharu.hideout.core.application.timeline.UserAddTimelineRelationshipApplicationService
import dev.usbharu.hideout.core.domain.event.relationship.RelationshipEvent
import dev.usbharu.hideout.core.domain.event.relationship.RelationshipEventBody
import dev.usbharu.hideout.core.domain.model.timelinerelationship.TimelineRelationship
import dev.usbharu.hideout.core.domain.model.timelinerelationship.TimelineRelationshipId
import dev.usbharu.hideout.core.domain.model.timelinerelationship.Visible
import dev.usbharu.hideout.core.domain.model.userdetails.UserDetailRepository
import dev.usbharu.hideout.core.domain.shared.id.IdGenerateService
import org.slf4j.LoggerFactory
import org.springframework.stereotype.Component
@Component
class TimelineRelationshipFollowSubscriber(
private val userAddTimelineRelationshipApplicationService: UserAddTimelineRelationshipApplicationService,
private val idGenerateService: IdGenerateService,
private val userDetailRepository: UserDetailRepository,
private val domainEventSubscriber: DomainEventSubscriber
) : Subscriber {
override fun init() {
domainEventSubscriber.subscribe<RelationshipEventBody>(RelationshipEvent.FOLLOW.eventName) {
val relationship = it.body.getRelationship()
val userDetail = userDetailRepository.findByActorId(relationship.actorId.id)
?: throw InternalServerException("Userdetail ${relationship.actorId} not found by actorid.")
if (userDetail.homeTimelineId == null) {
logger.warn("Home timeline for ${relationship.actorId} is not found")
return@subscribe
}
@Suppress("UnsafeCallOnNullableType")
userAddTimelineRelationshipApplicationService.execute(
AddTimelineRelationship(
TimelineRelationship(
TimelineRelationshipId(idGenerateService.generateId()),
userDetail.homeTimelineId!!,
relationship.targetActorId,
Visible.FOLLOWERS
)
),
it.body.principal
)
}
}
companion object {
private val logger = LoggerFactory.getLogger(TimelineRelationshipFollowSubscriber::class.java)
}
}
@@ -0,0 +1,56 @@
package dev.usbharu.hideout.core.application.domainevent.subscribers
import dev.usbharu.hideout.core.application.shared.AbstractApplicationService
import dev.usbharu.hideout.core.application.shared.Transaction
import dev.usbharu.hideout.core.domain.model.support.principal.Principal
import dev.usbharu.hideout.core.domain.model.timeline.*
import dev.usbharu.hideout.core.domain.model.timelinerelationship.TimelineRelationship
import dev.usbharu.hideout.core.domain.model.timelinerelationship.TimelineRelationshipId
import dev.usbharu.hideout.core.domain.model.timelinerelationship.TimelineRelationshipRepository
import dev.usbharu.hideout.core.domain.model.timelinerelationship.Visible
import dev.usbharu.hideout.core.domain.model.userdetails.UserDetailId
import dev.usbharu.hideout.core.domain.model.userdetails.UserDetailRepository
import dev.usbharu.hideout.core.domain.shared.id.IdGenerateService
import org.slf4j.LoggerFactory
import org.springframework.stereotype.Component
@Component
class UserRegisterHomeTimelineApplicationService(
private val userDetailRepository: UserDetailRepository,
private val timelineRepository: TimelineRepository,
private val idGenerateService: IdGenerateService,
transaction: Transaction,
private val timelineRelationshipRepository: TimelineRelationshipRepository
) : AbstractApplicationService<RegisterHomeTimeline, Unit>(transaction, logger) {
override suspend fun internalExecute(command: RegisterHomeTimeline, principal: Principal) {
val userDetail = (
userDetailRepository.findById(UserDetailId(command.userDetailId))
?: throw IllegalArgumentException("UserDetail ${command.userDetailId} not found.")
)
val timeline = Timeline.create(
TimelineId(idGenerateService.generateId()),
UserDetailId(command.userDetailId),
TimelineName("System-LocalUser-HomeTimeline-${command.userDetailId}"),
TimelineVisibility.PRIVATE,
true
)
timelineRepository.save(timeline)
userDetail.homeTimelineId = timeline.id
val timelineRelationship = TimelineRelationship(
TimelineRelationshipId(idGenerateService.generateId()),
timeline.id,
userDetail.actorId,
Visible.DIRECT
)
timelineRelationshipRepository.save(timelineRelationship)
userDetailRepository.save(userDetail)
}
companion object {
private val logger = LoggerFactory.getLogger(UserRegisterHomeTimelineApplicationService::class.java)
}
}
@@ -0,0 +1,14 @@
package dev.usbharu.hideout.core.application.exception
class InternalServerException : RuntimeException {
constructor() : super()
constructor(message: String?) : super(message)
constructor(message: String?, cause: Throwable?) : super(message, cause)
constructor(cause: Throwable?) : super(cause)
constructor(message: String?, cause: Throwable?, enableSuppression: Boolean, writableStackTrace: Boolean) : super(
message,
cause,
enableSuppression,
writableStackTrace
)
}
@@ -0,0 +1,14 @@
package dev.usbharu.hideout.core.application.exception
class PermissionDeniedException : RuntimeException {
constructor() : super()
constructor(message: String?) : super(message)
constructor(message: String?, cause: Throwable?) : super(message, cause)
constructor(cause: Throwable?) : super(cause)
constructor(message: String?, cause: Throwable?, enableSuppression: Boolean, writableStackTrace: Boolean) : super(
message,
cause,
enableSuppression,
writableStackTrace
)
}
@@ -16,22 +16,27 @@
package dev.usbharu.hideout.core.application.filter
import dev.usbharu.hideout.core.application.shared.AbstractApplicationService
import dev.usbharu.hideout.core.application.shared.CommandExecutor
import dev.usbharu.hideout.core.application.exception.PermissionDeniedException
import dev.usbharu.hideout.core.application.shared.LocalUserAbstractApplicationService
import dev.usbharu.hideout.core.application.shared.Transaction
import dev.usbharu.hideout.core.domain.model.filter.FilterId
import dev.usbharu.hideout.core.domain.model.filter.FilterRepository
import dev.usbharu.hideout.core.domain.model.support.principal.LocalUser
import org.slf4j.LoggerFactory
import org.springframework.stereotype.Service
@Service
class UserDeleteFilterApplicationService(private val filterRepository: FilterRepository, transaction: Transaction) :
AbstractApplicationService<DeleteFilter, Unit>(
LocalUserAbstractApplicationService<DeleteFilter, Unit>(
transaction,
logger
) {
override suspend fun internalExecute(command: DeleteFilter, executor: CommandExecutor) {
val filter = filterRepository.findByFilterId(FilterId(command.filterId)) ?: throw Exception("not found")
override suspend fun internalExecute(command: DeleteFilter, principal: LocalUser) {
val filter =
filterRepository.findByFilterId(FilterId(command.filterId)) ?: throw IllegalArgumentException("not found")
if (filter.userDetailId != principal.userDetailId) {
throw PermissionDeniedException()
}
filterRepository.delete(filter)
}
@@ -16,23 +16,27 @@
package dev.usbharu.hideout.core.application.filter
import dev.usbharu.hideout.core.application.shared.AbstractApplicationService
import dev.usbharu.hideout.core.application.shared.CommandExecutor
import dev.usbharu.hideout.core.application.exception.PermissionDeniedException
import dev.usbharu.hideout.core.application.shared.LocalUserAbstractApplicationService
import dev.usbharu.hideout.core.application.shared.Transaction
import dev.usbharu.hideout.core.domain.model.filter.FilterId
import dev.usbharu.hideout.core.domain.model.filter.FilterRepository
import dev.usbharu.hideout.core.domain.model.support.principal.LocalUser
import org.slf4j.LoggerFactory
import org.springframework.stereotype.Service
@Service
class UserGetFilterApplicationService(private val filterRepository: FilterRepository, transaction: Transaction) :
AbstractApplicationService<GetFilter, Filter>(
LocalUserAbstractApplicationService<GetFilter, Filter>(
transaction,
logger
) {
override suspend fun internalExecute(command: GetFilter, executor: CommandExecutor): Filter {
val filter = filterRepository.findByFilterId(FilterId(command.filterId)) ?: throw Exception("Not Found")
override suspend fun internalExecute(command: GetFilter, principal: LocalUser): Filter {
val filter =
filterRepository.findByFilterId(FilterId(command.filterId)) ?: throw IllegalArgumentException("Not Found")
if (filter.userDetailId != principal.userDetailId) {
throw PermissionDeniedException()
}
return Filter.of(filter)
}
@@ -16,13 +16,11 @@
package dev.usbharu.hideout.core.application.filter
import dev.usbharu.hideout.core.application.shared.AbstractApplicationService
import dev.usbharu.hideout.core.application.shared.CommandExecutor
import dev.usbharu.hideout.core.application.shared.LocalUserAbstractApplicationService
import dev.usbharu.hideout.core.application.shared.Transaction
import dev.usbharu.hideout.core.application.shared.UserDetailGettableCommandExecutor
import dev.usbharu.hideout.core.domain.model.filter.*
import dev.usbharu.hideout.core.domain.model.filter.FilterKeyword
import dev.usbharu.hideout.core.domain.model.userdetails.UserDetailId
import dev.usbharu.hideout.core.domain.model.support.principal.LocalUser
import dev.usbharu.hideout.core.domain.shared.id.IdGenerateService
import org.slf4j.LoggerFactory
import org.springframework.stereotype.Service
@@ -33,17 +31,15 @@ class UserRegisterFilterApplicationService(
private val filterRepository: FilterRepository,
transaction: Transaction,
) :
AbstractApplicationService<RegisterFilter, Filter>(
LocalUserAbstractApplicationService<RegisterFilter, Filter>(
transaction,
logger
) {
override suspend fun internalExecute(command: RegisterFilter, executor: CommandExecutor): Filter {
require(executor is UserDetailGettableCommandExecutor)
override suspend fun internalExecute(command: RegisterFilter, principal: LocalUser): Filter {
val filter = dev.usbharu.hideout.core.domain.model.filter.Filter.create(
id = FilterId(idGenerateService.generateId()),
userDetailId = UserDetailId(executor.userDetailId),
userDetailId = principal.userDetailId,
name = FilterName(command.filterName),
filterContext = command.filterContext,
filterAction = command.filterAction,
@@ -0,0 +1,44 @@
package dev.usbharu.hideout.core.application.instance
import dev.usbharu.hideout.core.application.exception.InternalServerException
import dev.usbharu.hideout.core.application.shared.AbstractApplicationService
import dev.usbharu.hideout.core.application.shared.Transaction
import dev.usbharu.hideout.core.config.ApplicationConfig
import dev.usbharu.hideout.core.domain.model.instance.InstanceRepository
import dev.usbharu.hideout.core.domain.model.support.principal.Principal
import org.slf4j.LoggerFactory
import org.springframework.stereotype.Service
@Service
class GetLocalInstanceApplicationService(
private val applicationConfig: ApplicationConfig,
private val instanceRepository: InstanceRepository,
transaction: Transaction
) :
AbstractApplicationService<Unit, Instance>(
transaction,
logger
) {
private var cachedInstance: Instance? = null
override suspend fun internalExecute(command: Unit, principal: Principal): Instance {
if (cachedInstance != null) {
logger.trace("Use cache {}", cachedInstance)
@Suppress("UnsafeCallOnNullableType")
return cachedInstance!!
}
val instance = (
instanceRepository.findByUrl(applicationConfig.url.toURI())
?: throw InternalServerException("Local instance not found.")
)
cachedInstance = Instance.of(instance)
@Suppress("UnsafeCallOnNullableType")
return cachedInstance!!
}
companion object {
private val logger = LoggerFactory.getLogger(GetLocalInstanceApplicationService::class.java)
}
}
@@ -0,0 +1,17 @@
package dev.usbharu.hideout.core.application.instance
import dev.usbharu.hideout.core.domain.model.instance.Instance
import java.net.URI
data class Instance(val id: Long, val name: String, val url: URI, val description: String) {
companion object {
fun of(instance: Instance): dev.usbharu.hideout.core.application.instance.Instance {
return Instance(
instance.id.instanceId,
instance.name.name,
instance.url,
instance.description.description
)
}
}
}
@@ -16,10 +16,10 @@
package dev.usbharu.hideout.core.application.media
import dev.usbharu.hideout.core.application.shared.AbstractApplicationService
import dev.usbharu.hideout.core.application.shared.CommandExecutor
import dev.usbharu.hideout.core.application.shared.LocalUserAbstractApplicationService
import dev.usbharu.hideout.core.application.shared.Transaction
import dev.usbharu.hideout.core.domain.model.media.*
import dev.usbharu.hideout.core.domain.model.support.principal.LocalUser
import dev.usbharu.hideout.core.domain.shared.id.IdGenerateService
import dev.usbharu.hideout.core.external.media.MediaProcessor
import dev.usbharu.hideout.core.external.mediastore.MediaStore
@@ -35,11 +35,11 @@ class UploadMediaApplicationService(
private val mediaRepository: MediaRepository,
private val idGenerateService: IdGenerateService,
transaction: Transaction
) : AbstractApplicationService<UploadMedia, Media>(
) : LocalUserAbstractApplicationService<UploadMedia, Media>(
transaction,
logger
) {
override suspend fun internalExecute(command: UploadMedia, executor: CommandExecutor): Media {
override suspend fun internalExecute(command: UploadMedia, principal: LocalUser): Media {
val process = mediaProcessor.process(command.path, command.name, null)
val id = idGenerateService.generateId()
val thumbnailUri = if (process.thumbnailPath != null) {
@@ -58,7 +58,8 @@ class UploadMediaApplicationService(
type = process.fileType,
mimeType = process.mimeType,
blurHash = process.blurHash?.let { MediaBlurHash(it) },
description = command.description?.let { MediaDescription(it) }
description = command.description?.let { MediaDescription(it) },
actorId = principal.actorId
)
mediaRepository.save(media)
@@ -0,0 +1,31 @@
package dev.usbharu.hideout.core.application.post
import dev.usbharu.hideout.core.domain.model.actor.Actor
import dev.usbharu.hideout.core.domain.model.media.Media
import java.net.URI
data class ActorDetail(
val actorId: Long,
val instanceId: Long,
val name: String,
val domain: String,
val screenName: String,
val url: URI,
val locked: Boolean,
val icon: URI?,
) {
companion object {
fun of(actor: Actor, iconMedia: Media?): ActorDetail {
return ActorDetail(
actorId = actor.id.id,
instanceId = actor.instance.instanceId,
name = actor.name.name,
domain = actor.domain.domain,
screenName = actor.screenName.screenName,
url = actor.url,
locked = actor.locked,
icon = iconMedia?.url
)
}
}
}
@@ -0,0 +1,3 @@
package dev.usbharu.hideout.core.application.post
data class DeleteLocalPost(val postId: Long)
@@ -16,23 +16,37 @@
package dev.usbharu.hideout.core.application.post
import dev.usbharu.hideout.core.application.exception.InternalServerException
import dev.usbharu.hideout.core.application.exception.PermissionDeniedException
import dev.usbharu.hideout.core.application.shared.LocalUserAbstractApplicationService
import dev.usbharu.hideout.core.application.shared.Transaction
import dev.usbharu.hideout.core.domain.model.actor.ActorRepository
import dev.usbharu.hideout.core.domain.model.post.PostId
import dev.usbharu.hideout.core.domain.model.post.PostRepository
import dev.usbharu.hideout.core.domain.model.userdetails.UserDetailRepository
import dev.usbharu.hideout.core.domain.model.support.principal.LocalUser
import org.slf4j.LoggerFactory
import org.springframework.stereotype.Service
@Service
class DeleteLocalPostApplicationService(
private val postRepository: PostRepository,
private val userDetailRepository: UserDetailRepository,
private val actorRepository: ActorRepository,
) {
suspend fun delete(postId: Long, userDetailId: Long) {
val findById = postRepository.findById(PostId(postId))!!
val user = userDetailRepository.findById(userDetailId)!!
val actor = actorRepository.findById(user.actorId)!!
transaction: Transaction,
) : LocalUserAbstractApplicationService<DeleteLocalPost, Unit>(transaction, logger) {
override suspend fun internalExecute(command: DeleteLocalPost, principal: LocalUser) {
val findById = postRepository.findById(PostId(command.postId))
?: throw IllegalArgumentException("Post ${command.postId} not found.")
if (findById.actorId != principal.actorId) {
throw PermissionDeniedException()
}
val actor = actorRepository.findById(principal.actorId)
?: throw InternalServerException("Actor ${principal.actorId} not found.")
findById.delete(actor)
postRepository.save(findById)
}
companion object {
private val logger = LoggerFactory.getLogger(DeleteLocalPostApplicationService::class.java)
}
}
@@ -16,21 +16,29 @@
package dev.usbharu.hideout.core.application.post
import dev.usbharu.hideout.core.application.exception.PermissionDeniedException
import dev.usbharu.hideout.core.application.shared.AbstractApplicationService
import dev.usbharu.hideout.core.application.shared.CommandExecutor
import dev.usbharu.hideout.core.application.shared.Transaction
import dev.usbharu.hideout.core.domain.model.post.PostId
import dev.usbharu.hideout.core.domain.model.post.PostRepository
import dev.usbharu.hideout.core.domain.model.support.principal.Principal
import dev.usbharu.hideout.core.domain.service.post.IPostReadAccessControl
import org.slf4j.LoggerFactory
import org.springframework.stereotype.Service
@Service
class GetPostApplicationService(private val postRepository: PostRepository, transaction: Transaction) :
class GetPostApplicationService(
private val postRepository: PostRepository,
private val iPostReadAccessControl: IPostReadAccessControl,
transaction: Transaction
) :
AbstractApplicationService<GetPost, Post>(transaction, logger) {
override suspend fun internalExecute(command: GetPost, executor: CommandExecutor): Post {
val post = postRepository.findById(PostId(command.postId)) ?: throw Exception("Post not found")
override suspend fun internalExecute(command: GetPost, principal: Principal): Post {
val post = postRepository.findById(PostId(command.postId)) ?: throw IllegalArgumentException("Post not found")
if (iPostReadAccessControl.isAllow(post, principal).not()) {
throw PermissionDeniedException()
}
return Post.of(post)
}
@@ -0,0 +1,3 @@
package dev.usbharu.hideout.core.application.post
data class GetPostDetail(val postId: Long)
@@ -0,0 +1,82 @@
package dev.usbharu.hideout.core.application.post
import dev.usbharu.hideout.core.application.exception.InternalServerException
import dev.usbharu.hideout.core.application.shared.AbstractApplicationService
import dev.usbharu.hideout.core.application.shared.Transaction
import dev.usbharu.hideout.core.domain.model.actor.Actor
import dev.usbharu.hideout.core.domain.model.actor.ActorRepository
import dev.usbharu.hideout.core.domain.model.media.Media
import dev.usbharu.hideout.core.domain.model.media.MediaRepository
import dev.usbharu.hideout.core.domain.model.post.PostId
import dev.usbharu.hideout.core.domain.model.post.PostRepository
import dev.usbharu.hideout.core.domain.model.support.principal.Principal
import dev.usbharu.hideout.core.domain.service.post.IPostReadAccessControl
import org.slf4j.LoggerFactory
import org.springframework.stereotype.Service
@Service
class GetPostDetailApplicationService(
transaction: Transaction,
private val postRepository: PostRepository,
private val actorRepository: ActorRepository,
private val mediaRepository: MediaRepository,
private val iPostReadAccessControl: IPostReadAccessControl
) : AbstractApplicationService<GetPostDetail, PostDetail>(
transaction,
logger
) {
override suspend fun internalExecute(command: GetPostDetail, principal: Principal): PostDetail {
val post = postRepository.findById(PostId(command.postId))
?: throw IllegalArgumentException("Post ${command.postId} not found.")
if (iPostReadAccessControl.isAllow(post, principal).not()) {
throw IllegalArgumentException("Post ${command.postId} not found.")
}
val actor =
actorRepository.findById(post.actorId) ?: throw InternalServerException("Actor ${post.actorId} not found.")
val iconMedia = actor.icon?.let { mediaRepository.findById(it) }
val mediaList = mediaRepository.findByIds(post.mediaIds)
return PostDetail.of(
post = post,
actor = actor,
iconMedia = iconMedia,
mediaList = mediaList,
reply = post.replyId?.let { fetchChild(it, actor, iconMedia, principal) },
repost = post.repostId?.let { fetchChild(it, actor, iconMedia, principal) },
moveTo = post.moveTo?.let { fetchChild(it, actor, iconMedia, principal) },
)
}
private suspend fun fetchChild(
postId: PostId,
actor: Actor,
iconMedia: Media?,
principal: Principal
): PostDetail? {
val post = postRepository.findById(postId) ?: return null
if (iPostReadAccessControl.isAllow(post, principal).not()) {
return null
}
val (first, third) = if (actor.id != post.actorId) {
(actorRepository.findById(post.actorId) ?: return null) to actor.icon?.let { mediaRepository.findById(it) }
} else {
actor to iconMedia
}
val mediaList = mediaRepository.findByIds(post.mediaIds)
return PostDetail.of(
post,
first,
third,
mediaList
)
}
companion object {
private val logger = LoggerFactory.getLogger(GetPostDetailApplicationService::class.java)
}
}
@@ -0,0 +1,30 @@
package dev.usbharu.hideout.core.application.post
import dev.usbharu.hideout.core.domain.model.media.Media
import java.net.URI
data class MediaDetail(
val mediaId: Long,
val type: String,
val url: URI,
val thumbnailUrl: URI?,
val sensitive: Boolean,
val description: String,
val blurhash: String,
val actorId: Long
) {
companion object {
fun of(media: Media): MediaDetail {
return MediaDetail(
mediaId = media.id.id,
type = media.type.name,
url = media.url,
thumbnailUrl = media.thumbnailUrl,
sensitive = false,
description = media.description?.description.orEmpty(),
blurhash = media.blurHash?.hash.orEmpty(),
actorId = media.actorId.id
)
}
}
}
@@ -0,0 +1,59 @@
package dev.usbharu.hideout.core.application.post
import dev.usbharu.hideout.core.domain.model.actor.Actor
import dev.usbharu.hideout.core.domain.model.media.Media
import dev.usbharu.hideout.core.domain.model.post.Post
import dev.usbharu.hideout.core.domain.model.post.Visibility
import java.net.URI
import java.time.Instant
data class PostDetail(
val id: Long,
val actor: ActorDetail,
val overview: String?,
val text: String,
val content: String,
val createdAt: Instant,
val visibility: Visibility,
val pureRepost: Boolean,
val url: URI,
val apId: URI,
val repost: PostDetail?,
val reply: PostDetail?,
val sensitive: Boolean,
val deleted: Boolean,
val mediaDetailList: List<MediaDetail>,
val moveTo: PostDetail?
) {
companion object {
@Suppress("LongParameterList")
fun of(
post: Post,
actor: Actor,
iconMedia: Media?,
mediaList: List<Media>,
reply: PostDetail? = null,
repost: PostDetail? = null,
moveTo: PostDetail? = null,
): PostDetail {
return PostDetail(
id = post.id.id,
actor = ActorDetail.of(actor, iconMedia),
overview = post.overview?.overview,
text = post.text,
content = post.content.content,
createdAt = post.createdAt,
visibility = post.visibility,
pureRepost = post.isPureRepost,
url = post.url,
apId = post.apId,
repost = repost,
reply = reply,
sensitive = post.sensitive,
deleted = false,
mediaDetailList = mediaList.map { MediaDetail.of(it) },
moveTo = moveTo
)
}
}
}
@@ -19,7 +19,6 @@ package dev.usbharu.hideout.core.application.post
import dev.usbharu.hideout.core.domain.model.post.Visibility
data class RegisterLocalPost(
val userDetailId: Long,
val content: String,
val overview: String?,
val visibility: Visibility,
@@ -16,15 +16,15 @@
package dev.usbharu.hideout.core.application.post
import dev.usbharu.hideout.core.application.shared.AbstractApplicationService
import dev.usbharu.hideout.core.application.shared.CommandExecutor
import dev.usbharu.hideout.core.application.exception.InternalServerException
import dev.usbharu.hideout.core.application.shared.LocalUserAbstractApplicationService
import dev.usbharu.hideout.core.application.shared.Transaction
import dev.usbharu.hideout.core.domain.model.actor.ActorRepository
import dev.usbharu.hideout.core.domain.model.media.MediaId
import dev.usbharu.hideout.core.domain.model.post.PostId
import dev.usbharu.hideout.core.domain.model.post.PostOverview
import dev.usbharu.hideout.core.domain.model.post.PostRepository
import dev.usbharu.hideout.core.domain.model.userdetails.UserDetailRepository
import dev.usbharu.hideout.core.domain.model.support.principal.LocalUser
import dev.usbharu.hideout.core.infrastructure.factory.PostFactoryImpl
import org.slf4j.Logger
import org.slf4j.LoggerFactory
@@ -35,17 +35,13 @@ class RegisterLocalPostApplicationService(
private val postFactory: PostFactoryImpl,
private val actorRepository: ActorRepository,
private val postRepository: PostRepository,
private val userDetailRepository: UserDetailRepository,
transaction: Transaction,
) : AbstractApplicationService<RegisterLocalPost, Long>(transaction, Companion.logger) {
) : LocalUserAbstractApplicationService<RegisterLocalPost, Long>(transaction, Companion.logger) {
override suspend fun internalExecute(command: RegisterLocalPost, executor: CommandExecutor): Long {
val actorId = (
userDetailRepository.findById(command.userDetailId)
?: throw IllegalStateException("actor not found")
).actorId
override suspend fun internalExecute(command: RegisterLocalPost, principal: LocalUser): Long {
val actorId = principal.actorId
val actor = actorRepository.findById(actorId)!!
val actor = actorRepository.findById(actorId) ?: throw InternalServerException("Actor $actorId not found.")
val post = postFactory.createLocal(
actor = actor,
@@ -21,5 +21,5 @@ data class UpdateLocalNote(
val overview: String?,
val content: String,
val sensitive: Boolean,
val mediaIds: List<Long>,
val mediaIds: List<Long>
)
@@ -16,15 +16,16 @@
package dev.usbharu.hideout.core.application.post
import dev.usbharu.hideout.core.application.shared.AbstractApplicationService
import dev.usbharu.hideout.core.application.shared.CommandExecutor
import dev.usbharu.hideout.core.application.exception.InternalServerException
import dev.usbharu.hideout.core.application.exception.PermissionDeniedException
import dev.usbharu.hideout.core.application.shared.LocalUserAbstractApplicationService
import dev.usbharu.hideout.core.application.shared.Transaction
import dev.usbharu.hideout.core.application.shared.UserDetailGettableCommandExecutor
import dev.usbharu.hideout.core.domain.model.actor.ActorRepository
import dev.usbharu.hideout.core.domain.model.media.MediaId
import dev.usbharu.hideout.core.domain.model.post.PostId
import dev.usbharu.hideout.core.domain.model.post.PostOverview
import dev.usbharu.hideout.core.domain.model.post.PostRepository
import dev.usbharu.hideout.core.domain.model.support.principal.LocalUser
import dev.usbharu.hideout.core.domain.model.userdetails.UserDetailRepository
import dev.usbharu.hideout.core.infrastructure.factory.PostContentFactoryImpl
import org.slf4j.LoggerFactory
@@ -37,14 +38,19 @@ class UpdateLocalNoteApplicationService(
private val postContentFactoryImpl: PostContentFactoryImpl,
private val userDetailRepository: UserDetailRepository,
private val actorRepository: ActorRepository,
) : AbstractApplicationService<UpdateLocalNote, Unit>(transaction, logger) {
) : LocalUserAbstractApplicationService<UpdateLocalNote, Unit>(transaction, logger) {
override suspend fun internalExecute(command: UpdateLocalNote, executor: CommandExecutor) {
require(executor is UserDetailGettableCommandExecutor)
override suspend fun internalExecute(command: UpdateLocalNote, principal: LocalUser) {
val post = postRepository.findById(PostId(command.postId))
?: throw IllegalArgumentException("Post ${command.postId} not found.")
if (post.actorId != principal.actorId) {
throw PermissionDeniedException()
}
val userDetail = userDetailRepository.findById(executor.userDetailId)!!
val actor = actorRepository.findById(userDetail.actorId)!!
val post = postRepository.findById(PostId(command.postId))!!
val userDetail = userDetailRepository.findById(principal.userDetailId)
?: throw InternalServerException("User detail ${principal.userDetailId} not found.")
val actor = actorRepository.findById(userDetail.actorId)
?: throw InternalServerException("Actor ${principal.actorId} not found.")
post.setContent(postContentFactoryImpl.create(command.content), actor)
post.setOverview(command.overview?.let { PostOverview(it) }, actor)
@@ -16,15 +16,14 @@
package dev.usbharu.hideout.core.application.relationship.acceptfollowrequest
import dev.usbharu.hideout.core.application.exception.InternalServerException
import dev.usbharu.hideout.core.application.relationship.block.UserBlockApplicationService
import dev.usbharu.hideout.core.application.shared.AbstractApplicationService
import dev.usbharu.hideout.core.application.shared.CommandExecutor
import dev.usbharu.hideout.core.application.shared.LocalUserAbstractApplicationService
import dev.usbharu.hideout.core.application.shared.Transaction
import dev.usbharu.hideout.core.application.shared.UserDetailGettableCommandExecutor
import dev.usbharu.hideout.core.domain.model.actor.ActorId
import dev.usbharu.hideout.core.domain.model.actor.ActorRepository
import dev.usbharu.hideout.core.domain.model.relationship.RelationshipRepository
import dev.usbharu.hideout.core.domain.model.userdetails.UserDetailRepository
import dev.usbharu.hideout.core.domain.model.support.principal.LocalUser
import org.slf4j.LoggerFactory
import org.springframework.stereotype.Service
@@ -33,19 +32,16 @@ class UserAcceptFollowRequestApplicationService(
private val relationshipRepository: RelationshipRepository,
transaction: Transaction,
private val actorRepository: ActorRepository,
private val userDetailRepository: UserDetailRepository,
) :
AbstractApplicationService<AcceptFollowRequest, Unit>(transaction, logger) {
override suspend fun internalExecute(command: AcceptFollowRequest, executor: CommandExecutor) {
require(executor is UserDetailGettableCommandExecutor)
val userDetail = userDetailRepository.findById(executor.userDetailId)!!
val actor = actorRepository.findById(userDetail.actorId)!!
LocalUserAbstractApplicationService<AcceptFollowRequest, Unit>(transaction, logger) {
override suspend fun internalExecute(command: AcceptFollowRequest, principal: LocalUser) {
val actor = actorRepository.findById(principal.actorId)
?: throw InternalServerException("Actor ${principal.actorId} not found")
val targetId = ActorId(command.sourceActorId)
val relationship = relationshipRepository.findByActorIdAndTargetId(targetId, actor.id)
?: throw Exception("Follow request not found")
?: throw InternalServerException("Follow request not found")
relationship.acceptFollowRequest()
@@ -16,15 +16,13 @@
package dev.usbharu.hideout.core.application.relationship.block
import dev.usbharu.hideout.core.application.shared.AbstractApplicationService
import dev.usbharu.hideout.core.application.shared.CommandExecutor
import dev.usbharu.hideout.core.application.shared.LocalUserAbstractApplicationService
import dev.usbharu.hideout.core.application.shared.Transaction
import dev.usbharu.hideout.core.application.shared.UserDetailGettableCommandExecutor
import dev.usbharu.hideout.core.domain.model.actor.ActorId
import dev.usbharu.hideout.core.domain.model.actor.ActorRepository
import dev.usbharu.hideout.core.domain.model.relationship.Relationship
import dev.usbharu.hideout.core.domain.model.relationship.RelationshipRepository
import dev.usbharu.hideout.core.domain.model.userdetails.UserDetailRepository
import dev.usbharu.hideout.core.domain.model.support.principal.LocalUser
import dev.usbharu.hideout.core.domain.service.relationship.RelationshipDomainService
import org.slf4j.LoggerFactory
import org.springframework.stereotype.Service
@@ -34,15 +32,12 @@ class UserBlockApplicationService(
private val relationshipRepository: RelationshipRepository,
transaction: Transaction,
private val actorRepository: ActorRepository,
private val userDetailRepository: UserDetailRepository,
private val relationshipDomainService: RelationshipDomainService,
) :
AbstractApplicationService<Block, Unit>(transaction, logger) {
override suspend fun internalExecute(command: Block, executor: CommandExecutor) {
require(executor is UserDetailGettableCommandExecutor)
val userDetail = userDetailRepository.findById(executor.userDetailId)!!
val actor = actorRepository.findById(userDetail.actorId)!!
LocalUserAbstractApplicationService<Block, Unit>(transaction, logger) {
override suspend fun internalExecute(command: Block, principal: LocalUser) {
val actor = actorRepository.findById(principal.actorId)
?: throw IllegalStateException("Actor ${principal.actorId} not found")
val targetId = ActorId(command.targetActorId)
val relationship = relationshipRepository.findByActorIdAndTargetId(actor.id, targetId) ?: Relationship.default(
@@ -16,15 +16,14 @@
package dev.usbharu.hideout.core.application.relationship.followrequest
import dev.usbharu.hideout.core.application.shared.AbstractApplicationService
import dev.usbharu.hideout.core.application.shared.CommandExecutor
import dev.usbharu.hideout.core.application.exception.InternalServerException
import dev.usbharu.hideout.core.application.shared.LocalUserAbstractApplicationService
import dev.usbharu.hideout.core.application.shared.Transaction
import dev.usbharu.hideout.core.application.shared.UserDetailGettableCommandExecutor
import dev.usbharu.hideout.core.domain.model.actor.ActorId
import dev.usbharu.hideout.core.domain.model.actor.ActorRepository
import dev.usbharu.hideout.core.domain.model.relationship.Relationship
import dev.usbharu.hideout.core.domain.model.relationship.RelationshipRepository
import dev.usbharu.hideout.core.domain.model.userdetails.UserDetailRepository
import dev.usbharu.hideout.core.domain.model.support.principal.LocalUser
import org.slf4j.LoggerFactory
import org.springframework.stereotype.Service
@@ -33,17 +32,14 @@ class UserFollowRequestApplicationService(
private val relationshipRepository: RelationshipRepository,
transaction: Transaction,
private val actorRepository: ActorRepository,
private val userDetailRepository: UserDetailRepository,
) : AbstractApplicationService<FollowRequest, Unit>(
) : LocalUserAbstractApplicationService<FollowRequest, Unit>(
transaction,
logger
) {
override suspend fun internalExecute(command: FollowRequest, executor: CommandExecutor) {
require(executor is UserDetailGettableCommandExecutor)
val userDetail = userDetailRepository.findById(executor.userDetailId)!!
val actor = actorRepository.findById(userDetail.actorId)!!
override suspend fun internalExecute(command: FollowRequest, principal: LocalUser) {
val actor = actorRepository.findById(principal.actorId)
?: throw InternalServerException("Actor ${principal.actorId} not found.")
val targetId = ActorId(command.targetActorId)
val relationship = relationshipRepository.findByActorIdAndTargetId(actor.id, targetId) ?: Relationship.default(
@@ -16,16 +16,15 @@
package dev.usbharu.hideout.core.application.relationship.get
import dev.usbharu.hideout.core.application.shared.AbstractApplicationService
import dev.usbharu.hideout.core.application.shared.CommandExecutor
import dev.usbharu.hideout.core.application.exception.InternalServerException
import dev.usbharu.hideout.core.application.shared.LocalUserAbstractApplicationService
import dev.usbharu.hideout.core.application.shared.Transaction
import dev.usbharu.hideout.core.application.shared.UserDetailGettableCommandExecutor
import dev.usbharu.hideout.core.domain.model.actor.ActorId
import dev.usbharu.hideout.core.domain.model.actor.ActorRepository
import dev.usbharu.hideout.core.domain.model.actorinstancerelationship.ActorInstanceRelationship
import dev.usbharu.hideout.core.domain.model.actorinstancerelationship.ActorInstanceRelationshipRepository
import dev.usbharu.hideout.core.domain.model.relationship.RelationshipRepository
import dev.usbharu.hideout.core.domain.model.userdetails.UserDetailRepository
import dev.usbharu.hideout.core.domain.model.support.principal.LocalUser
import org.slf4j.LoggerFactory
import org.springframework.stereotype.Service
@@ -33,29 +32,28 @@ import org.springframework.stereotype.Service
class GetRelationshipApplicationService(
private val relationshipRepository: RelationshipRepository,
private val actorRepository: ActorRepository,
private val userDetailRepository: UserDetailRepository,
private val actorInstanceRelationshipRepository: ActorInstanceRelationshipRepository,
transaction: Transaction,
) :
AbstractApplicationService<GetRelationship, Relationship>(
LocalUserAbstractApplicationService<GetRelationship, Relationship>(
transaction,
logger
) {
override suspend fun internalExecute(command: GetRelationship, executor: CommandExecutor): Relationship {
require(executor is UserDetailGettableCommandExecutor)
val userDetail = userDetailRepository.findById(executor.userDetailId)!!
val actor = actorRepository.findById(userDetail.actorId)!!
override suspend fun internalExecute(command: GetRelationship, principal: LocalUser): Relationship {
val actor = actorRepository.findById(principal.actorId)
?: throw InternalServerException("Actor ${principal.actorId} not found.")
val targetId = ActorId(command.targetActorId)
val target = actorRepository.findById(targetId)!!
val target = actorRepository.findById(targetId)
?: throw IllegalArgumentException("Actor ${command.targetActorId} not found.")
val relationship = (
relationshipRepository.findByActorIdAndTargetId(actor.id, targetId)
?: dev.usbharu.hideout.core.domain.model.relationship.Relationship.default(actor.id, targetId)
)
relationshipRepository.findByActorIdAndTargetId(actor.id, targetId)
?: dev.usbharu.hideout.core.domain.model.relationship.Relationship.default(actor.id, targetId)
)
val relationship1 = (
relationshipRepository.findByActorIdAndTargetId(targetId, actor.id)
?: dev.usbharu.hideout.core.domain.model.relationship.Relationship.default(targetId, actor.id)
)
relationshipRepository.findByActorIdAndTargetId(targetId, actor.id)
?: dev.usbharu.hideout.core.domain.model.relationship.Relationship.default(targetId, actor.id)
)
val actorInstanceRelationship =
actorInstanceRelationshipRepository.findByActorIdAndInstanceId(actor.id, target.instance)
@@ -16,16 +16,15 @@
package dev.usbharu.hideout.core.application.relationship.mute
import dev.usbharu.hideout.core.application.exception.InternalServerException
import dev.usbharu.hideout.core.application.relationship.block.UserBlockApplicationService
import dev.usbharu.hideout.core.application.shared.AbstractApplicationService
import dev.usbharu.hideout.core.application.shared.CommandExecutor
import dev.usbharu.hideout.core.application.shared.LocalUserAbstractApplicationService
import dev.usbharu.hideout.core.application.shared.Transaction
import dev.usbharu.hideout.core.application.shared.UserDetailGettableCommandExecutor
import dev.usbharu.hideout.core.domain.model.actor.ActorId
import dev.usbharu.hideout.core.domain.model.actor.ActorRepository
import dev.usbharu.hideout.core.domain.model.relationship.Relationship
import dev.usbharu.hideout.core.domain.model.relationship.RelationshipRepository
import dev.usbharu.hideout.core.domain.model.userdetails.UserDetailRepository
import dev.usbharu.hideout.core.domain.model.support.principal.LocalUser
import org.slf4j.LoggerFactory
import org.springframework.stereotype.Service
@@ -34,14 +33,11 @@ class UserMuteApplicationService(
private val relationshipRepository: RelationshipRepository,
transaction: Transaction,
private val actorRepository: ActorRepository,
private val userDetailRepository: UserDetailRepository,
) :
AbstractApplicationService<Mute, Unit>(transaction, logger) {
override suspend fun internalExecute(command: Mute, executor: CommandExecutor) {
require(executor is UserDetailGettableCommandExecutor)
val userDetail = userDetailRepository.findById(executor.userDetailId)!!
val actor = actorRepository.findById(userDetail.actorId)!!
LocalUserAbstractApplicationService<Mute, Unit>(transaction, logger) {
override suspend fun internalExecute(command: Mute, principal: LocalUser) {
val actor = actorRepository.findById(principal.actorId)
?: throw InternalServerException("Actor ${principal.actorId} not found.")
val targetId = ActorId(command.targetActorId)
val relationship = relationshipRepository.findByActorIdAndTargetId(actor.id, targetId) ?: Relationship.default(
@@ -16,15 +16,14 @@
package dev.usbharu.hideout.core.application.relationship.rejectfollowrequest
import dev.usbharu.hideout.core.application.exception.InternalServerException
import dev.usbharu.hideout.core.application.relationship.block.UserBlockApplicationService
import dev.usbharu.hideout.core.application.shared.AbstractApplicationService
import dev.usbharu.hideout.core.application.shared.CommandExecutor
import dev.usbharu.hideout.core.application.shared.LocalUserAbstractApplicationService
import dev.usbharu.hideout.core.application.shared.Transaction
import dev.usbharu.hideout.core.application.shared.UserDetailGettableCommandExecutor
import dev.usbharu.hideout.core.domain.model.actor.ActorId
import dev.usbharu.hideout.core.domain.model.actor.ActorRepository
import dev.usbharu.hideout.core.domain.model.relationship.RelationshipRepository
import dev.usbharu.hideout.core.domain.model.userdetails.UserDetailRepository
import dev.usbharu.hideout.core.domain.model.support.principal.LocalUser
import org.slf4j.LoggerFactory
import org.springframework.stereotype.Service
@@ -33,19 +32,16 @@ class UserRejectFollowRequestApplicationService(
private val relationshipRepository: RelationshipRepository,
transaction: Transaction,
private val actorRepository: ActorRepository,
private val userDetailRepository: UserDetailRepository,
) :
AbstractApplicationService<RejectFollowRequest, Unit>(transaction, logger) {
override suspend fun internalExecute(command: RejectFollowRequest, executor: CommandExecutor) {
require(executor is UserDetailGettableCommandExecutor)
val userDetail = userDetailRepository.findById(executor.userDetailId)!!
val actor = actorRepository.findById(userDetail.actorId)!!
LocalUserAbstractApplicationService<RejectFollowRequest, Unit>(transaction, logger) {
override suspend fun internalExecute(command: RejectFollowRequest, principal: LocalUser) {
val actor = actorRepository.findById(principal.actorId)
?: throw InternalServerException("Actor ${principal.actorId} not found.")
val targetId = ActorId(command.sourceActorId)
val relationship = relationshipRepository.findByActorIdAndTargetId(targetId, actor.id)
?: throw Exception("Follow request not found")
?: throw IllegalArgumentException("Follow request not found")
relationship.rejectFollowRequest()
@@ -16,16 +16,15 @@
package dev.usbharu.hideout.core.application.relationship.removefromfollowers
import dev.usbharu.hideout.core.application.exception.InternalServerException
import dev.usbharu.hideout.core.application.relationship.block.UserBlockApplicationService
import dev.usbharu.hideout.core.application.shared.AbstractApplicationService
import dev.usbharu.hideout.core.application.shared.CommandExecutor
import dev.usbharu.hideout.core.application.shared.LocalUserAbstractApplicationService
import dev.usbharu.hideout.core.application.shared.Transaction
import dev.usbharu.hideout.core.application.shared.UserDetailGettableCommandExecutor
import dev.usbharu.hideout.core.domain.model.actor.ActorId
import dev.usbharu.hideout.core.domain.model.actor.ActorRepository
import dev.usbharu.hideout.core.domain.model.relationship.Relationship
import dev.usbharu.hideout.core.domain.model.relationship.RelationshipRepository
import dev.usbharu.hideout.core.domain.model.userdetails.UserDetailRepository
import dev.usbharu.hideout.core.domain.model.support.principal.LocalUser
import org.slf4j.LoggerFactory
import org.springframework.stereotype.Service
@@ -34,14 +33,11 @@ class UserRemoveFromFollowersApplicationService(
private val relationshipRepository: RelationshipRepository,
transaction: Transaction,
private val actorRepository: ActorRepository,
private val userDetailRepository: UserDetailRepository,
) :
AbstractApplicationService<RemoveFromFollowers, Unit>(transaction, logger) {
override suspend fun internalExecute(command: RemoveFromFollowers, executor: CommandExecutor) {
require(executor is UserDetailGettableCommandExecutor)
val userDetail = userDetailRepository.findById(executor.userDetailId)!!
val actor = actorRepository.findById(userDetail.actorId)!!
LocalUserAbstractApplicationService<RemoveFromFollowers, Unit>(transaction, logger) {
override suspend fun internalExecute(command: RemoveFromFollowers, principal: LocalUser) {
val actor = actorRepository.findById(principal.actorId)
?: throw InternalServerException("Actor ${principal.actorId} not found.")
val targetId = ActorId(command.targetActorId)
val relationship = relationshipRepository.findByActorIdAndTargetId(targetId, actor.id) ?: Relationship.default(
@@ -16,16 +16,15 @@
package dev.usbharu.hideout.core.application.relationship.unblock
import dev.usbharu.hideout.core.application.exception.InternalServerException
import dev.usbharu.hideout.core.application.relationship.block.UserBlockApplicationService
import dev.usbharu.hideout.core.application.shared.AbstractApplicationService
import dev.usbharu.hideout.core.application.shared.CommandExecutor
import dev.usbharu.hideout.core.application.shared.LocalUserAbstractApplicationService
import dev.usbharu.hideout.core.application.shared.Transaction
import dev.usbharu.hideout.core.application.shared.UserDetailGettableCommandExecutor
import dev.usbharu.hideout.core.domain.model.actor.ActorId
import dev.usbharu.hideout.core.domain.model.actor.ActorRepository
import dev.usbharu.hideout.core.domain.model.relationship.Relationship
import dev.usbharu.hideout.core.domain.model.relationship.RelationshipRepository
import dev.usbharu.hideout.core.domain.model.userdetails.UserDetailRepository
import dev.usbharu.hideout.core.domain.model.support.principal.LocalUser
import org.slf4j.LoggerFactory
import org.springframework.stereotype.Service
@@ -34,14 +33,11 @@ class UserUnblockApplicationService(
private val relationshipRepository: RelationshipRepository,
transaction: Transaction,
private val actorRepository: ActorRepository,
private val userDetailRepository: UserDetailRepository,
) :
AbstractApplicationService<Unblock, Unit>(transaction, logger) {
override suspend fun internalExecute(command: Unblock, executor: CommandExecutor) {
require(executor is UserDetailGettableCommandExecutor)
val userDetail = userDetailRepository.findById(executor.userDetailId)!!
val actor = actorRepository.findById(userDetail.actorId)!!
LocalUserAbstractApplicationService<Unblock, Unit>(transaction, logger) {
override suspend fun internalExecute(command: Unblock, principal: LocalUser) {
val actor = actorRepository.findById(principal.actorId)
?: throw InternalServerException("Actor ${principal.actorId} not found.")
val targetId = ActorId(command.targetActorId)
val relationship = relationshipRepository.findByActorIdAndTargetId(actor.id, targetId) ?: Relationship.default(
@@ -16,16 +16,15 @@
package dev.usbharu.hideout.core.application.relationship.unfollow
import dev.usbharu.hideout.core.application.exception.InternalServerException
import dev.usbharu.hideout.core.application.relationship.block.UserBlockApplicationService
import dev.usbharu.hideout.core.application.shared.AbstractApplicationService
import dev.usbharu.hideout.core.application.shared.CommandExecutor
import dev.usbharu.hideout.core.application.shared.LocalUserAbstractApplicationService
import dev.usbharu.hideout.core.application.shared.Transaction
import dev.usbharu.hideout.core.application.shared.UserDetailGettableCommandExecutor
import dev.usbharu.hideout.core.domain.model.actor.ActorId
import dev.usbharu.hideout.core.domain.model.actor.ActorRepository
import dev.usbharu.hideout.core.domain.model.relationship.Relationship
import dev.usbharu.hideout.core.domain.model.relationship.RelationshipRepository
import dev.usbharu.hideout.core.domain.model.userdetails.UserDetailRepository
import dev.usbharu.hideout.core.domain.model.support.principal.LocalUser
import org.slf4j.LoggerFactory
import org.springframework.stereotype.Service
@@ -34,14 +33,11 @@ class UserUnfollowApplicationService(
private val relationshipRepository: RelationshipRepository,
transaction: Transaction,
private val actorRepository: ActorRepository,
private val userDetailRepository: UserDetailRepository,
) :
AbstractApplicationService<Unfollow, Unit>(transaction, logger) {
override suspend fun internalExecute(command: Unfollow, executor: CommandExecutor) {
require(executor is UserDetailGettableCommandExecutor)
val userDetail = userDetailRepository.findById(executor.userDetailId)!!
val actor = actorRepository.findById(userDetail.actorId)!!
LocalUserAbstractApplicationService<Unfollow, Unit>(transaction, logger) {
override suspend fun internalExecute(command: Unfollow, principal: LocalUser) {
val actor = actorRepository.findById(principal.actorId)
?: throw InternalServerException("Actor ${principal.actorId} not found.")
val targetId = ActorId(command.targetActorId)
val relationship = relationshipRepository.findByActorIdAndTargetId(actor.id, targetId) ?: Relationship.default(
@@ -16,16 +16,15 @@
package dev.usbharu.hideout.core.application.relationship.unmute
import dev.usbharu.hideout.core.application.exception.InternalServerException
import dev.usbharu.hideout.core.application.relationship.block.UserBlockApplicationService
import dev.usbharu.hideout.core.application.shared.AbstractApplicationService
import dev.usbharu.hideout.core.application.shared.CommandExecutor
import dev.usbharu.hideout.core.application.shared.LocalUserAbstractApplicationService
import dev.usbharu.hideout.core.application.shared.Transaction
import dev.usbharu.hideout.core.application.shared.UserDetailGettableCommandExecutor
import dev.usbharu.hideout.core.domain.model.actor.ActorId
import dev.usbharu.hideout.core.domain.model.actor.ActorRepository
import dev.usbharu.hideout.core.domain.model.relationship.Relationship
import dev.usbharu.hideout.core.domain.model.relationship.RelationshipRepository
import dev.usbharu.hideout.core.domain.model.userdetails.UserDetailRepository
import dev.usbharu.hideout.core.domain.model.support.principal.LocalUser
import org.slf4j.LoggerFactory
import org.springframework.stereotype.Service
@@ -34,18 +33,11 @@ class UserUnmuteApplicationService(
private val relationshipRepository: RelationshipRepository,
transaction: Transaction,
private val actorRepository: ActorRepository,
private val userDetailRepository: UserDetailRepository,
) :
AbstractApplicationService<Unmute, Unit>(transaction, logger) {
companion object {
private val logger = LoggerFactory.getLogger(UserBlockApplicationService::class.java)
}
override suspend fun internalExecute(command: Unmute, executor: CommandExecutor) {
require(executor is UserDetailGettableCommandExecutor)
val userDetail = userDetailRepository.findById(executor.userDetailId)!!
val actor = actorRepository.findById(userDetail.actorId)!!
LocalUserAbstractApplicationService<Unmute, Unit>(transaction, logger) {
override suspend fun internalExecute(command: Unmute, principal: LocalUser) {
val actor = actorRepository.findById(principal.actorId)
?: throw InternalServerException("Actor ${principal.actorId} not found.")
val targetId = ActorId(command.targetActorId)
val relationship = relationshipRepository.findByActorIdAndTargetId(actor.id, targetId) ?: Relationship.default(
@@ -57,4 +49,8 @@ class UserUnmuteApplicationService(
relationshipRepository.save(relationship)
}
companion object {
private val logger = LoggerFactory.getLogger(UserBlockApplicationService::class.java)
}
}
@@ -16,6 +16,7 @@
package dev.usbharu.hideout.core.application.shared
import dev.usbharu.hideout.core.domain.model.support.principal.Principal
import kotlinx.coroutines.CancellationException
import org.slf4j.Logger
@@ -23,22 +24,23 @@ abstract class AbstractApplicationService<T : Any, R>(
protected val transaction: Transaction,
protected val logger: Logger,
) : ApplicationService<T, R> {
override suspend fun execute(command: T, executor: CommandExecutor): R {
override suspend fun execute(command: T, principal: Principal): R {
return try {
logger.debug("START {} by {}", command::class.simpleName, executor)
logger.debug("START {}", command::class.simpleName)
val response = transaction.transaction<R> {
internalExecute(command, executor)
internalExecute(command, principal)
}
logger.info("SUCCESS ${command::class.simpleName} by ${executor.executor}")
logger.info("SUCCESS $command $response")
response
} catch (e: CancellationException) {
logger.debug("Coroutine canceled", e)
throw e
} catch (e: Exception) {
} catch (@Suppress("TooGenericExceptionCaught") e: Exception) {
logger.warn("Command execution error", e)
throw e
}
}
protected abstract suspend fun internalExecute(command: T, executor: CommandExecutor): R
protected abstract suspend fun internalExecute(command: T, principal: Principal): R
}
@@ -16,6 +16,8 @@
package dev.usbharu.hideout.core.application.shared
import dev.usbharu.hideout.core.domain.model.support.principal.Principal
interface ApplicationService<T : Any, R> {
suspend fun execute(command: T, executor: CommandExecutor): R
suspend fun execute(command: T, principal: Principal): R
}
@@ -1,25 +0,0 @@
/*
* Copyright (C) 2024 usbharu
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package dev.usbharu.hideout.core.application.shared
interface CommandExecutor {
val executor: String
}
interface UserDetailGettableCommandExecutor : CommandExecutor {
val userDetailId: Long
}
@@ -0,0 +1,18 @@
package dev.usbharu.hideout.core.application.shared
import dev.usbharu.hideout.core.application.exception.PermissionDeniedException
import dev.usbharu.hideout.core.domain.model.support.principal.LocalUser
import dev.usbharu.hideout.core.domain.model.support.principal.Principal
import org.slf4j.Logger
abstract class LocalUserAbstractApplicationService<T : Any, R>(transaction: Transaction, logger: Logger) :
AbstractApplicationService<T, R>(transaction, logger) {
override suspend fun internalExecute(command: T, principal: Principal): R {
if (principal !is LocalUser) {
throw PermissionDeniedException()
}
return internalExecute(command, principal)
}
protected abstract suspend fun internalExecute(command: T, principal: LocalUser): R
}
@@ -0,0 +1,5 @@
package dev.usbharu.hideout.core.application.timeline
import dev.usbharu.hideout.core.domain.model.post.PostId
data class AddPost(val postId: PostId)
@@ -0,0 +1,7 @@
package dev.usbharu.hideout.core.application.timeline
import dev.usbharu.hideout.core.domain.model.timelinerelationship.TimelineRelationship
data class AddTimelineRelationship(
val timelineRelationship: TimelineRelationship
)
@@ -0,0 +1,5 @@
package dev.usbharu.hideout.core.application.timeline
import dev.usbharu.hideout.core.domain.model.support.page.Page
data class GetUserTimeline(val id: Long, val page: Page)
@@ -0,0 +1,53 @@
package dev.usbharu.hideout.core.application.timeline
import dev.usbharu.hideout.core.application.post.PostDetail
import dev.usbharu.hideout.core.application.shared.AbstractApplicationService
import dev.usbharu.hideout.core.application.shared.Transaction
import dev.usbharu.hideout.core.domain.model.actor.ActorId
import dev.usbharu.hideout.core.domain.model.post.PostId
import dev.usbharu.hideout.core.domain.model.post.PostRepository
import dev.usbharu.hideout.core.domain.model.post.Visibility
import dev.usbharu.hideout.core.domain.model.support.page.PaginationList
import dev.usbharu.hideout.core.domain.model.support.principal.Principal
import dev.usbharu.hideout.core.query.usertimeline.UserTimelineQueryService
import org.slf4j.LoggerFactory
import org.springframework.stereotype.Service
@Service
class GetUserTimelineApplicationService(
private val userTimelineQueryService: UserTimelineQueryService,
private val postRepository: PostRepository,
transaction: Transaction
) :
AbstractApplicationService<GetUserTimeline, PaginationList<PostDetail, PostId>>(transaction, logger) {
override suspend fun internalExecute(
command: GetUserTimeline,
principal: Principal
): PaginationList<PostDetail, PostId> {
val postList = postRepository.findByActorIdAndVisibilityInList(
ActorId(command.id),
listOf(Visibility.PUBLIC, Visibility.UNLISTED, Visibility.FOLLOWERS),
command.page
)
val postIdList =
postList.mapNotNull { it.repostId } + postList.mapNotNull { it.replyId } + postList.map { it.id }
val postDetailMap = userTimelineQueryService.findByIdAll(postIdList, principal).associateBy { it.id }
return PaginationList(
postList.mapNotNull {
postDetailMap[it.id.id]?.copy(
repost = postDetailMap[it.repostId?.id],
reply = postDetailMap[it.replyId?.id]
)
},
postList.next,
postList.prev
)
}
companion object {
private val logger = LoggerFactory.getLogger(GetUserTimelineApplicationService::class.java)
}
}
@@ -0,0 +1,11 @@
package dev.usbharu.hideout.core.application.timeline
import dev.usbharu.hideout.core.domain.model.support.page.Page
data class ReadTimeline(
val timelineId: Long,
val mediaOnly: Boolean,
val localOnly: Boolean,
val remoteOnly: Boolean,
val page: Page
)
@@ -0,0 +1,84 @@
package dev.usbharu.hideout.core.application.timeline
import dev.usbharu.hideout.core.application.post.PostDetail
import dev.usbharu.hideout.core.application.shared.AbstractApplicationService
import dev.usbharu.hideout.core.application.shared.Transaction
import dev.usbharu.hideout.core.domain.model.post.PostId
import dev.usbharu.hideout.core.domain.model.support.page.PaginationList
import dev.usbharu.hideout.core.domain.model.support.principal.Principal
import dev.usbharu.hideout.core.domain.model.timeline.TimelineId
import dev.usbharu.hideout.core.domain.model.timeline.TimelineRepository
import dev.usbharu.hideout.core.external.timeline.ReadTimelineOption
import dev.usbharu.hideout.core.external.timeline.TimelineStore
import org.slf4j.LoggerFactory
import org.springframework.stereotype.Service
@Service
class ReadTimelineApplicationService(
private val timelineStore: TimelineStore,
private val timelineRepository: TimelineRepository,
transaction: Transaction
) :
AbstractApplicationService<ReadTimeline, PaginationList<PostDetail, PostId>>(transaction, logger) {
override suspend fun internalExecute(
command: ReadTimeline,
principal: Principal
): PaginationList<PostDetail, PostId> {
val findById = timelineRepository.findById(TimelineId(command.timelineId))
?: throw IllegalArgumentException("Timeline ${command.timelineId} not found.")
val readTimelineOption = ReadTimelineOption(
command.mediaOnly,
command.localOnly,
command.remoteOnly
)
val timeline = timelineStore.readTimeline(
findById,
readTimelineOption,
command.page,
principal,
)
val postDetailList = timeline.map {
val reply = if (it.replyPost != null) {
@Suppress("UnsafeCallOnNullableType")
PostDetail.of(
it.replyPost,
it.replyPostActor!!,
it.replyPostActorIconMedia,
it.replyPostMedias.orEmpty()
)
} else {
null
}
val repost = if (it.repostPost != null) {
@Suppress("UnsafeCallOnNullableType")
PostDetail.of(
it.repostPost,
it.repostPostActor!!,
it.repostPostActorIconMedia,
it.repostPostMedias.orEmpty()
)
} else {
null
}
PostDetail.of(
post = it.post,
actor = it.postActor,
iconMedia = it.postActorIconMedia,
mediaList = it.postMedias,
reply = reply,
repost = repost
)
}
return PaginationList(postDetailList, timeline.next, timeline.prev)
}
companion object {
private val logger = LoggerFactory.getLogger(ReadTimelineApplicationService::class.java)
}
}
@@ -0,0 +1,8 @@
package dev.usbharu.hideout.core.application.timeline
import dev.usbharu.hideout.core.domain.model.timeline.TimelineVisibility
data class RegisterTimeline(
val timelineName: String,
val visibility: TimelineVisibility
)
@@ -0,0 +1,30 @@
package dev.usbharu.hideout.core.application.timeline
import dev.usbharu.hideout.core.application.shared.AbstractApplicationService
import dev.usbharu.hideout.core.application.shared.Transaction
import dev.usbharu.hideout.core.domain.model.support.principal.Principal
import dev.usbharu.hideout.core.domain.model.timeline.TimelineRepository
import dev.usbharu.hideout.core.external.timeline.TimelineStore
import org.slf4j.LoggerFactory
import org.springframework.stereotype.Component
@Component
class SetTimelineToTimelineStoreApplicationService(
transaction: Transaction,
private val timelineStore: TimelineStore,
private val timelineRepository: TimelineRepository
) :
AbstractApplicationService<SetTimleineStore, Unit>(
transaction,
logger
) {
override suspend fun internalExecute(command: SetTimleineStore, principal: Principal) {
val findById = timelineRepository.findById(command.timelineId)
?: throw IllegalArgumentException("Timeline ${command.timelineId} not found")
timelineStore.addTimeline(findById, emptyList())
}
companion object {
private val logger = LoggerFactory.getLogger(SetTimelineToTimelineStoreApplicationService::class.java)
}
}
@@ -0,0 +1,5 @@
package dev.usbharu.hideout.core.application.timeline
import dev.usbharu.hideout.core.domain.model.timeline.TimelineId
data class SetTimleineStore(val timelineId: TimelineId)
@@ -0,0 +1,29 @@
package dev.usbharu.hideout.core.application.timeline
import dev.usbharu.hideout.core.application.shared.AbstractApplicationService
import dev.usbharu.hideout.core.application.shared.Transaction
import dev.usbharu.hideout.core.domain.model.post.PostRepository
import dev.usbharu.hideout.core.domain.model.support.principal.Principal
import dev.usbharu.hideout.core.external.timeline.TimelineStore
import org.slf4j.LoggerFactory
import org.springframework.stereotype.Component
@Component
class TimelineAddPostApplicationService(
private val timelineStore: TimelineStore,
private val postRepository: PostRepository,
transaction: Transaction
) : AbstractApplicationService<AddPost, Unit>(
transaction,
logger
) {
override suspend fun internalExecute(command: AddPost, principal: Principal) {
val findById = postRepository.findById(command.postId)
?: throw IllegalArgumentException("Post ${command.postId} not found.")
timelineStore.addPost(findById)
}
companion object {
private val logger = LoggerFactory.getLogger(TimelineAddPostApplicationService::class.java)
}
}
@@ -0,0 +1,26 @@
package dev.usbharu.hideout.core.application.timeline
import dev.usbharu.hideout.core.application.shared.LocalUserAbstractApplicationService
import dev.usbharu.hideout.core.application.shared.Transaction
import dev.usbharu.hideout.core.domain.model.support.principal.LocalUser
import dev.usbharu.hideout.core.domain.model.timelinerelationship.TimelineRelationshipRepository
import org.slf4j.LoggerFactory
import org.springframework.stereotype.Service
@Service
class UserAddTimelineRelationshipApplicationService(
private val timelineRelationshipRepository: TimelineRelationshipRepository,
transaction: Transaction
) :
LocalUserAbstractApplicationService<AddTimelineRelationship, Unit>(
transaction,
logger
) {
override suspend fun internalExecute(command: AddTimelineRelationship, principal: LocalUser) {
timelineRelationshipRepository.save(command.timelineRelationship)
}
companion object {
private val logger = LoggerFactory.getLogger(UserAddTimelineRelationshipApplicationService::class.java)
}
}
@@ -0,0 +1,37 @@
package dev.usbharu.hideout.core.application.timeline
import dev.usbharu.hideout.core.application.shared.LocalUserAbstractApplicationService
import dev.usbharu.hideout.core.application.shared.Transaction
import dev.usbharu.hideout.core.domain.model.support.principal.LocalUser
import dev.usbharu.hideout.core.domain.model.timeline.Timeline
import dev.usbharu.hideout.core.domain.model.timeline.TimelineId
import dev.usbharu.hideout.core.domain.model.timeline.TimelineName
import dev.usbharu.hideout.core.domain.model.timeline.TimelineRepository
import dev.usbharu.hideout.core.domain.shared.id.IdGenerateService
import org.slf4j.LoggerFactory
import org.springframework.stereotype.Component
@Component
class UserRegisterTimelineApplicationService(
private val idGenerateService: IdGenerateService,
private val timelineRepository: TimelineRepository,
transaction: Transaction
) :
LocalUserAbstractApplicationService<RegisterTimeline, TimelineId>(transaction, logger) {
override suspend fun internalExecute(command: RegisterTimeline, principal: LocalUser): TimelineId {
val timeline = Timeline.create(
id = TimelineId(idGenerateService.generateId()),
userDetailId = principal.userDetailId,
name = TimelineName(command.timelineName),
visibility = command.visibility,
isSystem = false
)
timelineRepository.save(timeline)
return timeline.id
}
companion object {
private val logger = LoggerFactory.getLogger(UserRegisterTimelineApplicationService::class.java)
}
}
@@ -0,0 +1,8 @@
package dev.usbharu.hideout.core.config
import org.springframework.boot.context.properties.ConfigurationProperties
@ConfigurationProperties("hideout.timeline.default")
data class DefaultTimelineStoreConfig(
val actorPostsCount: Int = 500
)
@@ -0,0 +1,16 @@
package dev.usbharu.hideout.core.config
import org.springframework.boot.autoconfigure.flyway.FlywayMigrationStrategy
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
@Configuration
class FlywayConfig {
@Bean
fun cleanMigrateStrategy(): FlywayMigrationStrategy {
return FlywayMigrationStrategy { migrate ->
migrate.repair()
migrate.migrate()
}
}
}
@@ -0,0 +1,26 @@
package dev.usbharu.hideout.core.config
import org.springframework.boot.autoconfigure.context.MessageSourceProperties
import org.springframework.boot.context.properties.ConfigurationProperties
import org.springframework.context.MessageSource
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.context.annotation.Profile
import org.springframework.context.support.ReloadableResourceBundleMessageSource
@Configuration
@Profile("dev")
class MessageSourceConfig {
@Bean
fun messageSource(messageSourceProperties: MessageSourceProperties): MessageSource {
val reloadableResourceBundleMessageSource = ReloadableResourceBundleMessageSource()
reloadableResourceBundleMessageSource.setBasename("classpath:" + messageSourceProperties.basename)
reloadableResourceBundleMessageSource.setCacheSeconds(0)
return reloadableResourceBundleMessageSource
}
@Bean
@Profile("dev")
@ConfigurationProperties(prefix = "spring.messages")
fun messageSourceProperties(): MessageSourceProperties = MessageSourceProperties()
}
@@ -23,6 +23,7 @@ import com.nimbusds.jose.jwk.source.JWKSource
import com.nimbusds.jose.proc.SecurityContext
import dev.usbharu.hideout.core.infrastructure.springframework.oauth2.HideoutUserDetails
import dev.usbharu.hideout.util.RsaUtil
import org.slf4j.LoggerFactory
import org.springframework.boot.context.properties.ConfigurationProperties
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
@@ -50,9 +51,13 @@ import org.springframework.security.oauth2.server.authorization.token.JwtEncodin
import org.springframework.security.oauth2.server.authorization.token.OAuth2TokenCustomizer
import org.springframework.security.web.SecurityFilterChain
import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint
import java.security.KeyPairGenerator
import java.security.interfaces.RSAPrivateKey
import java.security.interfaces.RSAPublicKey
import java.util.*
@Configuration
@EnableWebSecurity(debug = true)
@EnableWebSecurity(debug = false)
class SecurityConfig {
@Bean
fun passwordEncoder(): PasswordEncoder = BCryptPasswordEncoder()
@@ -63,7 +68,7 @@ class SecurityConfig {
OAuth2AuthorizationServerConfiguration.applyDefaultSecurity(http)
http {
exceptionHandling {
authenticationEntryPoint = LoginUrlAuthenticationEntryPoint("/login")
authenticationEntryPoint = LoginUrlAuthenticationEntryPoint("/auth/sign_in")
}
}
return http.build()
@@ -75,16 +80,29 @@ class SecurityConfig {
http {
authorizeHttpRequests {
authorize("/error", permitAll)
authorize("/login", permitAll)
authorize("/auth/sign_in", permitAll)
authorize(GET, "/.well-known/**", permitAll)
authorize(GET, "/nodeinfo/2.0", permitAll)
authorize(GET, "/auth/sign_up", hasRole("ANONYMOUS"))
authorize(POST, "/auth/sign_up", permitAll)
authorize(GET, "/users/{username}/posts/{postId}", permitAll)
authorize(GET, "/users/{userid}", permitAll)
authorize(GET, "/files/*", permitAll)
authorize(POST, "/publish", authenticated)
authorize(GET, "/publish", authenticated)
authorize(GET, "/", permitAll)
authorize(anyRequest, authenticated)
}
formLogin {
loginPage = "/auth/sign_in"
loginProcessingUrl = "/login"
defaultSuccessUrl("/home", false)
}
logout {
logoutUrl = "/auth/sign_out"
logoutSuccessUrl = "/auth/sign_in"
}
}
return http.build()
@@ -122,17 +140,55 @@ class SecurityConfig {
}
@Bean
fun loadJwkSource(jwkConfig: JwkConfig): JWKSource<SecurityContext> {
val rsaKey = RSAKey.Builder(RsaUtil.decodeRsaPublicKey(jwkConfig.publicKey))
.privateKey(RsaUtil.decodeRsaPrivateKey(jwkConfig.privateKey)).keyID(jwkConfig.keyId).build()
@Suppress("UnsafeCallOnNullableType")
fun loadJwkSource(jwkConfig: JwkConfig, applicationConfig: ApplicationConfig): JWKSource<SecurityContext> {
if (jwkConfig.keyId == null) {
logger.error("hideout.security.jwt.keyId is null.")
}
if (jwkConfig.publicKey == null) {
logger.error("hideout.security.jwt.publicKey is null.")
}
if (jwkConfig.privateKey == null) {
logger.error("hideout.security.jwt.privateKey is null.")
}
if (jwkConfig.keyId == null || jwkConfig.publicKey == null || jwkConfig.privateKey == null) {
val keyPairGenerator = KeyPairGenerator.getInstance("RSA")
keyPairGenerator.initialize(applicationConfig.keySize)
val generateKeyPair = keyPairGenerator.generateKeyPair()
jwkConfig.keyId = UUID.randomUUID().toString()
jwkConfig.publicKey = RsaUtil.encodeRsaPublicKey(generateKeyPair.public as RSAPublicKey)
jwkConfig.privateKey = RsaUtil.encodeRsaPrivateKey(generateKeyPair.private as RSAPrivateKey)
logger.error(
"""
|==============
|==============
|
|**Write the following settings in application.yml**
|
|hideout:
| security:
| jwt:
| keyId: ${jwkConfig.keyId}
| publicKey: ${jwkConfig.publicKey}
| privateKey: ${jwkConfig.privateKey}
|
|==============
|==============
""".trimMargin()
)
}
val rsaKey = RSAKey.Builder(RsaUtil.decodeRsaPublicKey(jwkConfig.publicKey!!))
.privateKey(RsaUtil.decodeRsaPrivateKey(jwkConfig.privateKey!!)).keyID(jwkConfig.keyId).build()
return ImmutableJWKSet(JWKSet(rsaKey))
}
@ConfigurationProperties("hideout.security.jwt")
data class JwkConfig(
val keyId: String,
val publicKey: String,
val privateKey: String,
var keyId: String?,
var publicKey: String?,
var privateKey: String?,
)
@Bean
@@ -191,4 +247,8 @@ class SecurityConfig {
return roleHierarchyImpl
}
companion object {
private val logger = LoggerFactory.getLogger(SecurityConfig::class.java)
}
}
@@ -16,20 +16,29 @@
package dev.usbharu.hideout.core.config
import dev.usbharu.hideout.core.infrastructure.springframework.SPAInterceptor
import dev.usbharu.hideout.generate.JsonOrFormModelMethodProcessor
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.http.converter.HttpMessageConverter
import org.springframework.web.method.support.HandlerMethodArgumentResolver
import org.springframework.web.servlet.config.annotation.InterceptorRegistry
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer
import org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor
import org.springframework.web.servlet.mvc.method.annotation.ServletModelAttributeMethodProcessor
@Configuration
class MvcConfigurer(private val jsonOrFormModelMethodProcessor: JsonOrFormModelMethodProcessor) : WebMvcConfigurer {
class MvcConfigurer(
private val jsonOrFormModelMethodProcessor: JsonOrFormModelMethodProcessor,
private val spaInterceptor: SPAInterceptor
) : WebMvcConfigurer {
override fun addArgumentResolvers(resolvers: MutableList<HandlerMethodArgumentResolver>) {
resolvers.add(jsonOrFormModelMethodProcessor)
}
override fun addInterceptors(registry: InterceptorRegistry) {
registry.addInterceptor(spaInterceptor)
}
}
@Configuration
@@ -17,23 +17,24 @@
package dev.usbharu.hideout.core.domain.event.actor
import dev.usbharu.hideout.core.domain.model.actor.Actor
import dev.usbharu.hideout.core.domain.model.actor.ActorId
import dev.usbharu.hideout.core.domain.shared.domainevent.DomainEvent
import dev.usbharu.hideout.core.domain.shared.domainevent.DomainEventBody
class ActorDomainEventFactory(private val actor: Actor) {
fun createEvent(actorEvent: ActorEvent): DomainEvent {
fun createEvent(actorEvent: ActorEvent): DomainEvent<ActorEventBody> {
return DomainEvent.create(
actorEvent.eventName,
ActorEventBody(actor),
ActorEventBody(actor.id),
actorEvent.collectable
)
}
}
class ActorEventBody(actor: Actor) : DomainEventBody(
class ActorEventBody(actor: ActorId) : DomainEventBody(
mapOf(
"actor" to actor
)
),
)
enum class ActorEvent(val eventName: String, val collectable: Boolean = true) {
@@ -21,7 +21,9 @@ import dev.usbharu.hideout.core.domain.shared.domainevent.DomainEvent
import dev.usbharu.hideout.core.domain.shared.domainevent.DomainEventBody
class ActorInstanceRelationshipDomainEventFactory(private val actorInstanceRelationship: ActorInstanceRelationship) {
fun createEvent(actorInstanceRelationshipEvent: ActorInstanceRelationshipEvent): DomainEvent {
fun createEvent(
actorInstanceRelationshipEvent: ActorInstanceRelationshipEvent
): DomainEvent<ActorInstanceRelationshipEventBody> {
return DomainEvent.create(
actorInstanceRelationshipEvent.eventName,
ActorInstanceRelationshipEventBody(actorInstanceRelationship)
@@ -37,7 +39,7 @@ class ActorInstanceRelationshipEventBody(actorInstanceRelationship: ActorInstanc
"muting" to actorInstanceRelationship.muting,
"blocking" to actorInstanceRelationship.blocking,
"doNotSendPrivate" to actorInstanceRelationship.doNotSendPrivate,
)
),
)
enum class ActorInstanceRelationshipEvent(val eventName: String) {
@@ -21,7 +21,7 @@ import dev.usbharu.hideout.core.domain.shared.domainevent.DomainEvent
import dev.usbharu.hideout.core.domain.shared.domainevent.DomainEventBody
class InstanceEventFactory(private val instance: Instance) {
fun createEvent(event: InstanceEvent): DomainEvent {
fun createEvent(event: InstanceEvent): DomainEvent<InstanceEventBody> {
return DomainEvent.create(
event.eventName,
InstanceEventBody(instance)

Some files were not shown because too many files have changed in this diff Show More