Skip to content

Commit 62e8dd2

Browse files
committed
feat(admin-ui): replace user-info with userInfoEndpoint endpoint
Signed-off-by: Jeet Viramgama <[email protected]>
1 parent 63cba77 commit 62e8dd2

File tree

7 files changed

+56
-146
lines changed

7 files changed

+56
-146
lines changed

admin-ui/app/redux/api/backend-api.js

+12-15
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
import axios from '../api/axios'
22
import axios_instance from 'axios'
33
const JansConfigApi = require('jans_config_api')
4-
import { useSelector } from 'react-redux'
5-
// Get OAuth2 Configuration
64

5+
// Get OAuth2 Configuration
76
export const fetchServerConfiguration = async (token) => {
87
const headers = { Authorization: `Bearer ${token}` }
98
return axios
@@ -30,20 +29,18 @@ export const getUserIpAndLocation = async () => {
3029
}
3130

3231
// Retrieve user information
33-
export const fetchUserInformation = async (code, codeVerifier) => {
32+
export const fetchUserInformation = async ({ userInfoEndpoint, token_type, access_token }) => {
33+
const headers = { Authorization: `${token_type} ${access_token}` }
3434
return axios
35-
.post('/app/admin-ui/oauth2/user-info', {
36-
code: code,
37-
codeVerifier: codeVerifier,
38-
})
39-
.then((response) => response.data)
40-
.catch((error) => {
41-
console.error(
42-
'Problems fetching user information with the provided code.',
43-
error,
44-
)
45-
return -1
46-
})
35+
.get(userInfoEndpoint, { headers })
36+
.then((response) => response.data)
37+
.catch((error) => {
38+
console.error(
39+
'Problems fetching user information with the provided code.',
40+
error,
41+
)
42+
return -1
43+
})
4744
}
4845

4946
// post user action

admin-ui/app/redux/features/authSlice.js

+6-17
Original file line numberDiff line numberDiff line change
@@ -41,21 +41,20 @@ const authSlice = createSlice({
4141
},
4242
getUserInfo: (state, action) => {},
4343
getUserInfoResponse: (state, action) => {
44-
if (action.payload?.uclaims) {
45-
state.userinfo = action.payload.uclaims
44+
if (action.payload?.ujwt) {
45+
state.userinfo = action.payload.userinfo
4646
state.userinfo_jwt = action.payload.ujwt
47-
state.permissions = action.payload.scopes
4847
state.isAuthenticated = true
4948
} else {
5049
state.isAuthenticated = true
5150
}
5251
},
5352
getAPIAccessToken: (state, action) => {},
5453
getAPIAccessTokenResponse: (state, action) => {
55-
if (action.payload?.accessToken) {
56-
state.token = action.payload.accessToken
57-
state.issuer = action.payload.accessToken.issuer
58-
state.permissions = action.payload.accessToken.scopes
54+
if (action.payload?.access_token) {
55+
state.token = { access_token: action.payload.access_token, scopes: action.payload.scopes }
56+
state.issuer = action.payload.issuer
57+
state.permissions = action.payload.scopes
5958
state.isAuthenticated = true
6059
}
6160
},
@@ -69,14 +68,6 @@ const authSlice = createSlice({
6968
state.defaultToken = action.payload
7069
state.issuer = action.payload.issuer
7170
},
72-
getRandomChallengePair: (state, action) => {},
73-
getRandomChallengePairResponse: (state, action) => {
74-
if (action.payload?.codeChallenge) {
75-
state.codeChallenge = action.payload.codeChallenge
76-
state.codeVerifier = action.payload.codeVerifier
77-
localStorage.setItem("codeVerifier", action.payload.codeVerifier)
78-
}
79-
},
8071
}
8172
})
8273

@@ -92,8 +83,6 @@ export const {
9283
getUserLocation,
9384
getUserLocationResponse,
9485
setApiDefaultToken,
95-
getRandomChallengePair,
96-
getRandomChallengePairResponse,
9786
} = authSlice.actions
9887
export default authSlice.reducer
9988
reducerRegistry.register('authReducer', authSlice.reducer)

admin-ui/app/redux/sagas/AuthSaga.js

+2-41
Original file line numberDiff line numberDiff line change
@@ -4,23 +4,17 @@
44
import { all, call, fork, put, takeEvery } from 'redux-saga/effects'
55
import {
66
getOAuth2ConfigResponse,
7-
getUserInfoResponse,
87
getAPIAccessTokenResponse,
98
getUserLocationResponse,
10-
getRandomChallengePairResponse,
119
} from '../features/authSlice'
1210

1311
import {
1412
fetchServerConfiguration,
15-
fetchUserInformation,
1613
fetchApiAccessToken,
1714
getUserIpAndLocation,
1815
fetchApiTokenWithDefaultScopes,
1916
} from '../api/backend-api'
2017

21-
import {RandomHashGenerator} from 'Utils/RandomHashGenerator'
22-
import { checkLicensePresentResponse } from '../actions'
23-
2418
function* getApiTokenWithDefaultScopes() {
2519
const response = yield call(fetchApiTokenWithDefaultScopes)
2620
return response.access_token
@@ -30,6 +24,7 @@ function* getOAuth2ConfigWorker({ payload }) {
3024
try {
3125
const token = !payload?.access_token ? yield* getApiTokenWithDefaultScopes() : payload.access_token
3226
const response = yield call(fetchServerConfiguration, token)
27+
localStorage.setItem('postLogoutRedirectUri', response.postLogoutRedirectUri)
3328
if (response) {
3429
yield put(getOAuth2ConfigResponse({ config: response }))
3530
return
@@ -40,24 +35,12 @@ function* getOAuth2ConfigWorker({ payload }) {
4035
yield put(getOAuth2ConfigResponse())
4136
}
4237

43-
function* getUserInformationWorker(code, codeVerifier) {
44-
try {
45-
const response = yield call(fetchUserInformation, code.payload, localStorage.getItem("codeVerifier"))
46-
if (response) {
47-
yield put(getUserInfoResponse({ uclaims: response.claims, ujwt: response.jwtUserInfo }))
48-
yield put(checkLicensePresentResponse({ isLicenseValid: true }))
49-
return
50-
}
51-
} catch (error) {
52-
console.log('Problems getting user information.', error)
53-
}
54-
}
5538
function* getAPIAccessTokenWorker(jwt) {
5639
try {
5740
if (jwt) {
5841
const response = yield call(fetchApiAccessToken, jwt.payload)
5942
if (response) {
60-
yield put(getAPIAccessTokenResponse({ accessToken: response }))
43+
yield put(getAPIAccessTokenResponse(response))
6144
return
6245
}
6346
}
@@ -66,19 +49,6 @@ function* getAPIAccessTokenWorker(jwt) {
6649
}
6750
}
6851

69-
function* getRandomChallengePairWorker() {
70-
try {
71-
const response = yield call(RandomHashGenerator.generateRandomChallengePair, 'SHA-256')
72-
if (response) {
73-
yield put(getRandomChallengePairResponse(response))
74-
return
75-
}
76-
77-
} catch (error) {
78-
console.log('Problems getting API Access Token.', error)
79-
}
80-
}
81-
8252
function* getLocationWorker() {
8353
try {
8454
const response = yield call(getUserIpAndLocation)
@@ -96,29 +66,20 @@ export function* getApiTokenWatcher() {
9666
yield takeEvery('auth/getAPIAccessToken', getAPIAccessTokenWorker)
9767
}
9868

99-
export function* userInfoWatcher() {
100-
yield takeEvery('auth/getUserInfo', getUserInformationWorker)
101-
}
102-
10369
export function* getOAuth2ConfigWatcher() {
10470
yield takeEvery('auth/getOAuth2Config', getOAuth2ConfigWorker)
10571
}
10672
export function* getLocationWatcher() {
10773
yield takeEvery('auth/getUserLocation', getLocationWorker)
10874
}
109-
export function* getRandomChallengePairWatcher() {
110-
yield takeEvery('auth/getRandomChallengePair', getRandomChallengePairWorker)
111-
}
11275

11376
/**
11477
* Auth Root Saga
11578
*/
11679
export default function* rootSaga() {
11780
yield all([
11881
fork(getOAuth2ConfigWatcher),
119-
fork(userInfoWatcher),
12082
fork(getApiTokenWatcher),
12183
fork(getLocationWatcher),
122-
fork(getRandomChallengePairWatcher),
12384
])
12485
}

admin-ui/app/utils/AppAuthProvider.js

+35-23
Original file line numberDiff line numberDiff line change
@@ -2,24 +2,19 @@ import React, { useState, useEffect } from 'react'
22
import ApiKeyRedirect from './ApiKeyRedirect'
33
import { useLocation } from 'react-router'
44
import {
5-
saveState,
65
NoHashQueryStringUtils,
7-
saveConfigRequest,
8-
getConfigRequest,
96
saveIssuer,
107
getIssuer
118
} from './TokenController'
129
import queryString from 'query-string'
1310
import { uuidv4 } from './Util'
1411
import { useSelector, useDispatch } from 'react-redux'
1512
import {
16-
getUserInfo,
1713
getAPIAccessToken,
1814
checkLicensePresent,
19-
getRandomChallengePair,
2015
} from 'Redux/actions'
2116
import SessionTimeout from 'Routes/Apps/Gluu/GluuSessionTimeout'
22-
import { checkLicenseConfigValid } from '../redux/actions'
17+
import { checkLicenseConfigValid, getOAuth2Config, getUserInfoResponse } from '../redux/actions'
2318
import GluuTimeoutModal from 'Routes/Apps/Gluu/GluuTimeoutModal'
2419
import GluuErrorModal from 'Routes/Apps/Gluu/GluuErrorModal'
2520
import {
@@ -34,21 +29,20 @@ import {
3429
AuthorizationNotifier,
3530
GRANT_TYPE_AUTHORIZATION_CODE,
3631
} from '@openid/appauth'
32+
import { fetchUserInformation } from 'Redux/api/backend-api'
33+
import jwt_decode from "jwt-decode";
3734

3835
export default function AppAuthProvider(props) {
3936
const dispatch = useDispatch()
4037
const location = useLocation()
41-
const [showContent, setShowContent] = useState(false)
4238
const [roleNotFound, setRoleNotFound] = useState(false)
39+
const [showAdminUI, setShowAdminUI] = useState(false)
4340
const {
4441
config,
4542
userinfo,
4643
userinfo_jwt,
4744
token,
4845
backendIsUp,
49-
codeChallenge,
50-
codeVerifier,
51-
codeChallengeMethod,
5246
issuer,
5347
} = useSelector((state) => state.authReducer)
5448
const {
@@ -63,7 +57,6 @@ export default function AppAuthProvider(props) {
6357
const params = queryString.parse(location.search)
6458
if (!(params.code && params.scope && params.state)) {
6559
dispatch(checkLicenseConfigValid())
66-
// dispatch(getRandomChallengePair())
6760
}
6861
}, [])
6962

@@ -102,7 +95,6 @@ export default function AppAuthProvider(props) {
10295
extras,
10396
})
10497
saveIssuer(issuer)
105-
saveConfigRequest(authRequest)
10698
authorizationHandler.performAuthorizationRequest(
10799
response,
108100
authRequest
@@ -123,13 +115,10 @@ export default function AppAuthProvider(props) {
123115
new DefaultCrypto()
124116
)
125117
const notifier = new AuthorizationNotifier()
126-
const config = getConfigRequest()
127118
const issuer = getIssuer()
128119

129120
notifier.setAuthorizationListener((request, response, error) => {
130-
console.log('the request', request)
131121
if (response) {
132-
console.log(`Authorization Code ${response.code}`)
133122

134123
let extras = null
135124
if (request.internal) {
@@ -144,17 +133,41 @@ export default function AppAuthProvider(props) {
144133
code: response.code,
145134
extras: { code_verifier: request.internal.code_verifier, scope: request.scope },
146135
})
147-
console.log(`tokenRequest`, tokenRequest)
136+
let authConfigs
137+
dispatch(getOAuth2Config())
148138

149139
AuthorizationServiceConfiguration.fetchFromIssuer(
150140
issuer,
151141
new FetchRequestor()
152142
)
153143
.then((configuration) => {
144+
authConfigs = configuration
154145
return tokenHandler.performTokenRequest(configuration, tokenRequest)
155146
})
156147
.then((token) => {
157-
localStorage.setItem('access_token', token.accessToken)
148+
return fetchUserInformation({ userInfoEndpoint: authConfigs.userInfoEndpoint, access_token: token.accessToken, token_type: token.tokenType })
149+
})
150+
.then((ujwt) => {
151+
if(!userinfo) {
152+
dispatch(getUserInfoResponse({ userinfo: jwt_decode(ujwt), ujwt: ujwt }))
153+
dispatch(getAPIAccessToken(ujwt))
154+
setShowAdminUI(true)
155+
} else {
156+
if (!userinfo.jansAdminUIRole || userinfo.jansAdminUIRole.length == 0) {
157+
setShowAdminUI(false)
158+
alert(
159+
'The logged-in user do not have valid role. Logging out of Admin UI'
160+
)
161+
setRoleNotFound(true)
162+
const state = uuidv4()
163+
const sessionEndpoint = `${authConfigs.endSessionEndpoint}?state=${state}&post_logout_redirect_uri=${localStorage.getItem('postLogoutRedirectUri')}`
164+
window.location.href = sessionEndpoint
165+
return null
166+
}
167+
if (!token) {
168+
dispatch(getAPIAccessToken(userinfo_jwt))
169+
}
170+
}
158171
})
159172
.catch((oError) => {
160173
setError(oError)
@@ -177,7 +190,7 @@ export default function AppAuthProvider(props) {
177190

178191
return (
179192
<React.Fragment>
180-
<SessionTimeout isAuthenticated={showContent} />
193+
<SessionTimeout isAuthenticated={showAdminUI} />
181194
<GluuTimeoutModal
182195
description={
183196
'The request has been terminated as there is no response from the server for more than 60 seconds.'
@@ -191,18 +204,17 @@ export default function AppAuthProvider(props) {
191204
}
192205
/>
193206
)}
194-
{showContent && props.children}
195-
{!showContent && (
207+
{showAdminUI && props.children}
208+
{!showAdminUI && (
196209
<ApiKeyRedirect
197210
backendIsUp={backendIsUp}
198211
isLicenseValid={isLicenseValid}
199-
redirectUrl={config.redirectUrl}
200212
isConfigValid={isConfigValid}
201213
islicenseCheckResultLoaded={islicenseCheckResultLoaded}
202214
isLicenseActivationResultLoaded={isLicenseActivationResultLoaded}
215+
roleNotFound={roleNotFound}
203216
/>
204217
)}
205218
</React.Fragment>
206219
)
207-
}
208-
220+
}

0 commit comments

Comments
 (0)