mirror of
https://github.com/sasjs/adapter.git
synced 2025-12-11 09:24:35 +00:00
Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 3556eb3903 | |||
| 600e561a45 | |||
| 6a161a05ef | |||
| 8db02012e5 | |||
| a01b1a9feb | |||
| e6ec51c7eb |
@@ -78,7 +78,16 @@ export class AuthManager {
|
||||
|
||||
if (isLoggedIn) {
|
||||
if (this.serverType === ServerType.Sas9) {
|
||||
await this.performCASSecurityCheck()
|
||||
const casSecurityCheckResponse = await this.performCASSecurityCheck()
|
||||
|
||||
if (isPublicAccessDenied(casSecurityCheckResponse.result)) {
|
||||
return {
|
||||
isLoggedIn: false,
|
||||
userName: this.userName || '',
|
||||
userLongName: this.userLongName || '',
|
||||
errorMessage: 'Public access has been denied.'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const { userName, userLongName } = await this.fetchUserName()
|
||||
@@ -149,7 +158,17 @@ export class AuthManager {
|
||||
|
||||
if (isLoggedIn) {
|
||||
if (this.serverType === ServerType.Sas9) {
|
||||
await this.performCASSecurityCheck()
|
||||
const casSecurityCheckResponse = await this.performCASSecurityCheck()
|
||||
if (isPublicAccessDenied(casSecurityCheckResponse.result)) {
|
||||
isLoggedIn = false
|
||||
|
||||
return {
|
||||
isLoggedIn,
|
||||
userName: this.userName || '',
|
||||
userLongName: this.userLongName || '',
|
||||
errorMessage: 'Public access has been denied.'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.loginCallback()
|
||||
@@ -166,11 +185,15 @@ export class AuthManager {
|
||||
private async performCASSecurityCheck() {
|
||||
const casAuthenticationUrl = `${this.serverUrl}/SASStoredProcess/j_spring_cas_security_check`
|
||||
|
||||
await this.requestClient
|
||||
return await this.requestClient
|
||||
.get<string>(`/SASLogon/login?service=${casAuthenticationUrl}`, undefined)
|
||||
.catch((err) => {
|
||||
// ignore if resource not found error
|
||||
if (!(err instanceof NotFoundError)) throw err
|
||||
|
||||
return {
|
||||
result: ''
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -387,3 +410,7 @@ const isLogInSuccess = (serverType: ServerType, response: any): boolean => {
|
||||
|
||||
return /You have signed in/gm.test(response)
|
||||
}
|
||||
|
||||
const isPublicAccessDenied = (response: any): boolean => {
|
||||
return /Public access has been denied/gm.test(response)
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import axios from 'axios'
|
||||
import {
|
||||
mockedCurrentUserApi,
|
||||
mockLoginAuthoriseRequiredResponse,
|
||||
mockLoginPublicAccessDeniedResponse,
|
||||
mockLoginSuccessResponse
|
||||
} from './mockResponses'
|
||||
import { serialize } from '../../utils'
|
||||
@@ -213,6 +214,61 @@ describe('AuthManager', () => {
|
||||
expect(authCallback).toHaveBeenCalledTimes(1)
|
||||
})
|
||||
|
||||
it('should post a login & a cas_security request to the SAS9 server when not logged in & get rejected due to public access denied', async () => {
|
||||
const serverType = ServerType.Sas9
|
||||
const authManager = new AuthManager(
|
||||
serverUrl,
|
||||
serverType,
|
||||
requestClient,
|
||||
authCallback
|
||||
)
|
||||
jest.spyOn(authManager, 'checkSession').mockImplementation(() =>
|
||||
Promise.resolve({
|
||||
isLoggedIn: false,
|
||||
userName: '',
|
||||
userLongName: '',
|
||||
loginForm: { name: 'test' }
|
||||
})
|
||||
)
|
||||
mockedAxios.post.mockImplementationOnce(() =>
|
||||
Promise.resolve({ data: mockLoginSuccessResponse })
|
||||
)
|
||||
mockedAxios.get.mockImplementationOnce(() =>
|
||||
Promise.resolve({ data: mockLoginPublicAccessDeniedResponse })
|
||||
)
|
||||
|
||||
const loginResponse = await authManager.logIn(userName, password)
|
||||
|
||||
expect(loginResponse.isLoggedIn).toBeFalse()
|
||||
expect(loginResponse.userName).toEqual('')
|
||||
expect(loginResponse.errorMessage).toEqual(
|
||||
'Public access has been denied.'
|
||||
)
|
||||
|
||||
const loginParams = serialize({
|
||||
_service: 'default',
|
||||
username: userName,
|
||||
password,
|
||||
name: 'test'
|
||||
})
|
||||
expect(mockedAxios.post).toHaveBeenCalledWith(
|
||||
`/SASLogon/login`,
|
||||
loginParams,
|
||||
{
|
||||
withCredentials: true,
|
||||
headers: {
|
||||
'Content-Type': 'application/x-www-form-urlencoded',
|
||||
Accept: '*/*'
|
||||
}
|
||||
}
|
||||
)
|
||||
const casAuthenticationUrl = `${serverUrl}/SASStoredProcess/j_spring_cas_security_check`
|
||||
expect(mockedAxios.get).toHaveBeenCalledWith(
|
||||
`/SASLogon/login?service=${casAuthenticationUrl}`,
|
||||
getHeadersJson
|
||||
)
|
||||
})
|
||||
|
||||
it('should return empty username if unable to logged in', async () => {
|
||||
const authManager = new AuthManager(
|
||||
serverUrl,
|
||||
@@ -422,6 +478,53 @@ describe('AuthManager', () => {
|
||||
expect(authCallback).toHaveBeenCalledTimes(1)
|
||||
})
|
||||
|
||||
it('should return error if public account access is denied', async () => {
|
||||
const serverType = ServerType.Sas9
|
||||
const authManager = new AuthManager(
|
||||
serverUrl,
|
||||
serverType,
|
||||
requestClient,
|
||||
authCallback
|
||||
)
|
||||
jest
|
||||
.spyOn<any, any>(authManager, 'fetchUserName')
|
||||
.mockImplementationOnce(() =>
|
||||
Promise.resolve({
|
||||
isLoggedIn: false,
|
||||
userName: ''
|
||||
})
|
||||
)
|
||||
.mockImplementationOnce(() =>
|
||||
Promise.resolve({
|
||||
isLoggedIn: true,
|
||||
userName
|
||||
})
|
||||
)
|
||||
mockedAxios.get.mockImplementation(() =>
|
||||
Promise.resolve({ data: mockLoginPublicAccessDeniedResponse })
|
||||
)
|
||||
|
||||
const loginResponse = await authManager.redirectedLogIn({})
|
||||
|
||||
expect(loginResponse.isLoggedIn).toBeFalse()
|
||||
expect(loginResponse.userName).toEqual('')
|
||||
expect(loginResponse.errorMessage).toEqual(
|
||||
'Public access has been denied.'
|
||||
)
|
||||
|
||||
expect(openWebPageModule.openWebPage).toHaveBeenCalledWith(
|
||||
`/SASLogon`,
|
||||
'SASLogon',
|
||||
{
|
||||
width: 500,
|
||||
height: 600
|
||||
},
|
||||
undefined
|
||||
)
|
||||
expect(authManager['fetchUserName']).toHaveBeenCalledTimes(1)
|
||||
expect(verifySas9LoginModule.verifySas9Login).toHaveBeenCalledTimes(1)
|
||||
})
|
||||
|
||||
it('should return empty username if user unable to re-login via pop up', async () => {
|
||||
const authManager = new AuthManager(
|
||||
serverUrl,
|
||||
|
||||
@@ -2,6 +2,7 @@ import { SasAuthResponse } from '@sasjs/utils/types'
|
||||
|
||||
export const mockLoginAuthoriseRequiredResponse = `<form id="application_authorization" action="/SASLogon/oauth/authorize" method="POST"><input type="hidden" name="X-Uaa-Csrf" value="2nfuxIn6WaOURWL7tzTXCe"/>`
|
||||
export const mockLoginSuccessResponse = `You have signed in`
|
||||
export const mockLoginPublicAccessDeniedResponse = `Public access has been denied`
|
||||
|
||||
export const mockAuthResponse: SasAuthResponse = {
|
||||
access_token: 'acc355',
|
||||
|
||||
@@ -187,6 +187,12 @@ export class WebJobExecutor extends BaseJobExecutor {
|
||||
{ result: jsonResponse, log: res.log },
|
||||
extraResponseAttributes
|
||||
)
|
||||
|
||||
if (this.isPublicAccessDenied(jsonResponse))
|
||||
reject(
|
||||
new ErrorResponse('Public access has been denied', responseObject)
|
||||
)
|
||||
|
||||
resolve(responseObject)
|
||||
})
|
||||
.catch(async (e: Error) => {
|
||||
@@ -262,4 +268,8 @@ export class WebJobExecutor extends BaseJobExecutor {
|
||||
}
|
||||
return uri
|
||||
}
|
||||
|
||||
private isPublicAccessDenied = (response: string): boolean => {
|
||||
return /Public access has been denied/gm.test(response)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ export interface LoginResult {
|
||||
isLoggedIn: boolean
|
||||
userName: string
|
||||
userLongName: string
|
||||
errorMessage?: string
|
||||
}
|
||||
export interface LoginResultInternal {
|
||||
isLoggedIn: boolean
|
||||
|
||||
Reference in New Issue
Block a user