Skip to content

Commit f193866

Browse files
committed
Role assign logic
1 parent 9d3b820 commit f193866

File tree

18 files changed

+429
-104
lines changed

18 files changed

+429
-104
lines changed

src/main/kotlin/be/sgl/backend/config/DataLoader.kt

Lines changed: 29 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -2,78 +2,61 @@ package be.sgl.backend.config
22

33
import be.sgl.backend.entity.branch.Branch
44
import be.sgl.backend.entity.branch.BranchStatus
5-
import be.sgl.backend.entity.user.Role
6-
import be.sgl.backend.entity.user.RoleLevel
7-
import be.sgl.backend.entity.user.User
8-
import be.sgl.backend.entity.user.UserRole
5+
import be.sgl.backend.entity.user.Role.Companion.adminRole
6+
import be.sgl.backend.entity.user.Role.Companion.memberRole
7+
import be.sgl.backend.entity.user.Role.Companion.staffRole
98
import be.sgl.backend.repository.BranchRepository
109
import be.sgl.backend.repository.RoleRepository
11-
import be.sgl.backend.repository.user.UserRepository
12-
import be.sgl.backend.repository.user.UserRoleRepository
1310
import org.springframework.beans.factory.annotation.Autowired
11+
import org.springframework.beans.factory.annotation.Value
1412
import org.springframework.boot.CommandLineRunner
1513
import org.springframework.context.annotation.Bean
1614
import org.springframework.context.annotation.Configuration
17-
import org.springframework.context.annotation.Profile
18-
import java.time.LocalDate
1915

2016
@Configuration
21-
@Profile("local")
2217
class DataLoader {
2318

2419
@Autowired
2520
private lateinit var branchRepository: BranchRepository
2621
@Autowired
2722
private lateinit var roleRepository: RoleRepository
28-
@Autowired
29-
private lateinit var userRepository: UserRepository
30-
@Autowired
31-
private lateinit var userRoleRepository: UserRoleRepository
23+
@Value("\${organization.external.id}")
24+
var externalOrganizationId: String? = null
3225

3326
@Bean
3427
fun loadData() = CommandLineRunner {
28+
// Suppose a clean first run only when no branches are configured
29+
if (branchRepository.findAll().isNotEmpty()) {
30+
return@CommandLineRunner
31+
}
32+
3533
val kapoenen = createBranch("Kapoenen", 7, 8)
3634
val welpen = createBranch("Welpen", 9, 11)
3735
val jonggivers = createBranch("Jonggivers", 12, 14)
3836
val givers = createBranch("Givers", 15, 17)
3937
val jins = createBranch("Jins", 18, 18)
4038
val staff = createBranch("Leiding", 19, null, BranchStatus.MEMBER)
41-
if (branchRepository.findAll().isEmpty()) {
42-
branchRepository.saveAll(listOf(kapoenen, welpen, jonggivers, givers, jins, staff))
43-
}
44-
var adminRole = createRole("VGA", "d5f75b320b812440010b812555970393", level = RoleLevel.ADMIN)
45-
if (roleRepository.findAll().isEmpty()) {
46-
adminRole = roleRepository.save(adminRole)
39+
branchRepository.saveAll(listOf(kapoenen, welpen, jonggivers, givers, jins, staff))
40+
41+
val externalSync = externalOrganizationId != null
42+
roleRepository.saveAll(listOf(
43+
adminRole("Admin", "d5f75b320b812440010b812555970393".takeIf { externalSync }, "8a95af9385ad9b880185c035ee740010".takeIf { externalSync }),
44+
staffRole("Kapoenenleiding", "d5f75b320b812440010b812555e603a4".takeIf { externalSync }, null, kapoenen, true),
45+
staffRole("Welpenleiding", "d5f75b320b812440010b812555ec03a5".takeIf { externalSync }, null, welpen, true),
46+
staffRole("Jonggiverleiding", "d5f75b320b812440010b812555cc039e".takeIf { externalSync }, null, jonggivers, true),
47+
staffRole("Giverleiding", "d5f75b320b812440010b812555b50398".takeIf { externalSync }, null, givers, true),
48+
staffRole("Jinleiding", "d5f75b320b812440010b812555d2039f".takeIf { externalSync }, null, jins, true),
49+
staffRole("Groepsleiding", "d5f75b320b812440010b8125558e0391".takeIf { externalSync }, null, staff, true)
50+
))
51+
if (externalSync) {
4752
roleRepository.saveAll(listOf(
48-
createRole("AVGA", "8a95af9385ad9b880185c035ee740010", level = RoleLevel.ADMIN),
49-
createRole("Kapoen", "d5f75b320b812440010b812555de03a2"),
50-
createRole("Welp", "d5f75b320b812440010b8125567703cb"),
51-
createRole("Jonggiver", "d5f75b320b812440010b812555d603a0"),
52-
createRole("Giver", "d5f75b320b812440010b8125565203c1"),
53-
createRole("Jin", "d5f75b320b812440010b812555c1039b"),
54-
createRole("Kapoenenleiding", "d5f75b320b812440010b812555e603a4", kapoenen, RoleLevel.STAFF),
55-
createRole("Welpenleiding", "d5f75b320b812440010b812555ec03a5", welpen, RoleLevel.STAFF),
56-
createRole("Jonggiverleiding", "d5f75b320b812440010b812555cc039e", jonggivers, RoleLevel.STAFF),
57-
createRole("Giverleiding", "d5f75b320b812440010b812555b50398", givers, RoleLevel.STAFF),
58-
createRole("Jinleiding", "d5f75b320b812440010b812555d2039f", jins, RoleLevel.STAFF),
59-
createRole("Groepsleiding", "d5f75b320b812440010b8125558e0391", staff, RoleLevel.STAFF)
53+
memberRole("Kapoen", "d5f75b320b812440010b812555de03a2", null, kapoenen),
54+
memberRole("Welp", "d5f75b320b812440010b8125567703cb", null, welpen),
55+
memberRole("Jonggiver", "d5f75b320b812440010b812555d603a0", null, jonggivers),
56+
memberRole("Giver", "d5f75b320b812440010b8125565203c1", null, givers),
57+
memberRole("Jin", "d5f75b320b812440010b812555c1039b", null, jins)
6058
))
6159
}
62-
if (userRepository.findAll().isEmpty()) {
63-
val rootUser = userRepository.save(User().apply {
64-
firstName = "root"
65-
name = "user"
66-
username = "admin"
67-
})
68-
userRoleRepository.save(UserRole(rootUser, adminRole, LocalDate.now()))
69-
}
70-
}
71-
72-
private fun createRole(name: String, externalId: String, staffBranch: Branch? = null, level: RoleLevel = RoleLevel.GUEST) = Role().apply {
73-
this.name = name
74-
this.externalId = externalId
75-
this.staffBranch = staffBranch
76-
this.level = level
7760
}
7861

7962
private fun createBranch(name: String, min: Int, max: Int?, status: BranchStatus = BranchStatus.ACTIVE) = Branch().apply {

src/main/kotlin/be/sgl/backend/controller/ActivityController.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ class ActivityController {
155155
description = "Returns the registration identified with the given id.",
156156
responses = [
157157
ApiResponse(responseCode = "200", description = "Ok", content = [Content(mediaType = APPLICATION_JSON_VALUE, schema = Schema(implementation = ActivityRegistrationDTO::class))]),
158-
ApiResponse(responseCode = "204", description = "Not found", content = [Content(mediaType = APPLICATION_JSON_VALUE, schema = Schema(implementation = ApiErrorResponse::class))])
158+
ApiResponse(responseCode = "204", description = "Not found")
159159
]
160160
)
161161
fun getRegistration(@PathVariable registrationId: Int): ResponseEntity<ActivityRegistrationDTO?> {

src/main/kotlin/be/sgl/backend/controller/EventController.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ class EventController {
138138
description = "Returns the registration identified with the given id.",
139139
responses = [
140140
ApiResponse(responseCode = "200", description = "Ok", content = [Content(mediaType = APPLICATION_JSON_VALUE, schema = Schema(type = "array", implementation = EventRegistrationDTO::class))]),
141-
ApiResponse(responseCode = "204", description = "Not found", content = [Content(mediaType = APPLICATION_JSON_VALUE, schema = Schema(implementation = ApiErrorResponse::class))])
141+
ApiResponse(responseCode = "204", description = "Not found")
142142
]
143143
)
144144
fun getRegistration(@PathVariable registrationId: Int): ResponseEntity<EventRegistrationDTO?> {

src/main/kotlin/be/sgl/backend/controller/MembershipController.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ class MembershipController {
125125
description = "Returns the paid membership linked to the current period for the current user.",
126126
responses = [
127127
ApiResponse(responseCode = "200", description = "Ok", content = [Content(mediaType = APPLICATION_JSON_VALUE, schema = Schema(implementation = MembershipDTO::class))]),
128-
ApiResponse(responseCode = "204", description = "Not found", content = [Content(mediaType = APPLICATION_JSON_VALUE, schema = Schema(implementation = ApiErrorResponse::class))])
128+
ApiResponse(responseCode = "204", description = "Not found")
129129
]
130130
)
131131
fun getCurrentMembershipsForCurrentUser(@AuthenticationPrincipal userDetails: CustomUserDetails): ResponseEntity<MembershipDTO?> {
@@ -168,7 +168,7 @@ class MembershipController {
168168
description = "Returns the membership identified with the given id.",
169169
responses = [
170170
ApiResponse(responseCode = "200", description = "Ok", content = [Content(mediaType = APPLICATION_JSON_VALUE, schema = Schema(implementation = MembershipDTO::class))]),
171-
ApiResponse(responseCode = "204", description = "Not found", content = [Content(mediaType = APPLICATION_JSON_VALUE, schema = Schema(implementation = ApiErrorResponse::class))])
171+
ApiResponse(responseCode = "204", description = "Not found")
172172
]
173173
)
174174
fun getMembershipById(@PathVariable id: Int): ResponseEntity<MembershipDTO?> {

src/main/kotlin/be/sgl/backend/controller/RoleController.kt

Lines changed: 122 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,25 @@
11
package be.sgl.backend.controller
22

33
import be.sgl.backend.config.security.OnlyAdmin
4+
import be.sgl.backend.config.security.Public
5+
import be.sgl.backend.dto.MemberRoleDTO
6+
import be.sgl.backend.dto.StaffRoleDTO
47
import be.sgl.backend.dto.ExternalFunction
58
import be.sgl.backend.dto.RoleDTO
6-
import be.sgl.backend.dto.UserDTO
7-
import be.sgl.backend.dto.UserRoleDTO
8-
import be.sgl.backend.entity.user.RoleLevel
99
import be.sgl.backend.service.RoleService
10+
import io.github.wimdeblauwe.errorhandlingspringbootstarter.ApiErrorResponse
1011
import io.swagger.v3.oas.annotations.Operation
1112
import io.swagger.v3.oas.annotations.media.Content
1213
import io.swagger.v3.oas.annotations.media.Schema
1314
import io.swagger.v3.oas.annotations.responses.ApiResponse
1415
import io.swagger.v3.oas.annotations.tags.Tag
16+
import jakarta.validation.Valid
1517
import org.springframework.beans.factory.annotation.Autowired
18+
import org.springframework.http.HttpStatus
1619
import org.springframework.http.MediaType.APPLICATION_JSON_VALUE
1720
import org.springframework.http.ResponseEntity
1821
import org.springframework.stereotype.Controller
19-
import org.springframework.web.bind.annotation.GetMapping
20-
import org.springframework.web.bind.annotation.PathVariable
21-
import org.springframework.web.bind.annotation.RequestMapping
22+
import org.springframework.web.bind.annotation.*
2223

2324
@Controller
2425
@RequestMapping("/roles")
@@ -41,6 +42,20 @@ class RoleController {
4142
return ResponseEntity.ok(roleService.getAllRoles())
4243
}
4344

45+
@GetMapping("/admin")
46+
@Public
47+
@Operation(
48+
summary = "Get the admin role",
49+
description = "Returns the single admin role.",
50+
responses = [
51+
ApiResponse(responseCode = "200", description = "Ok", content = [Content(mediaType = APPLICATION_JSON_VALUE, schema = Schema(implementation = RoleDTO::class))]),
52+
ApiResponse(responseCode = "500", description = "No admin role configured", content = [Content(mediaType = APPLICATION_JSON_VALUE, schema = Schema(implementation = ApiErrorResponse::class))])
53+
]
54+
)
55+
fun getAdminRole(): ResponseEntity<RoleDTO> {
56+
return ResponseEntity.ok(roleService.getAdminRole())
57+
}
58+
4459
@GetMapping("/functions")
4560
@OnlyAdmin
4661
@Operation(
@@ -67,16 +82,111 @@ class RoleController {
6782
return ResponseEntity.ok(roleService.getPaidExternalFunctions())
6883
}
6984

70-
@GetMapping("/{level}/users")
85+
@GetMapping("/branch/{branchId}")
86+
@Public
87+
@Operation(
88+
summary = "Get the role linked to the specified branch",
89+
description = "Returns the single role that is assigned when a user engages in a membership for the given branch, if one.",
90+
responses = [
91+
ApiResponse(responseCode = "200", description = "Ok", content = [Content(mediaType = APPLICATION_JSON_VALUE, schema = Schema(implementation = RoleDTO::class))]),
92+
ApiResponse(responseCode = "204", description = "Not found"),
93+
ApiResponse(responseCode = "404", description = "Invalid id", content = [Content(mediaType = APPLICATION_JSON_VALUE, schema = Schema(implementation = ApiErrorResponse::class))])
94+
]
95+
)
96+
fun getRoleToSyncByBranch(@PathVariable branchId: Int): ResponseEntity<RoleDTO?> {
97+
val memberRole = roleService.getRoleToSyncByBranch(branchId)
98+
return memberRole?.let { ResponseEntity.ok(it) } ?: ResponseEntity.noContent().build()
99+
}
100+
101+
@GetMapping("/staff-branch/{branchId}")
102+
@Public
103+
@Operation(
104+
summary = "Get the role linked to the specified staff branch",
105+
description = "Returns the single staff role that is assigned when a user is marked as staff of the given branch, if one.",
106+
responses = [
107+
ApiResponse(responseCode = "200", description = "Ok", content = [Content(mediaType = APPLICATION_JSON_VALUE, schema = Schema(implementation = RoleDTO::class))]),
108+
ApiResponse(responseCode = "204", description = "Not found"),
109+
ApiResponse(responseCode = "404", description = "Invalid id", content = [Content(mediaType = APPLICATION_JSON_VALUE, schema = Schema(implementation = ApiErrorResponse::class))])
110+
]
111+
)
112+
fun getStaffRoleToSyncByBranch(@PathVariable branchId: Int): ResponseEntity<RoleDTO?> {
113+
val staffRole = roleService.getStaffRoleToSyncByBranch(branchId)
114+
return staffRole?.let { ResponseEntity.ok(it) } ?: ResponseEntity.noContent().build()
115+
}
116+
117+
@PostMapping("/branch/{branchId}")
118+
@OnlyAdmin
119+
@Operation(
120+
summary = "Create a member role",
121+
description = "Creates a member role with the provided request body and returns it.",
122+
responses = [
123+
ApiResponse(responseCode = "201", description = "Role created", content = [Content(mediaType = APPLICATION_JSON_VALUE, schema = Schema(implementation = RoleDTO::class))]),
124+
ApiResponse(responseCode = "400", description = "Bad role format", content = [Content(mediaType = APPLICATION_JSON_VALUE, schema = Schema(implementation = ApiErrorResponse::class))]),
125+
ApiResponse(responseCode = "404", description = "Invalid id", content = [Content(mediaType = APPLICATION_JSON_VALUE, schema = Schema(implementation = ApiErrorResponse::class))])
126+
127+
]
128+
)
129+
fun createMemberRole(@PathVariable branchId: Int, @Valid @RequestBody roleDto: MemberRoleDTO): ResponseEntity<RoleDTO> {
130+
return ResponseEntity(roleService.createMemberRole(branchId, roleDto), HttpStatus.CREATED)
131+
}
132+
133+
@PostMapping("/staff-branch/{branchId}")
134+
@OnlyAdmin
135+
@Operation(
136+
summary = "Create a staff role",
137+
description = "Creates a staff role with the provided request body and returns it.",
138+
responses = [
139+
ApiResponse(responseCode = "201", description = "Role created", content = [Content(mediaType = APPLICATION_JSON_VALUE, schema = Schema(implementation = RoleDTO::class))]),
140+
ApiResponse(responseCode = "400", description = "Bad role format", content = [Content(mediaType = APPLICATION_JSON_VALUE, schema = Schema(implementation = ApiErrorResponse::class))]),
141+
ApiResponse(responseCode = "404", description = "Invalid id", content = [Content(mediaType = APPLICATION_JSON_VALUE, schema = Schema(implementation = ApiErrorResponse::class))])
142+
]
143+
)
144+
fun createStaffRole(@PathVariable branchId: Int, @Valid @RequestBody roleDto: StaffRoleDTO): ResponseEntity<RoleDTO> {
145+
return ResponseEntity(roleService.createStaffRole(branchId, roleDto), HttpStatus.CREATED)
146+
}
147+
148+
@PutMapping("/branch/{id}")
149+
@OnlyAdmin
150+
@Operation(
151+
summary = "Update an existing member role",
152+
description = "Updates a member role, identified with the given id, with the provided request body and returns it.",
153+
responses = [
154+
ApiResponse(responseCode = "200", description = "Role updated", content = [Content(mediaType = APPLICATION_JSON_VALUE, schema = Schema(implementation = RoleDTO::class))]),
155+
ApiResponse(responseCode = "400", description = "Bad role format", content = [Content(mediaType = APPLICATION_JSON_VALUE, schema = Schema(implementation = ApiErrorResponse::class))]),
156+
ApiResponse(responseCode = "404", description = "Invalid id", content = [Content(mediaType = APPLICATION_JSON_VALUE, schema = Schema(implementation = ApiErrorResponse::class))])
157+
]
158+
)
159+
fun updateMemberRole(@PathVariable id: Int, @Valid @RequestBody roleDTO: MemberRoleDTO): ResponseEntity<RoleDTO> {
160+
return ResponseEntity.ok(roleService.mergeMemberRoleDTOChanges(id, roleDTO))
161+
}
162+
163+
@PutMapping("/staff-branch/{id}")
164+
@OnlyAdmin
165+
@Operation(
166+
summary = "Update an existing staff role",
167+
description = "Updates a staff role, identified with the given id, with the provided request body and returns it.",
168+
responses = [
169+
ApiResponse(responseCode = "200", description = "Role updated", content = [Content(mediaType = APPLICATION_JSON_VALUE, schema = Schema(implementation = RoleDTO::class))]),
170+
ApiResponse(responseCode = "400", description = "Bad role format", content = [Content(mediaType = APPLICATION_JSON_VALUE, schema = Schema(implementation = ApiErrorResponse::class))]),
171+
ApiResponse(responseCode = "404", description = "Invalid id", content = [Content(mediaType = APPLICATION_JSON_VALUE, schema = Schema(implementation = ApiErrorResponse::class))])
172+
]
173+
)
174+
fun updateStaffRole(@PathVariable id: Int, @Valid @RequestBody roleDTO: StaffRoleDTO): ResponseEntity<RoleDTO> {
175+
return ResponseEntity.ok(roleService.mergeStaffRoleDTOChanges(id, roleDTO))
176+
}
177+
178+
@DeleteMapping("/{id}")
71179
@OnlyAdmin
72180
@Operation(
73-
summary = "Get all users with a role of the specified level",
74-
description = "Returns a list of all users roles, filtered by their current role level.",
181+
summary = "Delete an existing role",
182+
description = "Deletes a role, identified with the given id. All linked user roles are also deleted.",
75183
responses = [
76-
ApiResponse(responseCode = "200", description = "Ok", content = [Content(mediaType = APPLICATION_JSON_VALUE, schema = Schema(type = "array", implementation = UserDTO::class))])
184+
ApiResponse(responseCode = "200", description = "Role deleted"),
185+
ApiResponse(responseCode = "404", description = "Invalid id", content = [Content(mediaType = APPLICATION_JSON_VALUE, schema = Schema(implementation = ApiErrorResponse::class))])
77186
]
78187
)
79-
fun getAllUsers(@PathVariable level: RoleLevel): ResponseEntity<List<UserRoleDTO>> {
80-
return ResponseEntity.ok(roleService.getUserRoles(level))
188+
fun deleteRole(@PathVariable id: Int): ResponseEntity<Unit> {
189+
roleService.deleteRole(id)
190+
return ResponseEntity.ok().build()
81191
}
82192
}

0 commit comments

Comments
 (0)