Skip to content

Commit a9946bd

Browse files
committed
Refactor web services #141
1 parent 542166e commit a9946bd

File tree

7 files changed

+111
-32
lines changed

7 files changed

+111
-32
lines changed

userdetails-gorm/build.gradle

+1-1
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ dependencies {
107107

108108
implementation "org.grails.plugins:ala-bootstrap3:4.1.0"
109109
implementation "org.grails.plugins:ala-ws-plugin:3.1.1"
110-
implementation "org.grails.plugins:ala-ws-security-plugin:4.3.3-SNAPSHOT"
110+
implementation "org.grails.plugins:ala-ws-security-plugin:4.3.5-SNAPSHOT"
111111
implementation "org.grails.plugins:ala-auth:5.2.0-CognitoLogoutFix-SNAPSHOT"
112112
implementation "org.grails.plugins:ala-admin-plugin:2.3.0"
113113

userdetails-gorm/src/main/groovy/au/org/ala/userdetails/gorm/GormUserService.groovy

+73
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ class GormUserService implements IUserService {
6161
LocationService locationService
6262
MessageSource messageSource
6363
WebService webService
64+
ProfileService profileService
6465

6566
@Value('${password.encoder}')
6667
String passwordEncoderType = 'bcrypt'
@@ -730,4 +731,76 @@ class GormUserService implements IUserService {
730731

731732
@Override
732733
void enableMfa(String userId, boolean enable){}
734+
boolean removeUserRole(User user, Role role) {
735+
return false
736+
}
737+
738+
@Override
739+
User findByUserNameOrEmail(String userName) {
740+
return User.findByUserNameOrEmail(userName, userName)
741+
}
742+
743+
@Override
744+
def findUsersByRole(String roleName, List numberIds, List userIds, String pageOrToken) {
745+
ScrollableResults results = null
746+
// stream the results just in case someone requests ROLE_USER or something
747+
User.withStatelessSession { session ->
748+
Role role = Role.findByRole(roleName)
749+
if (!role) {
750+
return [error: "Role not found"]
751+
}
752+
753+
def c = User.createCriteria()
754+
results = c.scroll {
755+
or {
756+
if (numberIds) {
757+
inList('id', numberIds*.toLong())
758+
}
759+
if (userIds) {
760+
inList('userName', userIds)
761+
inList('email', userIds)
762+
}
763+
}
764+
userRoles {
765+
eq("role", role)
766+
}
767+
} as ScrollableResults
768+
}
769+
return [results: results]
770+
}
771+
772+
def getUserDetailsFromIdList(List idList){
773+
def c = User.createCriteria()
774+
def results = c.list() {
775+
'in'("id", idList.collect { userId -> userId as long } )
776+
}
777+
return results
778+
}
779+
780+
def searchByUsernameOrEmail(String q, int max){
781+
782+
ScrollableResults results = null
783+
784+
User.withStatelessSession { session ->
785+
def c = User.createCriteria()
786+
results = c.scroll {
787+
or {
788+
ilike('userName', "%$q%")
789+
ilike('email', "%$q%")
790+
ilike('displayName', "%$q%")
791+
}
792+
maxResults(max)
793+
} as ScrollableResults
794+
}
795+
return [results: results]
796+
}
797+
798+
def saveCustomUserProperty(User user, String name, String value){
799+
UserProperty property = profileService.saveUserProperty(user, name, value)
800+
return property.hasErrors() ? null: property
801+
}
802+
803+
def getCustomUserProperty(User user, String name){
804+
return profileService.getUserProperty(user, name);
805+
}
733806
}

userdetails-plugin/grails-app/controllers/au/org/ala/userdetails/PropertyController.groovy

+5-7
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,6 @@ class PropertyController extends BaseController {
6464
name = "alaId",
6565
in = QUERY,
6666
description = "The user's ALA ID",
67-
schema = @Schema(implementation = Long),
6867
required = true
6968
),
7069
@Parameter(
@@ -100,14 +99,14 @@ class PropertyController extends BaseController {
10099
@PreAuthorise(requiredScope = 'users/read')
101100
def getProperty() {
102101
String name = params.name
103-
Long alaId = params.long('alaId')
102+
String alaId = params.alaId
104103
if (!name || !alaId) {
105104
badRequest "name and alaId must be provided";
106105
} else {
107106
UserRecord user = userService.getUserById(alaId);
108107
List props
109108
if (user) {
110-
props = profileService.getUserProperty(user, name);
109+
props = userService.getCustomUserProperty(user, name)
111110
render text: props as JSON, contentType: 'application/json'
112111
} else {
113112
notFound "Could not find user for id: ${alaId}";
@@ -130,7 +129,6 @@ class PropertyController extends BaseController {
130129
name = "alaId",
131130
in = QUERY,
132131
description = "The user's ALA ID",
133-
schema = @Schema(implementation = Long),
134132
required = true
135133
),
136134
@Parameter(
@@ -178,15 +176,15 @@ class PropertyController extends BaseController {
178176
def saveProperty(){
179177
String name = params.name;
180178
String value = params.value;
181-
Long alaId = params.long('alaId');
179+
String alaId = params.alaId
182180
if (!name || !alaId) {
183181
badRequest "name and alaId must be provided";
184182
} else {
185183
UserRecord user = userService.getUserById(alaId);
186184
UserPropertyRecord property
187185
if (user) {
188-
property = profileService.saveUserProperty(user, name, value);
189-
if (property.hasErrors()) {
186+
property = userService.saveCustomUserProperty(user, name, value);
187+
if (!property) {
190188
saveFailed()
191189
} else {
192190
render text: property as JSON, contentType: 'application/json'

userdetails-plugin/grails-app/controllers/au/org/ala/userdetails/RoleBasedInterceptor.groovy

+11-5
Original file line numberDiff line numberDiff line change
@@ -42,12 +42,18 @@ class RoleBasedInterceptor {
4242
PreAuthorise pa = method.getAnnotation(PreAuthorise) ?: controllerClass.getAnnotation(PreAuthorise)
4343
response.withFormat {
4444
json {
45-
if (!authorisedSystemService.isAuthorisedRequest(request, response, pa.requiredRole(), pa.requiredScope())) {
46-
log.warn("Denying access to $actionName from remote addr: ${request.remoteAddr}, remote host: ${request.remoteHost}")
47-
response.status = HttpStatus.SC_UNAUTHORIZED
48-
render(['error': "Unauthorized"] as JSON)
45+
try{
46+
if (!authorisedSystemService.isAuthorisedRequest(request, response, pa.requiredRole(), pa.requiredScope())) {
47+
log.warn("Denying access to $actionName from remote addr: ${request.remoteAddr}, remote host: ${request.remoteHost}")
48+
response.status = HttpStatus.SC_UNAUTHORIZED
49+
render(['error': "Unauthorized"] as JSON)
4950

50-
result = false
51+
result = false
52+
}
53+
}
54+
catch (Exception e){
55+
response.sendError(HttpStatus.SC_UNAUTHORIZED, e.getMessage())
56+
return false
5157
}
5258
}
5359
'*' {

userdetails-plugin/grails-app/controllers/au/org/ala/userdetails/UserDetailsController.groovy

+4-8
Original file line numberDiff line numberDiff line change
@@ -272,7 +272,6 @@ class UserDetailsController {
272272
user = userService.getUserById(userName)
273273
} else {
274274
user = userService.findByUserNameOrEmail(userName)
275-
// user = UserRecord.findByUserNameOrEmail(userName, userName)
276275
}
277276
} else {
278277
render status:400, text: "Missing parameter: userName"
@@ -422,24 +421,21 @@ class UserDetailsController {
422421
if (req && req.userIds) {
423422

424423
try {
425-
List<Long> idList = req.userIds.collect { userId -> userId as long }
424+
List idList = req.userIds
426425

427-
def c = UserRecord.createCriteria()
428-
def results = c.list() {
429-
'in'("id", idList)
430-
}
426+
def results = userService.getUserDetailsFromIdList(idList)
431427
String jsonConfig = includeProps ? UserMarshaller.WITH_PROPERTIES_CONFIG : null
432428
try {
433429

434430
JSON.use(jsonConfig)
435431

436432
def resultsMap = [users:[:], invalidIds:[], success: true]
437433
results.each { user ->
438-
resultsMap.users[user.id] = user
434+
resultsMap.users[user.userId] = user
439435
}
440436

441437
idList.each {
442-
if (!resultsMap.users[it]) {
438+
if (!resultsMap.users[it.toString()]) {
443439
resultsMap.invalidIds << it
444440
}
445441
}

userdetails-plugin/grails-app/controllers/au/org/ala/userdetails/UserDetailsWebServicesInterceptor.groovy

+11-5
Original file line numberDiff line numberDiff line change
@@ -30,13 +30,19 @@ class UserDetailsWebServicesInterceptor {
3030
}
3131

3232
boolean before() {
33-
if (!authorisedSystemService.isAuthorisedRequest(request, response, null, 'users/read')) {
34-
log.warn("Denying access to $actionName from remote addr: ${request.remoteAddr}, remote host: ${request.remoteHost}")
35-
response.sendError(HttpStatus.SC_UNAUTHORIZED)
36-
33+
try {
34+
if (!authorisedSystemService.isAuthorisedRequest(request, response, null, 'users/read')) {
35+
log.warn("Denying access to $actionName from remote addr: ${request.remoteAddr}, remote host: ${request.remoteHost}")
36+
response.sendError(HttpStatus.SC_UNAUTHORIZED)
37+
38+
return false
39+
}
40+
return true
41+
}
42+
catch (Exception e){
43+
response.sendError(HttpStatus.SC_UNAUTHORIZED, e.getMessage())
3744
return false
3845
}
39-
return true
4046
}
4147

4248
boolean after() { true }

userdetails-plugin/grails-app/services/au/org/ala/userdetails/AuthorisedSystemService.groovy

+6-6
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ import org.pac4j.core.context.WebContext
2121
import org.pac4j.core.profile.ProfileManager
2222
import org.pac4j.core.profile.UserProfile
2323
import org.pac4j.core.util.FindBest
24-
import org.pac4j.http.client.direct.DirectBearerAuthClient
24+
import au.org.ala.ws.security.client.AlaAuthClient
2525
import org.pac4j.jee.context.JEEContextFactory
2626
import org.springframework.beans.factory.annotation.Autowired
2727

@@ -35,7 +35,7 @@ class AuthorisedSystemService {
3535
@Autowired(required = false)
3636
Config config
3737
@Autowired(required = false)
38-
DirectBearerAuthClient directBearerAuthClient
38+
AlaAuthClient alaAuthClient
3939
@Autowired
4040
IAuthorisedSystemRepository authorisedSystemRepository
4141

@@ -64,15 +64,15 @@ class AuthorisedSystemService {
6464
ProfileManager profileManager = new ProfileManager(context, config.sessionStore)
6565
profileManager.setConfig(config)
6666

67-
def credentials = directBearerAuthClient.getCredentials(context, config.sessionStore)
67+
def credentials = alaAuthClient.getCredentials(context, config.sessionStore)
6868
if (credentials.isPresent()) {
69-
def profile = directBearerAuthClient.getUserProfile(credentials.get(), context, config.sessionStore)
69+
def profile = alaAuthClient.getUserProfile(credentials.get(), context, config.sessionStore)
7070
if (profile.isPresent()) {
7171
def userProfile = profile.get()
7272
profileManager.save(
73-
directBearerAuthClient.getSaveProfileInSession(context, userProfile),
73+
alaAuthClient.getSaveProfileInSession(context, userProfile),
7474
userProfile,
75-
directBearerAuthClient.isMultiProfile(context, userProfile)
75+
alaAuthClient.isMultiProfile(context, userProfile)
7676
)
7777

7878
result = true

0 commit comments

Comments
 (0)