mirror of
https://github.com/usbharu/Hideout.git
synced 2026-07-07 05:58:23 +00:00
Compare commits
315 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
1ac8a93619
|
|||
|
a284f4359e
|
|||
|
3a49b2ce9a
|
|||
|
5ae4d1577a
|
|||
| 20a762b8f4 | |||
|
da106a6922
|
|||
|
ee23ce8b82
|
|||
|
4acc1653d1
|
|||
|
4d86cc0e41
|
|||
| 92b6418202 | |||
| f86a224ed2 | |||
| 5036e01c89 | |||
| ed41c025cf | |||
|
c8a8e77021
|
|||
|
48d325deed
|
|||
|
df6d2940ed
|
|||
|
aa34fb0370
|
|||
|
7b77b097ca
|
|||
| fc8cb156da | |||
|
15cb1375c8
|
|||
|
4f9c431d9b
|
|||
|
fec59ab622
|
|||
|
975fd5160b
|
|||
| 57afdcdd7b | |||
| ec565039d1 | |||
| 4c5344426b | |||
| 0cf8185e50 | |||
| 140351f5e7 | |||
| 9c445fba8c | |||
| 79a10a27fc | |||
| baba7e8c0e | |||
|
0463ad6b69
|
|||
| c94bb81fb2 | |||
| 8f3008b96c | |||
| e9bac27608 | |||
| 37de9ccd00 | |||
| efb07f5927 | |||
|
992cc18c62
|
|||
| b7caf11e3e | |||
| f0d8ee979d | |||
|
c48694ab0b
|
|||
|
533582534f
|
|||
| bd219b62e1 | |||
|
92a9bbcfdb
|
|||
| 623e56bb91 | |||
|
3b8156e16d
|
|||
|
a60b709cb0
|
|||
|
1115590ab2
|
|||
|
456df222f2
|
|||
|
e054e47453
|
|||
| dd9749a536 | |||
| ac5d6800e1 | |||
|
eed5e8a75a
|
|||
|
0c9faa509b
|
|||
|
e4947ce5a9
|
|||
|
9b60099ad9
|
|||
|
7362d20565
|
|||
|
457b6a12be
|
|||
|
c872a837eb
|
|||
| 4dcec9e806 | |||
| 8e0aedf0db | |||
| 406668e958 | |||
| 9663cba4af | |||
|
e2c633a917
|
|||
|
d5805089f5
|
|||
| f9c10eeb7a | |||
| 896e7de1ec | |||
| 486268609b | |||
| 2f0b5915fc | |||
|
ca92ce71b6
|
|||
|
de56fa0547
|
|||
|
da1235f95c
|
|||
|
fd0d6b9625
|
|||
| 76abc69c6c | |||
|
e15380c96c
|
|||
|
aa476256ac
|
|||
|
7e8d066144
|
|||
| e21552df97 | |||
| fb3f3ddd4b | |||
| d4b9b67f08 | |||
| 1d131e71c5 | |||
| 7cb3a48e46 | |||
| b3d4ad8546 | |||
| ddc559807a | |||
| 7120e82827 | |||
| 15b8e65d2d | |||
| 6758105394 | |||
| b248258808 | |||
|
9efbf457a4
|
|||
| 65d8502a18 | |||
| 29ff1269ce | |||
| 3105c6cf65 | |||
|
11e2eb1e10
|
|||
| 3d638a4d63 | |||
| 77f72178dc | |||
|
d53cdca9e5
|
|||
|
e1787423e8
|
|||
|
e9d776f71a
|
|||
| 707e4aef65 | |||
|
8d244b74c1
|
|||
|
711084e366
|
|||
| 31bee9b15a | |||
|
88a61ba97f
|
|||
| 04a0059fb2 | |||
| 1df1aae880 | |||
| 60d71e1eb2 | |||
|
6c91b77eeb
|
|||
|
f6fec05667
|
|||
|
b2d59f619b
|
|||
| 6f11d1cd4e | |||
| c71ad2a28e | |||
| 6d997e8012 | |||
|
d5f08ef710
|
|||
| 17bf2aade6 | |||
|
4e8581ca94
|
|||
|
2db668e6ff
|
|||
| 475efbe99a | |||
|
91573c0b2e
|
|||
| 3794ac2d3c | |||
|
1fc6a1fa38
|
|||
|
2bc9b17cdc
|
|||
|
be07a89b7f
|
|||
|
f4d30e837e
|
|||
|
ced41e64fd
|
|||
| 42b9d4e64b | |||
| 7f1f566924 | |||
|
7ec997c1d5
|
|||
|
94f790d039
|
|||
|
ed3b3f07fb
|
|||
|
146b907c69
|
|||
|
540fe0eaa5
|
|||
|
1a3fc05dad
|
|||
|
507c1d8932
|
|||
| 4fb32d7928 | |||
| e082b0b7b9 | |||
| 700a8d8ed1 | |||
| cb408fd192 | |||
|
2e38c64a3d
|
|||
|
4a665029ec
|
|||
|
a1b4631a13
|
|||
| 86c8fb0bad | |||
| 96e2f9b420 | |||
| ecd59cd886 | |||
|
0983f39a17
|
|||
|
0d671b2557
|
|||
|
7b1e99095b
|
|||
|
0b4a47f22a
|
|||
|
a70eb9864c
|
|||
| 11030e3a63 | |||
| d8d6d053f7 | |||
|
ed6a590450
|
|||
|
afffe046ef
|
|||
|
afbeee38a6
|
|||
|
67b37bce10
|
|||
|
852ba5e415
|
|||
|
eaf0d4d7fb
|
|||
|
1a19afa4db
|
|||
|
556644d7e3
|
|||
|
19872ce50f
|
|||
|
e45dd333d7
|
|||
|
46e31c9878
|
|||
|
575554a36c
|
|||
|
ef57349f95
|
|||
|
b7cc88d533
|
|||
|
41c506fa97
|
|||
|
e706b2eb17
|
|||
|
0b13fce03c
|
|||
|
1fbe3356fc
|
|||
|
53a4953c07
|
|||
|
8a86c54edf
|
|||
|
80f33f7563
|
|||
|
ba46dcabcc
|
|||
|
5ab29d1449
|
|||
|
2fecd697b6
|
|||
|
8d9a6e5426
|
|||
|
06a7b035e4
|
|||
|
e4215df83f
|
|||
|
a6c6b110cf
|
|||
|
7ebb29100d
|
|||
|
3fcd7ae917
|
|||
|
6062230e78
|
|||
|
ceb206289c
|
|||
| e9f263bab1 | |||
| d829b58f8c | |||
|
3ab86fc511
|
|||
| 35a40727df | |||
|
29d356efac
|
|||
|
7db82462fa
|
|||
| 15c5cc89cd | |||
| cf71c17464 | |||
|
2cfc8bc0d8
|
|||
| 71c1b74975 | |||
|
f7de5b03f1
|
|||
| 322db23411 | |||
| 2f284c415d | |||
|
f96c16b2a3
|
|||
| 85ea4c9c09 | |||
| f87b92df10 | |||
|
046350ef84
|
|||
|
4fd97b6182
|
|||
| ac0d1d6fc0 | |||
| 6c9244839c | |||
| 54cf58af55 | |||
| f61b64535a | |||
|
0825be76b3
|
|||
|
c056b7598b
|
|||
| e0203c5aef | |||
| 716bf190b5 | |||
|
deb0a05629
|
|||
|
cb886fc763
|
|||
| 488ca1018d | |||
|
f5fc4fd0ee
|
|||
| 547ce1ae19 | |||
| 497f42af0c | |||
|
884983f3e4
|
|||
| 1cf06be012 | |||
| c9478f68b3 | |||
| 09feb573ad | |||
| 7f0ce7cf69 | |||
| cb0f06065c | |||
| b3a9be96c5 | |||
|
8d0f87c84c
|
|||
|
d9bd21661c
|
|||
| 2f84525f66 | |||
|
fcd6ebc518
|
|||
|
982a29f1e0
|
|||
|
175c0b38da
|
|||
| cc76cb18fe | |||
|
afec1ed8ea
|
|||
|
316e786fc4
|
|||
|
2fe5b1c278
|
|||
|
ef281f1028
|
|||
|
d888a1fbbc
|
|||
|
96be4e5577
|
|||
| 34768bdcf0 | |||
| 1a17561f1e | |||
| 086f58bec6 | |||
| f0c4eb93f8 | |||
| 0461656738 | |||
| da22a2a29f | |||
| 1198d7e551 | |||
| 58d55ae8dc | |||
| 92e3f7c13d | |||
| d975690f12 | |||
| 97bbd1a407 | |||
|
e70f104b5c
|
|||
| cde57081ad | |||
| d044ba909c | |||
| ee4a0e4296 | |||
| 0d75682ed7 | |||
| c864407c9e | |||
|
e728b0f990
|
|||
|
8e84c8e59c
|
|||
|
edae599978
|
|||
|
d0ff47525f
|
|||
|
efbf2b0af7
|
|||
|
841289700b
|
|||
| f47b8b3c5b | |||
|
c32e264575
|
|||
|
b61282a058
|
|||
|
3057d9cc5a
|
|||
| d24d34787b | |||
| 0ba8771468 | |||
| a7eb36ba80 | |||
| 22a1ff5986 | |||
| a3f8629561 | |||
| 3b5d80e539 | |||
| 353c3a532d | |||
| 965ce437a3 | |||
| 7799bc2821 | |||
| 5566773e77 | |||
|
b4c62fbd43
|
|||
|
5303b13b08
|
|||
|
a550ddd5c3
|
|||
|
0143038707
|
|||
| 92ca9343aa | |||
| 183ce0ee52 | |||
| 1247ea3302 | |||
| 6ea0bcd2d1 | |||
| b52d869a6c | |||
| 99b69b9b92 | |||
| 93b380c40a | |||
| f23977a40c | |||
| 02e9ea80a7 | |||
|
0d39e779c4
|
|||
|
a4a3f4c0c4
|
|||
| 2f565dbb3a | |||
| afb843421a | |||
| f575ac4918 | |||
| 8133799d13 | |||
| 5d2e1682c8 | |||
| 8542ba7ab7 | |||
| 935b1053fd | |||
|
faee779cfb
|
|||
|
ed872610f7
|
|||
|
3f92ccab98
|
|||
|
6188463a68
|
|||
|
c0f03560d5
|
|||
|
c74aba652e
|
|||
| 0803877c8b | |||
| 31f72787f8 | |||
| eabe341ece | |||
| 001d5bc863 | |||
| 5f41feda61 | |||
| ac4d03200a | |||
|
5320be6c9a
|
|||
| dba4d85ff3 | |||
| f4db384a5a | |||
| 5ac0b3f14d | |||
| 379e41f506 | |||
| b1135e6794 | |||
|
88775f50fe
|
|||
| dbd7e55940 | |||
| dd0c93a0b4 | |||
| bf2d7986cc |
@@ -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 }}
|
||||
@@ -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() }}
|
||||
|
||||
@@ -48,3 +48,4 @@ out/
|
||||
/hideout-core/files/
|
||||
/hideout-core/.kotlin/sessions/
|
||||
/hideout-mastodon/.kotlin/sessions/
|
||||
/http-client.private.env.json
|
||||
|
||||
+2
-1
@@ -66,4 +66,5 @@ tasks.register("run") {
|
||||
|
||||
springBoot {
|
||||
mainClass = "dev.usbharu.hideout.SpringApplicationKt"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
@@ -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
|
||||
Vendored
BIN
Binary file not shown.
+1
-1
@@ -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
|
||||
|
||||
@@ -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
@@ -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,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
|
||||
|
||||
Vendored
+4
-1
@@ -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
@@ -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 ##########################################################################
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
BIN
Binary file not shown.
+1
-1
@@ -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
@@ -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
@@ -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 ##########################################################################
|
||||
|
||||
@@ -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 {
|
||||
|
||||
+38
@@ -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,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
+5
@@ -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)
|
||||
-37
@@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
+8
@@ -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
|
||||
)
|
||||
+47
@@ -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)
|
||||
}
|
||||
}
|
||||
+8
-5
@@ -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 })
|
||||
|
||||
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
package dev.usbharu.hideout.core.application.actor
|
||||
|
||||
data class MigrationLocalActor(val from: Long, val to: Long)
|
||||
+40
-18
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
+10
-6
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
-8
@@ -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>)
|
||||
}
|
||||
+46
@@ -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)
|
||||
}
|
||||
}
|
||||
-37
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
-36
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
+51
-45
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
+10
@@ -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
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
package dev.usbharu.hideout.core.application.domainevent.subscribers
|
||||
|
||||
data class RegisterHomeTimeline(
|
||||
val userDetailId: Long
|
||||
)
|
||||
+21
@@ -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
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
+21
@@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
package dev.usbharu.hideout.core.application.domainevent.subscribers
|
||||
|
||||
interface Subscriber {
|
||||
fun init()
|
||||
}
|
||||
+12
@@ -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() }
|
||||
}
|
||||
}
|
||||
+20
@@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
+52
@@ -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)
|
||||
}
|
||||
}
|
||||
+56
@@ -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)
|
||||
}
|
||||
}
|
||||
+14
@@ -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
|
||||
)
|
||||
}
|
||||
+14
@@ -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
|
||||
)
|
||||
}
|
||||
+10
-5
@@ -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)
|
||||
}
|
||||
|
||||
|
||||
+10
-6
@@ -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)
|
||||
}
|
||||
|
||||
|
||||
+5
-9
@@ -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,
|
||||
|
||||
+44
@@ -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)
|
||||
}
|
||||
}
|
||||
+17
@@ -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
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
+6
-5
@@ -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
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
package dev.usbharu.hideout.core.application.post
|
||||
|
||||
data class DeleteLocalPost(val postId: Long)
|
||||
+21
-7
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
+13
-5
@@ -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)
|
||||
}
|
||||
|
||||
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
package dev.usbharu.hideout.core.application.post
|
||||
|
||||
data class GetPostDetail(val postId: Long)
|
||||
+82
@@ -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
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
-1
@@ -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,
|
||||
|
||||
+7
-11
@@ -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,
|
||||
|
||||
+1
-1
@@ -21,5 +21,5 @@ data class UpdateLocalNote(
|
||||
val overview: String?,
|
||||
val content: String,
|
||||
val sensitive: Boolean,
|
||||
val mediaIds: List<Long>,
|
||||
val mediaIds: List<Long>
|
||||
)
|
||||
|
||||
+15
-9
@@ -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)
|
||||
|
||||
+8
-12
@@ -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()
|
||||
|
||||
|
||||
+6
-11
@@ -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(
|
||||
|
||||
+7
-11
@@ -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(
|
||||
|
||||
+15
-17
@@ -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)
|
||||
|
||||
+7
-11
@@ -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(
|
||||
|
||||
+8
-12
@@ -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()
|
||||
|
||||
|
||||
+7
-11
@@ -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(
|
||||
|
||||
+7
-11
@@ -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(
|
||||
|
||||
+7
-11
@@ -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(
|
||||
|
||||
+11
-15
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
+8
-6
@@ -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
|
||||
}
|
||||
|
||||
+3
-1
@@ -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
|
||||
}
|
||||
|
||||
-25
@@ -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
|
||||
}
|
||||
+18
@@ -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)
|
||||
+7
@@ -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
|
||||
)
|
||||
+5
@@ -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)
|
||||
+53
@@ -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)
|
||||
}
|
||||
}
|
||||
+11
@@ -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
|
||||
)
|
||||
+84
@@ -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)
|
||||
}
|
||||
}
|
||||
+8
@@ -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
|
||||
)
|
||||
+30
@@ -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)
|
||||
}
|
||||
}
|
||||
+5
@@ -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)
|
||||
+29
@@ -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)
|
||||
}
|
||||
}
|
||||
+26
@@ -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)
|
||||
}
|
||||
}
|
||||
+37
@@ -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)
|
||||
}
|
||||
}
|
||||
+8
@@ -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
|
||||
|
||||
+5
-4
@@ -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) {
|
||||
|
||||
+4
-2
@@ -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) {
|
||||
|
||||
+1
-1
@@ -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
Reference in New Issue
Block a user