Skip to content

Commit 31b1cf7

Browse files
Merge pull request #60 from DevKor-github/develop
운영 배포포
2 parents a8dfd50 + e1803c5 commit 31b1cf7

33 files changed

Lines changed: 2527 additions & 92 deletions

src/main/java/apu/saerok_admin/infra/CurrentAdminClient.java

Lines changed: 76 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
import java.util.LinkedHashSet;
77
import java.util.List;
88
import java.util.Locale;
9-
import java.util.Map;
109
import java.util.Optional;
1110
import java.util.Set;
1211
import org.slf4j.Logger;
@@ -22,12 +21,6 @@
2221
public class CurrentAdminClient {
2322

2423
private static final Logger log = LoggerFactory.getLogger(CurrentAdminClient.class);
25-
private static final Map<String, String> ROLE_DESCRIPTION_MAP = Map.of(
26-
"ADMIN_VIEWER", "열람자",
27-
"ADMIN_EDITOR", "운영자"
28-
);
29-
private static final String UNKNOWN_ROLE_DESCRIPTION = "알 수 없는 관리자 권한";
30-
3124
private final RestClient saerokRestClient;
3225
private final List<String> missingPrefixSegments;
3326
private final LoginSessionManager loginSessionManager;
@@ -57,14 +50,19 @@ public Optional<CurrentAdminProfile> fetchCurrentAdminProfile() {
5750
return Optional.empty();
5851
}
5952

60-
List<String> roles = response.roles() != null ? List.copyOf(response.roles()) : List.of();
53+
List<String> backendRoles = response.roles() != null ? List.copyOf(response.roles()) : List.of();
54+
AdminRoleInfo roleInfo = fetchAdminRoleInfo();
55+
List<String> roleCodes = !roleInfo.roleCodes().isEmpty()
56+
? roleInfo.roleCodes()
57+
: normalizeRoleCodes(backendRoles);
6158

6259
return Optional.of(new CurrentAdminProfile(
6360
response.nickname(),
6461
response.email(),
6562
response.profileImageUrl(),
66-
toRoleDescriptions(roles),
67-
normalizeRoleCodes(roles)
63+
roleInfo.roleDisplayNames(),
64+
roleCodes,
65+
roleInfo.permissionKeys()
6866
));
6967
} catch (RestClientResponseException exception) {
7068
log.warn(
@@ -96,30 +94,79 @@ private record BackendUserProfileResponse(
9694
) {
9795
}
9896

99-
private List<String> toRoleDescriptions(List<String> roles) {
100-
if (roles == null || roles.isEmpty()) {
101-
return List.of();
102-
}
103-
104-
Set<String> descriptions = new LinkedHashSet<>();
105-
for (String role : roles) {
106-
if (!StringUtils.hasText(role)) {
107-
continue;
108-
}
97+
private AdminRoleInfo fetchAdminRoleInfo() {
98+
try {
99+
AdminMyRoleResponse response = saerokRestClient.get()
100+
.uri(uriBuilder -> buildUri(uriBuilder, "admin", "role", "me"))
101+
.retrieve()
102+
.body(AdminMyRoleResponse.class);
109103

110-
String normalized = role.toUpperCase(Locale.ROOT);
111-
String description = ROLE_DESCRIPTION_MAP.get(normalized);
112-
if (description != null) {
113-
descriptions.add(description);
114-
continue;
104+
if (response == null) {
105+
return AdminRoleInfo.empty();
115106
}
116107

117-
if (normalized.startsWith("ADMIN_")) {
118-
descriptions.add(UNKNOWN_ROLE_DESCRIPTION);
119-
}
108+
List<String> roleDisplayNames = response.roles() == null
109+
? List.of()
110+
: response.roles().stream()
111+
.map(RoleSummaryResponse::displayName)
112+
.filter(StringUtils::hasText)
113+
.map(String::trim)
114+
.toList();
115+
List<String> roleCodes = response.roles() == null
116+
? List.of()
117+
: response.roles().stream()
118+
.map(RoleSummaryResponse::code)
119+
.filter(StringUtils::hasText)
120+
.toList();
121+
List<String> permissionKeys = response.permissions() == null
122+
? List.of()
123+
: response.permissions().stream()
124+
.map(PermissionSummaryResponse::key)
125+
.filter(StringUtils::hasText)
126+
.toList();
127+
return new AdminRoleInfo(roleDisplayNames, roleCodes, permissionKeys);
128+
} catch (RestClientResponseException exception) {
129+
log.warn(
130+
"Failed to fetch current admin roles. status={}, body={}",
131+
exception.getStatusCode(),
132+
exception.getResponseBodyAsString(),
133+
exception
134+
);
135+
} catch (RestClientException exception) {
136+
log.warn("Failed to fetch current admin roles.", exception);
120137
}
138+
return AdminRoleInfo.empty();
139+
}
140+
141+
private record AdminMyRoleResponse(
142+
List<RoleSummaryResponse> roles,
143+
List<PermissionSummaryResponse> permissions
144+
) {
145+
}
121146

122-
return descriptions.isEmpty() ? List.of() : List.copyOf(descriptions);
147+
private record RoleSummaryResponse(
148+
Long id,
149+
String code,
150+
String displayName,
151+
String description,
152+
Boolean builtin
153+
) {
154+
}
155+
156+
private record PermissionSummaryResponse(
157+
String key,
158+
String description
159+
) {
160+
}
161+
162+
private record AdminRoleInfo(
163+
List<String> roleDisplayNames,
164+
List<String> roleCodes,
165+
List<String> permissionKeys
166+
) {
167+
private static AdminRoleInfo empty() {
168+
return new AdminRoleInfo(List.of(), List.of(), List.of());
169+
}
123170
}
124171

125172
private List<String> normalizeRoleCodes(List<String> roles) {

src/main/java/apu/saerok_admin/infra/auth/BackendAuthClient.java

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@
2525
public class BackendAuthClient {
2626

2727
private static final Logger log = LoggerFactory.getLogger(BackendAuthClient.class);
28-
private static final String ADMIN_CHANNEL = "admin";
2928

3029
private final RestClient authRestClient;
3130
private final List<String> missingPrefixSegments;
@@ -39,10 +38,10 @@ public BackendAuthClient(
3938
}
4039

4140
public LoginSuccess kakaoLogin(String authorizationCode) {
42-
KakaoLoginPayload payload = new KakaoLoginPayload(authorizationCode, ADMIN_CHANNEL);
41+
KakaoLoginPayload payload = new KakaoLoginPayload(authorizationCode);
4342
log.info("Requesting Kakao login from backend with authorization code length {}", authorizationCode == null ? 0 : authorizationCode.length());
4443
ResponseEntity<BackendAccessTokenResponse> response = authRestClient.post()
45-
.uri(uriBuilder -> buildUri(uriBuilder, "auth", "kakao", "login"))
44+
.uri(uriBuilder -> buildUri(uriBuilder, "admin", "auth", "kakao", "login"))
4645
.contentType(MediaType.APPLICATION_JSON)
4746
.body(payload)
4847
.retrieve()
@@ -113,6 +112,10 @@ private URI buildUri(UriBuilder builder, String... segments) {
113112
}
114113

115114
private record KakaoLoginPayload(String authorizationCode, String channel) {
115+
116+
private KakaoLoginPayload(String authorizationCode) {
117+
this(authorizationCode, "admin");
118+
}
116119
}
117120

118121
private record AppleLoginPayload(String authorizationCode) {
Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
package apu.saerok_admin.infra.role;
2+
3+
import apu.saerok_admin.infra.SaerokApiProps;
4+
import apu.saerok_admin.infra.role.dto.AdminMyRoleResponse;
5+
import apu.saerok_admin.infra.role.dto.AdminRoleListResponse;
6+
import apu.saerok_admin.infra.role.dto.AdminRoleUserListResponse;
7+
import apu.saerok_admin.infra.role.dto.AdminUserRoleResponse;
8+
import apu.saerok_admin.infra.role.dto.AssignRoleRequest;
9+
import apu.saerok_admin.infra.role.dto.CreateRoleRequest;
10+
import apu.saerok_admin.infra.role.dto.RoleDetailResponse;
11+
import apu.saerok_admin.infra.role.dto.UpdateRolePermissionsRequest;
12+
import java.net.URI;
13+
import java.util.List;
14+
import org.springframework.http.HttpMethod;
15+
import org.springframework.stereotype.Component;
16+
import org.springframework.web.client.RestClient;
17+
import org.springframework.web.util.UriBuilder;
18+
19+
@Component
20+
public class AdminRoleClient {
21+
22+
private static final String[] ADMIN_ROLE_SEGMENTS = {"admin", "role"};
23+
24+
private final RestClient saerokRestClient;
25+
private final String[] missingPrefixSegments;
26+
27+
public AdminRoleClient(RestClient saerokRestClient, SaerokApiProps saerokApiProps) {
28+
this.saerokRestClient = saerokRestClient;
29+
List<String> missing = saerokApiProps.missingPrefixSegments();
30+
this.missingPrefixSegments = missing.toArray(new String[0]);
31+
}
32+
33+
public AdminMyRoleResponse getMyRoles() {
34+
return get(AdminMyRoleResponse.class, "me");
35+
}
36+
37+
public AdminRoleUserListResponse listAdminUsers() {
38+
return get(AdminRoleUserListResponse.class, "users");
39+
}
40+
41+
public AdminRoleListResponse listRoles() {
42+
return get(AdminRoleListResponse.class);
43+
}
44+
45+
public RoleDetailResponse createRole(CreateRoleRequest request) {
46+
return post(RoleDetailResponse.class, request);
47+
}
48+
49+
public RoleDetailResponse updateRolePermissions(String roleCode, UpdateRolePermissionsRequest request) {
50+
return put(RoleDetailResponse.class, request, roleCode, "permissions");
51+
}
52+
53+
public void deleteRole(String roleCode) {
54+
deleteVoid(roleCode);
55+
}
56+
57+
public AdminUserRoleResponse grantRole(Long userId, AssignRoleRequest request) {
58+
return post(AdminUserRoleResponse.class, request, "users", userId.toString(), "roles");
59+
}
60+
61+
public AdminUserRoleResponse revokeRole(Long userId, String roleCode) {
62+
return delete(AdminUserRoleResponse.class, "users", userId.toString(), "roles", roleCode);
63+
}
64+
65+
private <T> T get(Class<T> responseType, String... segments) {
66+
T response = saerokRestClient.get()
67+
.uri(uriBuilder -> buildUri(uriBuilder, segments))
68+
.retrieve()
69+
.body(responseType);
70+
if (response == null) {
71+
throw new IllegalStateException("Empty response from admin role API");
72+
}
73+
return response;
74+
}
75+
76+
private <T> T post(Class<T> responseType, Object body, String... segments) {
77+
T response = saerokRestClient.post()
78+
.uri(uriBuilder -> buildUri(uriBuilder, segments))
79+
.body(body)
80+
.retrieve()
81+
.body(responseType);
82+
if (response == null) {
83+
throw new IllegalStateException("Empty response from admin role API");
84+
}
85+
return response;
86+
}
87+
88+
private <T> T put(Class<T> responseType, Object body, String... segments) {
89+
T response = saerokRestClient.method(HttpMethod.PUT)
90+
.uri(uriBuilder -> buildUri(uriBuilder, segments))
91+
.body(body)
92+
.retrieve()
93+
.body(responseType);
94+
if (response == null) {
95+
throw new IllegalStateException("Empty response from admin role API");
96+
}
97+
return response;
98+
}
99+
100+
private <T> T delete(Class<T> responseType, String... segments) {
101+
T response = saerokRestClient.delete()
102+
.uri(uriBuilder -> buildUri(uriBuilder, segments))
103+
.retrieve()
104+
.body(responseType);
105+
if (response == null) {
106+
throw new IllegalStateException("Empty response from admin role API");
107+
}
108+
return response;
109+
}
110+
111+
private void deleteVoid(String... segments) {
112+
saerokRestClient.delete()
113+
.uri(uriBuilder -> buildUri(uriBuilder, segments))
114+
.retrieve()
115+
.toBodilessEntity();
116+
}
117+
118+
private URI buildUri(UriBuilder builder, String... segments) {
119+
if (missingPrefixSegments.length > 0) {
120+
builder.pathSegment(missingPrefixSegments);
121+
}
122+
builder.pathSegment(ADMIN_ROLE_SEGMENTS);
123+
if (segments.length > 0) {
124+
builder.pathSegment(segments);
125+
}
126+
return builder.build();
127+
}
128+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package apu.saerok_admin.infra.role.dto;
2+
3+
import java.util.List;
4+
5+
public record AdminMyRoleResponse(
6+
List<RoleSummaryResponse> roles,
7+
List<PermissionSummaryResponse> permissions
8+
) {
9+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package apu.saerok_admin.infra.role.dto;
2+
3+
import java.util.List;
4+
5+
public record AdminRoleListResponse(
6+
List<RoleDetailResponse> roles
7+
) {
8+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package apu.saerok_admin.infra.role.dto;
2+
3+
import java.util.List;
4+
5+
public record AdminRoleUserListResponse(
6+
List<AdminUserRoleResponse> users
7+
) {
8+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package apu.saerok_admin.infra.role.dto;
2+
3+
import java.util.List;
4+
5+
public record AdminUserRoleResponse(
6+
Long userId,
7+
String nickname,
8+
String email,
9+
boolean superAdmin,
10+
List<RoleSummaryResponse> roles,
11+
List<PermissionSummaryResponse> permissions
12+
) {
13+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
package apu.saerok_admin.infra.role.dto;
2+
3+
public record AssignRoleRequest(
4+
String roleCode
5+
) {
6+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package apu.saerok_admin.infra.role.dto;
2+
3+
public record CreateRoleRequest(
4+
String code,
5+
String displayName,
6+
String description
7+
) {
8+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package apu.saerok_admin.infra.role.dto;
2+
3+
public record PermissionSummaryResponse(
4+
String key,
5+
String description
6+
) {
7+
}

0 commit comments

Comments
 (0)