Skip to content

Commit

Permalink
[WIP] 2FA auth support
Browse files Browse the repository at this point in the history
  • Loading branch information
fredj committed Oct 4, 2019
1 parent 52bc6d8 commit 5b47de5
Show file tree
Hide file tree
Showing 9 changed files with 43 additions and 10 deletions.
2 changes: 1 addition & 1 deletion contribs/gmf/apps/desktop/index.html.ejs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<title ng-bind-template="{{'Desktop Application'|translate}}">GeoMapFish</title>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1.0, user-scalable=no, width=device-width">
<meta name="dynamicUrl" content="https://geomapfish-demo-2-5.camptocamp.com/dynamic.json">
<meta name="dynamicUrl" content="https://geomapfish-demo-2-5-2fa.paas-ch-3.camptocamp.com/dynamic.json">
<meta name="interface" content="desktop">
<link rel="shortcut icon" href="<%=require("./image/favicon.ico")%>" />
<% for (var css in htmlWebpackPlugin.files.css) { %>
Expand Down
2 changes: 1 addition & 1 deletion contribs/gmf/apps/desktop_alt/index.html.ejs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<title ng-bind-template="{{'Alternative Desktop Application'|translate}}">GeoMapFish</title>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1.0, user-scalable=no, width=device-width">
<meta name="dynamicUrl" content="https://geomapfish-demo-2-5.camptocamp.com/dynamic.json">
<meta name="dynamicUrl" content="https://geomapfish-demo-2-5-2fa.paas-ch-3.camptocamp.com/dynamic.json">
<meta name="interface" content="desktop_alt">
<link rel="shortcut icon" href="<%=require("./image/favicon.ico")%>" />
<% for (var css in htmlWebpackPlugin.files.css) { %>
Expand Down
2 changes: 1 addition & 1 deletion contribs/gmf/apps/iframe_api/index.html.ejs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<title ng-bind-template="{{'Iframe API Application'|translate}}">GeoMapFish</title>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1.0, user-scalable=no, width=device-width">
<meta name="dynamicUrl" content="https://geomapfish-demo-2-5.camptocamp.com/dynamic.json">
<meta name="dynamicUrl" content="https://geomapfish-demo-2-5-2fa.paas-ch-3.camptocamp.com/dynamic.json">
<meta name="interface" content="iframe_api">
<link rel="shortcut icon" href="<%=require("./image/favicon.ico")%>" />
<% for (var css in htmlWebpackPlugin.files.css) { %>
Expand Down
2 changes: 1 addition & 1 deletion contribs/gmf/apps/mobile/index.html.ejs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<meta name="viewport" content="initial-scale=1.0, user-scalable=no, width=device-width">
<meta name="mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="dynamicUrl" content="https://geomapfish-demo-2-5.camptocamp.com/dynamic.json">
<meta name="dynamicUrl" content="https://geomapfish-demo-2-5-2fa.paas-ch-3.camptocamp.com/dynamic.json">
<meta name="interface" content="mobile">
<link rel="shortcut icon" href="<%=require("./image/favicon.ico")%>" />
<% for (var css in htmlWebpackPlugin.files.css) { %>
Expand Down
2 changes: 1 addition & 1 deletion contribs/gmf/apps/mobile_alt/index.html.ejs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<meta name="viewport" content="initial-scale=1.0, user-scalable=no, width=device-width">
<meta name="mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="dynamicUrl" content="https://geomapfish-demo-2-5.camptocamp.com/dynamic.json">
<meta name="dynamicUrl" content="https://geomapfish-demo-2-5-2fa.paas-ch-3.camptocamp.com/dynamic.json">
<meta name="interface" content="mobile_alt">
<link rel="shortcut icon" href="<%=require("./image/favicon.ico")%>" />
<% for (var css in htmlWebpackPlugin.files.css) { %>
Expand Down
2 changes: 1 addition & 1 deletion contribs/gmf/apps/oeedit/index.html.ejs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<title ng-bind-template="{{'ObjectEditing - Edit Application'|translate}}">GeoMapFish</title>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1.0, user-scalable=no, width=device-width">
<meta name="dynamicUrl" content="https://geomapfish-demo-2-5.camptocamp.com/dynamic.json">
<meta name="dynamicUrl" content="https://geomapfish-demo-2-5-2fa.paas-ch-3.camptocamp.com/dynamic.json">
<meta name="interface" content="oeedit">
<link rel="shortcut icon" href="<%=require("./image/favicon.ico")%>" />
<% for (var css in htmlWebpackPlugin.files.css) { %>
Expand Down
13 changes: 11 additions & 2 deletions contribs/gmf/src/authentication/Service.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ import * as Sentry from '@sentry/browser';
* False otherwise.
* @property {RoleInfo[]} roles Roles information.
* @property {string|null} username The name of the user.
* @property {string|null} otp_key
* @property {string|null} otp_uri
*/


Expand All @@ -49,6 +51,8 @@ import * as Sentry from '@sentry/browser';
* @property {boolean} [is_password_changed]
* @property {RoleInfo[]} [roles]
* @property {string} [username]
* @property {string} [otp_key]
* @property {string} [otp_uri]
*/


Expand Down Expand Up @@ -172,12 +176,17 @@ export class AuthenticationService extends olEventsEventTarget {
/**
* @param {string} login Login name.
* @param {string} pwd Password.
* @param {string} [otp]
* @return {angular.IPromise<angular.IHttpResponse<AuthenticationLoginResponse>>} Promise.
*/
login(login, pwd) {
login(login, pwd, otp = undefined) {
const url = `${this.baseUrl_}/${RouteSuffix.LOGIN}`;
const params = {'login': login, 'password': pwd};
if (otp) {
Object.assign(params, {'otp': otp});
}

return this.$http_.post(url, $.param({'login': login, 'password': pwd}), {
return this.$http_.post(url, $.param(params), {
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
withCredentials: true
}).then(
Expand Down
8 changes: 8 additions & 0 deletions contribs/gmf/src/authentication/component.html
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,14 @@
ng-model="$ctrl.pwdVal"
ng-attr-placeholder="{{'Password' | translate}}"/>
</div>
<div ng-if="$ctrl.twoFactorAuth" class="form-group">
<input
type="text"
class="form-control"
name="otp"
ng-model="$ctrl.otpVal"
ng-attr-placeholder="{{'Authentication code' | translate}}"/>
</div>
<div class="form-group">
<input
type="submit"
Expand Down
20 changes: 18 additions & 2 deletions contribs/gmf/src/authentication/component.js
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,7 @@ module.component('gmfAuthentication', authenticationComponent);
class AuthenticationController {
/**
* @param {JQuery} $element Element.
* @param {boolean} gmfTwoFactorAuth Two factor authentication is required.
* @param {angular.gettext.gettextCatalog} gettextCatalog Gettext catalog.
* @param {import("gmf/authentication/Service.js").AuthenticationService} gmfAuthenticationService
* GMF Authentication service
Expand All @@ -156,7 +157,7 @@ class AuthenticationController {
* @ngdoc controller
* @ngname GmfAuthenticationController
*/
constructor($element, gettextCatalog, gmfAuthenticationService, gmfUser, ngeoNotification) {
constructor($element, gmfTwoFactorAuth, gettextCatalog, gmfAuthenticationService, gmfUser, ngeoNotification) {

/**
* @type {JQuery}
Expand Down Expand Up @@ -187,6 +188,11 @@ class AuthenticationController {
*/
this.notification_ = ngeoNotification;

/**
* @type {boolean}
*/
this.twoFactorAuth = gmfTwoFactorAuth;

/**
* @type {boolean}
*/
Expand Down Expand Up @@ -244,6 +250,11 @@ class AuthenticationController {
*/
this.pwdVal = '';

/**
* @type {string}
*/
this.otpVal;

// CHANGE PASSWORD form values

/**
Expand Down Expand Up @@ -350,17 +361,22 @@ class AuthenticationController {
if (this.pwdVal === '') {
errors.push(gettextCatalog.getString('The password is required.'));
}
if (this.twoFactorAuth && !this.otpVal) {
errors.push(gettextCatalog.getString('The authentication code is required.'));
}
if (errors.length) {
this.setError_(errors);
} else {
this.gmfAuthenticationService_.login(this.loginVal, this.pwdVal)
this.gmfAuthenticationService_.login(this.loginVal, this.pwdVal, this.otpVal)
.then(() => {
this.loginVal = '';
this.pwdVal = '';
this.otpVal = '';
this.resetError_();
})
.catch(() => {
this.pwdVal = '';
this.otpVal = '';
this.setError_(gettextCatalog.getString('Incorrect credentials or disabled account.'));
});
}
Expand Down

0 comments on commit 5b47de5

Please sign in to comment.