Skip to content

Commit

Permalink
Refactor web services #141
Browse files Browse the repository at this point in the history
  • Loading branch information
yasima-csiro committed Dec 14, 2022
1 parent 542166e commit a9946bd
Show file tree
Hide file tree
Showing 7 changed files with 111 additions and 32 deletions.
2 changes: 1 addition & 1 deletion userdetails-gorm/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ dependencies {

implementation "org.grails.plugins:ala-bootstrap3:4.1.0"
implementation "org.grails.plugins:ala-ws-plugin:3.1.1"
implementation "org.grails.plugins:ala-ws-security-plugin:4.3.3-SNAPSHOT"
implementation "org.grails.plugins:ala-ws-security-plugin:4.3.5-SNAPSHOT"
implementation "org.grails.plugins:ala-auth:5.2.0-CognitoLogoutFix-SNAPSHOT"
implementation "org.grails.plugins:ala-admin-plugin:2.3.0"

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ class GormUserService implements IUserService {
LocationService locationService
MessageSource messageSource
WebService webService
ProfileService profileService

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

@Override
void enableMfa(String userId, boolean enable){}
boolean removeUserRole(User user, Role role) {
return false
}

@Override
User findByUserNameOrEmail(String userName) {
return User.findByUserNameOrEmail(userName, userName)
}

@Override
def findUsersByRole(String roleName, List numberIds, List userIds, String pageOrToken) {
ScrollableResults results = null
// stream the results just in case someone requests ROLE_USER or something
User.withStatelessSession { session ->
Role role = Role.findByRole(roleName)
if (!role) {
return [error: "Role not found"]
}

def c = User.createCriteria()
results = c.scroll {
or {
if (numberIds) {
inList('id', numberIds*.toLong())
}
if (userIds) {
inList('userName', userIds)
inList('email', userIds)
}
}
userRoles {
eq("role", role)
}
} as ScrollableResults
}
return [results: results]
}

def getUserDetailsFromIdList(List idList){
def c = User.createCriteria()
def results = c.list() {
'in'("id", idList.collect { userId -> userId as long } )
}
return results
}

def searchByUsernameOrEmail(String q, int max){

ScrollableResults results = null

User.withStatelessSession { session ->
def c = User.createCriteria()
results = c.scroll {
or {
ilike('userName', "%$q%")
ilike('email', "%$q%")
ilike('displayName', "%$q%")
}
maxResults(max)
} as ScrollableResults
}
return [results: results]
}

def saveCustomUserProperty(User user, String name, String value){
UserProperty property = profileService.saveUserProperty(user, name, value)
return property.hasErrors() ? null: property
}

def getCustomUserProperty(User user, String name){
return profileService.getUserProperty(user, name);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,6 @@ class PropertyController extends BaseController {
name = "alaId",
in = QUERY,
description = "The user's ALA ID",
schema = @Schema(implementation = Long),
required = true
),
@Parameter(
Expand Down Expand Up @@ -100,14 +99,14 @@ class PropertyController extends BaseController {
@PreAuthorise(requiredScope = 'users/read')
def getProperty() {
String name = params.name
Long alaId = params.long('alaId')
String alaId = params.alaId
if (!name || !alaId) {
badRequest "name and alaId must be provided";
} else {
UserRecord user = userService.getUserById(alaId);
List props
if (user) {
props = profileService.getUserProperty(user, name);
props = userService.getCustomUserProperty(user, name)
render text: props as JSON, contentType: 'application/json'
} else {
notFound "Could not find user for id: ${alaId}";
Expand All @@ -130,7 +129,6 @@ class PropertyController extends BaseController {
name = "alaId",
in = QUERY,
description = "The user's ALA ID",
schema = @Schema(implementation = Long),
required = true
),
@Parameter(
Expand Down Expand Up @@ -178,15 +176,15 @@ class PropertyController extends BaseController {
def saveProperty(){
String name = params.name;
String value = params.value;
Long alaId = params.long('alaId');
String alaId = params.alaId
if (!name || !alaId) {
badRequest "name and alaId must be provided";
} else {
UserRecord user = userService.getUserById(alaId);
UserPropertyRecord property
if (user) {
property = profileService.saveUserProperty(user, name, value);
if (property.hasErrors()) {
property = userService.saveCustomUserProperty(user, name, value);
if (!property) {
saveFailed()
} else {
render text: property as JSON, contentType: 'application/json'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,18 @@ class RoleBasedInterceptor {
PreAuthorise pa = method.getAnnotation(PreAuthorise) ?: controllerClass.getAnnotation(PreAuthorise)
response.withFormat {
json {
if (!authorisedSystemService.isAuthorisedRequest(request, response, pa.requiredRole(), pa.requiredScope())) {
log.warn("Denying access to $actionName from remote addr: ${request.remoteAddr}, remote host: ${request.remoteHost}")
response.status = HttpStatus.SC_UNAUTHORIZED
render(['error': "Unauthorized"] as JSON)
try{
if (!authorisedSystemService.isAuthorisedRequest(request, response, pa.requiredRole(), pa.requiredScope())) {
log.warn("Denying access to $actionName from remote addr: ${request.remoteAddr}, remote host: ${request.remoteHost}")
response.status = HttpStatus.SC_UNAUTHORIZED
render(['error': "Unauthorized"] as JSON)

result = false
result = false
}
}
catch (Exception e){
response.sendError(HttpStatus.SC_UNAUTHORIZED, e.getMessage())
return false
}
}
'*' {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,6 @@ class UserDetailsController {
user = userService.getUserById(userName)
} else {
user = userService.findByUserNameOrEmail(userName)
// user = UserRecord.findByUserNameOrEmail(userName, userName)
}
} else {
render status:400, text: "Missing parameter: userName"
Expand Down Expand Up @@ -422,24 +421,21 @@ class UserDetailsController {
if (req && req.userIds) {

try {
List<Long> idList = req.userIds.collect { userId -> userId as long }
List idList = req.userIds

def c = UserRecord.createCriteria()
def results = c.list() {
'in'("id", idList)
}
def results = userService.getUserDetailsFromIdList(idList)
String jsonConfig = includeProps ? UserMarshaller.WITH_PROPERTIES_CONFIG : null
try {

JSON.use(jsonConfig)

def resultsMap = [users:[:], invalidIds:[], success: true]
results.each { user ->
resultsMap.users[user.id] = user
resultsMap.users[user.userId] = user
}

idList.each {
if (!resultsMap.users[it]) {
if (!resultsMap.users[it.toString()]) {
resultsMap.invalidIds << it
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,19 @@ class UserDetailsWebServicesInterceptor {
}

boolean before() {
if (!authorisedSystemService.isAuthorisedRequest(request, response, null, 'users/read')) {
log.warn("Denying access to $actionName from remote addr: ${request.remoteAddr}, remote host: ${request.remoteHost}")
response.sendError(HttpStatus.SC_UNAUTHORIZED)

try {
if (!authorisedSystemService.isAuthorisedRequest(request, response, null, 'users/read')) {
log.warn("Denying access to $actionName from remote addr: ${request.remoteAddr}, remote host: ${request.remoteHost}")
response.sendError(HttpStatus.SC_UNAUTHORIZED)

return false
}
return true
}
catch (Exception e){
response.sendError(HttpStatus.SC_UNAUTHORIZED, e.getMessage())
return false
}
return true
}

boolean after() { true }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import org.pac4j.core.context.WebContext
import org.pac4j.core.profile.ProfileManager
import org.pac4j.core.profile.UserProfile
import org.pac4j.core.util.FindBest
import org.pac4j.http.client.direct.DirectBearerAuthClient
import au.org.ala.ws.security.client.AlaAuthClient
import org.pac4j.jee.context.JEEContextFactory
import org.springframework.beans.factory.annotation.Autowired

Expand All @@ -35,7 +35,7 @@ class AuthorisedSystemService {
@Autowired(required = false)
Config config
@Autowired(required = false)
DirectBearerAuthClient directBearerAuthClient
AlaAuthClient alaAuthClient
@Autowired
IAuthorisedSystemRepository authorisedSystemRepository

Expand Down Expand Up @@ -64,15 +64,15 @@ class AuthorisedSystemService {
ProfileManager profileManager = new ProfileManager(context, config.sessionStore)
profileManager.setConfig(config)

def credentials = directBearerAuthClient.getCredentials(context, config.sessionStore)
def credentials = alaAuthClient.getCredentials(context, config.sessionStore)
if (credentials.isPresent()) {
def profile = directBearerAuthClient.getUserProfile(credentials.get(), context, config.sessionStore)
def profile = alaAuthClient.getUserProfile(credentials.get(), context, config.sessionStore)
if (profile.isPresent()) {
def userProfile = profile.get()
profileManager.save(
directBearerAuthClient.getSaveProfileInSession(context, userProfile),
alaAuthClient.getSaveProfileInSession(context, userProfile),
userProfile,
directBearerAuthClient.isMultiProfile(context, userProfile)
alaAuthClient.isMultiProfile(context, userProfile)
)

result = true
Expand Down

0 comments on commit a9946bd

Please sign in to comment.