Skip to content

Commit dff2ef4

Browse files
authored
release: 1.9.1 (#206)
2 parents f7363d5 + 294e5bc commit dff2ef4

File tree

17 files changed

+269
-5
lines changed

17 files changed

+269
-5
lines changed

.github/workflows/deploy.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ jobs:
8888
"RELAY_APPROVE_TOKEN=${{ secrets.RELAY_APPROVE_TOKEN }}"
8989
"INTERNAL_AUTH_SECRET=${{ secrets.INTERNAL_AUTH_SECRET }}"
9090
"LOGIN_SECRET=${{ secrets.LOGIN_SECRET }}"
91+
"GITANIMALS_ADMIN_TOKEN=${{ secrets.GITANIMALS_ADMIN_TOKEN }}"
9192
9293
- name: build and push filebeat
9394
uses: docker/build-push-action@v4

deploy/api/Dockerfile

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ ARG QUIZ_APPROVE_TOKEN
2323
ARG RELAY_APPROVE_TOKEN
2424
ARG INTERNAL_AUTH_SECRET
2525
ARG LOGIN_SECRET
26+
ARG GITANIMALS_ADMIN_TOKEN
2627

2728
ARG JAR_FILE=./*.jar
2829
COPY ${JAR_FILE} gitanimals-api.jar
@@ -49,7 +50,8 @@ ENV db_url=${DB_URL} \
4950
quiz_approve_token=${QUIZ_APPROVE_TOKEN} \
5051
relay_approve_token=${RELAY_APPROVE_TOKEN} \
5152
internal_auth_secret=${INTERNAL_AUTH_SECRET} \
52-
login_secret=${LOGIN_SECRET}
53+
login_secret=${LOGIN_SECRET} \
54+
gitanimals_admin_token=${GITANIMALS_ADMIN_TOKEN}
5355

5456
ENTRYPOINT java -Djava.net.preferIPv4Stack=true -jar gitanimals-api.jar \
5557
--spring.datasource.url=${db_url} \
@@ -74,4 +76,5 @@ ENTRYPOINT java -Djava.net.preferIPv4Stack=true -jar gitanimals-api.jar \
7476
--quiz.approve.token=${quiz_approve_token} \
7577
--relay.approve.token=${relay_approve_token} \
7678
--internal.auth.secret=${internal_auth_secret} \
77-
--login.secret=${login_secret}
79+
--login.secret=${login_secret} \
80+
--gitanimals.admin.token=${gitanimals_admin_token}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# Get user by token
2+
3+
username에 해당하는 유저의 포인트를 감소시킵니다.
4+
5+
> [!WARN]
6+
> 요청하면 별도의 승인절차를 거친 후 승인이 되었을때, 요청이 처리됩니다.
7+
8+
## Request
9+
### HTTP METHOD : `POST`
10+
### url : `https://api.gitanimals.org/admin/users/points/decrease/by-username/{username}`
11+
### RequestHeader
12+
- Admin-Secret: `{발급받은 어드민 토큰을 넘겨주세요.}`
13+
- Authorization: `{어드민 요청자의 인증토큰을 넘겨주세요.}`
14+
15+
### Request Body
16+
```json
17+
{
18+
"point": 100000, // 감소 시킬 포인트
19+
"reason": "" // 요청을 처리하는 이유
20+
}
21+
```
22+
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# Get user by token
2+
3+
username에 해당하는 유저의 포인트를 증가시킵니다.
4+
5+
> [!WARN]
6+
> 요청하면 별도의 승인절차를 거친 후 승인이 되었을때, 요청이 처리됩니다.
7+
8+
## Request
9+
### HTTP METHOD : `POST`
10+
### url : `https://api.gitanimals.org/admin/users/points/increase/by-username/{username}`
11+
### RequestHeader
12+
- Admin-Secret: `{발급받은 어드민 토큰을 넘겨주세요.}`
13+
- Authorization: `{어드민 요청자의 인증토큰을 넘겨주세요.}`
14+
15+
### Request Body
16+
```json
17+
{
18+
"point": 100000, // 증가 시킬 포인트
19+
"reason": "" // 요청을 처리하는 이유
20+
}
21+
```
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package org.gitanimals.core.admin
2+
3+
interface AbstractAdminRequest {
4+
val reason: String
5+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package org.gitanimals.core.admin
2+
3+
import org.gitanimals.core.IdGenerator
4+
import org.gitanimals.core.filter.MDCFilter
5+
import org.gitanimals.core.redis.AsyncRedisPubSubEvent
6+
import org.gitanimals.core.redis.RedisPubSubChannel
7+
import org.slf4j.MDC
8+
9+
data class AdminCallDetected(
10+
val username: String,
11+
val reason: String,
12+
val path: String,
13+
val description: String,
14+
) : AsyncRedisPubSubEvent(
15+
channel = RedisPubSubChannel.ADMIN_CALL_DETECTED,
16+
traceId = runCatching { MDC.get(MDCFilter.TRACE_ID) }
17+
.getOrElse { IdGenerator.generate().toString() },
18+
)
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package org.gitanimals.core.admin
2+
3+
object AdminConst {
4+
const val ADMIN_SECRET_KEY = "Admin-Secret"
5+
}

src/main/kotlin/org/gitanimals/core/redis/RedisPubSubChannel.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,6 @@ object RedisPubSubChannel {
1212
const val DEAD_LETTER_OCCURRED = "DEAD_LETTER_OCCURRED"
1313

1414
const val NEW_PET_DROP_RATE_DISTRIBUTION = "NEW_PET_DROP_RATE_DISTRIBUTION"
15+
16+
const val ADMIN_CALL_DETECTED = "ADMIN_CALL_DETECTED"
1517
}
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
package org.gitanimals.identity.controller.admin
2+
3+
import org.gitanimals.core.admin.AdminCallDetected
4+
import org.gitanimals.core.admin.AdminConst.ADMIN_SECRET_KEY
5+
import org.gitanimals.identity.app.Token
6+
import org.gitanimals.identity.app.UserFacade
7+
import org.gitanimals.identity.controller.admin.request.PointDecreaseRequest
8+
import org.gitanimals.identity.controller.admin.request.PointIncreaseRequest
9+
import org.gitanimals.identity.domain.EntryPoint
10+
import org.gitanimals.identity.domain.UserService
11+
import org.springframework.beans.factory.annotation.Value
12+
import org.springframework.context.ApplicationEventPublisher
13+
import org.springframework.http.HttpHeaders
14+
import org.springframework.http.HttpStatus
15+
import org.springframework.web.bind.annotation.*
16+
17+
@RestController
18+
class AdminUserController(
19+
private val userService: UserService,
20+
private val userFacade: UserFacade,
21+
private val eventPublisher: ApplicationEventPublisher,
22+
@Value("\${gitanimals.admin.token}") private val adminToken: String,
23+
) {
24+
25+
@ResponseStatus(HttpStatus.OK)
26+
@PostMapping("/admin/users/points/increase/by-username/{username}")
27+
fun increaseUserPointsByUsername(
28+
@PathVariable("username") username: String,
29+
@RequestParam(
30+
name = "entryPoint",
31+
defaultValue = "GITHUB",
32+
)
33+
entryPoint: EntryPoint = EntryPoint.GITHUB,
34+
@RequestHeader(ADMIN_SECRET_KEY) adminSecret: String,
35+
@RequestHeader(HttpHeaders.AUTHORIZATION) authorization: String,
36+
@RequestBody pointIncreaseRequest: PointIncreaseRequest,
37+
) {
38+
require(adminSecret == adminToken) {
39+
"WRONG TOKEN"
40+
}
41+
42+
val user = userFacade.getUserByToken(Token.from(authorization))
43+
44+
userService.increasePointByUsernameWithoutIdempotency(username, entryPoint, pointIncreaseRequest.point)
45+
eventPublisher.publishEvent(
46+
AdminCallDetected(
47+
username = user.getName(),
48+
reason = pointIncreaseRequest.reason,
49+
path = "/admin/users/points/increase/by-username/{username}",
50+
description = "$username 유저에게 ${pointIncreaseRequest.point} 지급",
51+
)
52+
)
53+
}
54+
55+
@ResponseStatus(HttpStatus.OK)
56+
@PostMapping("/admin/users/points/decrease/by-username/{username}")
57+
fun decreaseUserPointsByUsername(
58+
@PathVariable("username") username: String,
59+
@RequestParam(
60+
name = "entryPoint",
61+
defaultValue = "GITHUB",
62+
)
63+
entryPoint: EntryPoint = EntryPoint.GITHUB,
64+
@RequestHeader(ADMIN_SECRET_KEY) adminSecret: String,
65+
@RequestHeader(HttpHeaders.AUTHORIZATION) authorization: String,
66+
@RequestBody pointDecreaseRequest: PointDecreaseRequest,
67+
) {
68+
require(adminSecret == adminToken) {
69+
"WRONG TOKEN"
70+
}
71+
72+
val user = userFacade.getUserByToken(Token.from(authorization))
73+
74+
userService.decreasePointByUsernameWithoutIdempotency(username, entryPoint, pointDecreaseRequest.point)
75+
eventPublisher.publishEvent(
76+
AdminCallDetected(
77+
username = user.getName(),
78+
reason = pointDecreaseRequest.reason,
79+
path = "/admin/users/points/decrease/by-username/{username}",
80+
description = "$username 유저에게 ${pointDecreaseRequest.point} 차감",
81+
)
82+
)
83+
}
84+
85+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package org.gitanimals.identity.controller.admin.request
2+
3+
import org.gitanimals.core.admin.AbstractAdminRequest
4+
5+
data class PointDecreaseRequest(
6+
val point: Long,
7+
override val reason: String,
8+
) : AbstractAdminRequest

0 commit comments

Comments
 (0)