1
1
package au.org.ala.ecodata.forms
2
2
3
+ import au.org.ala.web.UserDetails
3
4
import org.grails.web.servlet.mvc.GrailsWebRequest
4
5
import org.pac4j.core.config.Config
5
6
import org.pac4j.core.context.WebContext
6
7
import org.pac4j.core.credentials.Credentials
7
8
import org.pac4j.core.util.FindBest
8
9
import org.pac4j.jee.context.JEEContextFactory
9
- import org.pac4j.http. client.direct.DirectBearerAuthClient
10
+ import au. org.ala.ws.security. client.AlaOidcClient
10
11
import org.springframework.beans.factory.annotation.Autowired
11
12
import org.springframework.http.HttpStatus
12
13
@@ -36,12 +37,46 @@ class UserInfoService {
36
37
@Autowired (required = false )
37
38
Config config
38
39
@Autowired (required = false )
39
- DirectBearerAuthClient directBearerAuthClient
40
+ AlaOidcClient alaOidcClient
40
41
41
42
static String USER_NAME_HEADER_FIELD = " userName"
42
43
static String AUTH_KEY_HEADER_FIELD = " authKey"
43
44
static String AUTHORIZATION_HEADER_FIELD = " Authorization"
44
45
46
+ private static ThreadLocal<UserDetails > _currentUser = new ThreadLocal<UserDetails > ()
47
+
48
+ String getCurrentUserDisplayName () {
49
+ getCurrentUser()?. displayName
50
+ }
51
+
52
+ UserDetails getCurrentUser () {
53
+ _currentUser. get()
54
+ }
55
+
56
+ /**
57
+ * This method gets called by a filter at the beginning of the request (if a userId parameter is on the URL)
58
+ * It sets the user details in a thread local for extraction by the audit service.
59
+ * @param userId
60
+ */
61
+ UserDetails setCurrentUser () {
62
+ clearCurrentUser()
63
+ UserDetails userDetails = getCurrentUserFromSupportedMethods()
64
+
65
+ if (userDetails) {
66
+ _currentUser. set(userDetails)
67
+ } else {
68
+ log. warn(" Failed to get user details! No details set on thread local." )
69
+ }
70
+
71
+ userDetails
72
+ }
73
+
74
+ def clearCurrentUser () {
75
+ if (_currentUser) {
76
+ _currentUser. remove()
77
+ }
78
+ }
79
+
45
80
/**
46
81
* Get User details for the given user name and auth key.
47
82
*
@@ -50,18 +85,13 @@ class UserInfoService {
50
85
* @return Map
51
86
*
52
87
**/
53
- Map getUserFromAuthKey (String username , String key ) {
88
+ UserDetails getUserFromAuthKey (String username , String key ) {
54
89
String url = grailsApplication. config. getProperty(' mobile.auth.check.url' )
55
90
Map params = [userName : username, authKey : key]
56
91
def result = webService. doPostWithParams(url, params)
57
92
58
93
if (result. statusCode == HttpStatus . OK . value() && result. resp?. status == ' success' ) {
59
- params = [userName : username]
60
- url = grailsApplication. config. getProperty(' userDetails.url' ) + " userDetails/getUserDetails"
61
- result = webService. doPostWithParams(url, params)
62
- if (result. statusCode == HttpStatus . OK . value() && result. resp) {
63
- return [' displayName' : " ${ result.resp.firstName} ${ result.resp.lastName} " , ' userName' : result. resp. userName, ' userId' : result. resp. userId]
64
- }
94
+ return authService. getUserForEmailAddress(username, true )
65
95
} else {
66
96
log. error(" Failed to get user details for parameters: ${ params.toString()} " )
67
97
log. error(result. toString())
@@ -73,57 +103,65 @@ class UserInfoService {
73
103
* @param authorizationHeader
74
104
* @return
75
105
*/
76
- Map getUserFromJWT (String authorizationHeader = null ) {
77
- if ((config == null ) || (directBearerAuthClient == null ))
106
+ UserDetails getUserFromJWT (String authorizationHeader = null ) {
107
+ if ((config == null ) || (alaOidcClient == null ))
78
108
return
79
-
80
- GrailsWebRequest grailsWebRequest = GrailsWebRequest . lookup()
81
- HttpServletRequest request = grailsWebRequest. getCurrentRequest()
82
- HttpServletResponse response = grailsWebRequest. getCurrentResponse()
83
- if (! authorizationHeader)
84
- authorizationHeader = request?. getHeader(AUTHORIZATION_HEADER_FIELD )
85
- if (authorizationHeader?. startsWith(" Bearer" )) {
86
- final WebContext context = FindBest . webContextFactory(null , config, JEEContextFactory . INSTANCE ). newContext(request, response)
87
- def optCredentials = directBearerAuthClient. getCredentials(context, config. sessionStore)
88
- if (optCredentials. isPresent()) {
89
- Credentials credentials = optCredentials. get()
90
- def optUserProfile = directBearerAuthClient. getUserProfile(credentials, context, config. sessionStore)
91
- if (optUserProfile. isPresent()) {
92
- def userProfile = optUserProfile. get()
93
- return [' displayName' : " ${ userProfile.getAttribute("given_name")} ${ userProfile.getAttribute("family_name")} " , ' userName' : userProfile. getAttribute(" email" ), ' userId' : userProfile. getAttribute(" userid" )]
109
+ try {
110
+ GrailsWebRequest grailsWebRequest = GrailsWebRequest . lookup()
111
+ HttpServletRequest request = grailsWebRequest. getCurrentRequest()
112
+ HttpServletResponse response = grailsWebRequest. getCurrentResponse()
113
+ if (! authorizationHeader)
114
+ authorizationHeader = request?. getHeader(AUTHORIZATION_HEADER_FIELD )
115
+ if (authorizationHeader?. startsWith(" Bearer" )) {
116
+ final WebContext context = FindBest . webContextFactory(null , config, JEEContextFactory . INSTANCE ). newContext(request, response)
117
+ def optCredentials = alaOidcClient. getCredentials(context, config. sessionStore)
118
+ if (optCredentials. isPresent()) {
119
+ Credentials credentials = optCredentials. get()
120
+ def optUserProfile = alaOidcClient. getUserProfile(credentials, context, config. sessionStore)
121
+ if (optUserProfile. isPresent()) {
122
+ def userProfile = optUserProfile. get()
123
+ String userId = userProfile?. userId ?: userProfile?. getAttribute(grailsApplication. config. getProperty(' userProfile.userIdAttribute' ))
124
+ if (userId) {
125
+ return authService. getUserForUserId(userId)
126
+ }
127
+ }
94
128
}
95
129
}
130
+ } catch (Throwable e) {
131
+ log. error(" Failed to get user details from JWT" , e)
132
+ return
96
133
}
97
134
}
98
135
99
136
/**
100
137
* Get details of the current user either from CAS or lookup to user details server.
101
138
* Authentication details are provide in header userName and authKey
102
- * @return Map with following key
103
- * ['displayName': "", 'userName': "", 'userId': ""]
139
+ * @return UserDetails
104
140
*/
105
- def getCurrentUser () {
141
+ UserDetails getCurrentUserFromSupportedMethods () {
106
142
def user
107
143
108
144
// First, check if CAS can get logged in user details
109
145
def userDetails = authService. userDetails()
110
- if (userDetails) {
111
- user = [' displayName' : " ${ userDetails.firstName} ${ userDetails.lastName} " , ' userName' : userDetails. userName, ' userId' : userDetails. userId]
112
- }
146
+ user = userDetails?: null
113
147
114
148
// Second, check if request has headers to lookup user details.
115
149
if (! user) {
116
- GrailsWebRequest request = GrailsWebRequest . lookup()
117
- if (request) {
118
- String authorizationHeader = request?. getHeader(AUTHORIZATION_HEADER_FIELD )
119
- String username = request. getHeader(UserInfoService . USER_NAME_HEADER_FIELD )
120
- String key = request. getHeader(UserInfoService . AUTH_KEY_HEADER_FIELD )
121
-
122
- if (authorizationHeader) {
123
- user = getUserFromJWT(authorizationHeader)
124
- } else if (grailsApplication. config. getProperty(" mobile.authKeyEnabled" , Boolean ) && username && key) {
125
- user = getUserFromAuthKey(username, key)
150
+ try {
151
+ GrailsWebRequest request = GrailsWebRequest . lookup()
152
+ if (request) {
153
+ String authorizationHeader = request?. getHeader(AUTHORIZATION_HEADER_FIELD )
154
+ String username = request. getHeader(UserInfoService . USER_NAME_HEADER_FIELD )
155
+ String key = request. getHeader(UserInfoService . AUTH_KEY_HEADER_FIELD )
156
+
157
+ if (authorizationHeader) {
158
+ user = getUserFromJWT(authorizationHeader)
159
+ } else if (grailsApplication. config. getProperty(" mobile.authKeyEnabled" , Boolean ) && username && key) {
160
+ user = getUserFromAuthKey(username, key)
161
+ }
126
162
}
163
+ } catch (Throwable e) {
164
+ log. error(" Failed to get user details from JWT or API key" , e)
127
165
}
128
166
}
129
167
0 commit comments