Skip to content

Commit

Permalink
feat: form auth - redirect to auth page for custom id provider (#88)
Browse files Browse the repository at this point in the history
  • Loading branch information
tsaleksandrova authored and maximnaidenov committed Jun 19, 2019
1 parent 9d89e79 commit 6dc6e1c
Show file tree
Hide file tree
Showing 6 changed files with 66 additions and 16 deletions.
2 changes: 2 additions & 0 deletions docs/config/authentication.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ auth: {
userFieldSelector: '<CSS selector of user input field>',
passFieldSelector: '<CSS selector of password input field>',
logonButtonSelector: '<CSS selector of submit button>',
idpSelector: '<CSS selector of login link>',
user: '<user>',
pass: '<pass>'
}
Expand Down Expand Up @@ -82,6 +83,7 @@ Implemented in [formAuthenticator.js](../../src/authenticator/formAuthenticator.
* userFieldSelector - the CSS selctor for the user input field
* passFieldSelector - the CSS selector for the password input field
* logonButtonSelector - the CSS selector for the submit button
* idpSelector - the CSS selector for the link to log in with a different ID provider
* frameSelector - if provided, the inoput fields are searched in this iFrame
* redirectUrl - if provided, it overides the basicUrl that is used to synchronize on page redirect that the identitty provider
initiates after successfull authentication. Request arguments and fragment are removed when matching, RegExp is supported.
Expand Down
3 changes: 2 additions & 1 deletion e2e/scenario/fixture/apps/formauth/app.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,10 @@
<script>
var url = new URL(window.location.href);
var authFlag = url.searchParams.get('auth');
var idpFlag = url.searchParams.get('idp');
// redirect to login if no ?auth=true
if (!authFlag || authFlag != 'true') {
window.location.replace('./login.html?callback=./app.html');
window.location.replace('./login.html?redirect=app.html&idp=' + idpFlag);
}
</script>

Expand Down
37 changes: 26 additions & 11 deletions e2e/scenario/fixture/apps/formauth/login.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,33 @@
<meta charset="utf-8">
<title>IDP mock - Login Page</title>
<script>
// attach form action and redirect to ?callback=<url>. append ?auth=true
// attach form action and redirect to ?redirect=<url>. append ?auth=true
window.addEventListener('DOMContentLoaded',() => {
document.getElementById('logOnFormSubmit').onclick = () => {
let user = document.getElementById('j_username').value;
let pass = document.getElementById('j_password').value;
var url = new URL(window.location.href);
var callback = url.searchParams.get('callback');
var redirectUrl = callback + '?auth=true&user=' + user + '&pass=' + pass;
console.log('RedirectUrl:' + redirectUrl);
window.location.replace(redirectUrl);
};
var loginForm = document.getElementsByTagName('form')[0];
var url = new URL(window.location.href);
var idpFlag = url.searchParams.get('idp');
var redirectParam = url.searchParams.get('redirect');

if (idpFlag === 'true') {
var link = document.createElement('a');
link.id = 'saml-login-link';
link.href = './login.html?redirect=' + redirectParam;
link.textContent = 'Login with SAML';
loginForm.append(link);
} else {
var loginBtn = document.createElement('button');
loginBtn.id = 'logOnFormSubmit';
loginBtn.textContent = 'Login';
loginBtn.onclick = (e) => {
e.preventDefault();
let user = document.getElementById('j_username').value;
let pass = document.getElementById('j_password').value;
var redirectUrl = redirectParam + '?auth=true&user=' + user + '&pass=' + pass;
console.log('RedirectUrl:' + redirectUrl);
window.location.replace(redirectUrl);
};
loginForm.append(loginBtn);
}
});
</script>
</head>
Expand All @@ -25,7 +41,6 @@
<div>
<input id="j_username" type="text" placeholder="Username" name="username" required>
<input id="j_password" type="password" placeholder="Password" name="password" required>
<button id="logOnFormSubmit" type="button">Login</button>
</div>
</form>
</body>
Expand Down
10 changes: 9 additions & 1 deletion e2e/scenario/formauth.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,12 @@ describe('FormAuth scenario test', function() {
confjs: './scenario/formauth_regexp.conf.js'
});
},40000);
});

it('should execute auth with custom idp link', () => {
return Runner.execTest({
specs: './scenario/fixture/empty.spec.js',
baseUrl: app.host + '/formauth/app.html?idp=true',
confjs: './scenario/formauth_idp.conf.js'
});
},40000);
});
9 changes: 9 additions & 0 deletions e2e/scenario/formauth_idp.conf.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
exports.config = {
auth: {
'sapcloud-form': {
user: 'user',
pass: 'pass',
idpSelector: "#saml-login-link"
}
}
};
21 changes: 18 additions & 3 deletions src/authenticator/formAuthenticator.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ function FormAuthenticator(config,instanceConfig,logger,statisticsCollector){
this.userFieldSelector = instanceConfig.userFieldSelector;
this.passFieldSelector = instanceConfig.passFieldSelector;
this.logonButtonSelector = instanceConfig.logonButtonSelector;
this.idpSelector = instanceConfig.idpSelector;
this.redirectUrl = instanceConfig.redirectUrl;
this.statisticsCollector = statisticsCollector;
}
Expand All @@ -40,6 +41,22 @@ FormAuthenticator.prototype.get = function(url){
// open the page
browser.driver.get(url);

// collect login actions separately
this.statisticsCollector.authStarted();

// handle idp selection
if (this.idpSelector) {
browser.driver.wait(function(){
return browser.driver.findElements(by.css(that.idpSelector)).then(function (elements) {
return !!elements.length;
});
}, browser.getPageTimeout, 'Waiting for default IDP auth page to fully load');

browser.driver.findElement(by.css(this.idpSelector)).click().then(function () {
that.logger.debug('Opening custom IDP auth page');
});
}

// wait till redirection is complete and page is fully rendered
var switchedToFrame = false;
browser.driver.wait(function(){
Expand All @@ -56,10 +73,8 @@ FormAuthenticator.prototype.get = function(url){
return browser.driver.findElements(by.css(that.userFieldSelector)).then(function (elements) {
return !!elements.length;
});
},browser.getPageTimeout,'Waiting for auth page to fully load');
},browser.getPageTimeout,'Waiting for' + (this.idpSelector ? ' custom IDP' : '') + ' auth page to fully load');

// collect login actions separately
this.statisticsCollector.authStarted();
// enter user and pass in the respective fields
browser.driver.findElement(by.css(this.userFieldSelector)).sendKeys(this.user);
browser.driver.findElement(by.css(this.passFieldSelector)).sendKeys(this.pass);
Expand Down

0 comments on commit 6dc6e1c

Please sign in to comment.