From 0f9d673eb52fddbe4523058eb8b92c1e8b89a43a Mon Sep 17 00:00:00 2001 From: Harvey Kandola Date: Mon, 20 Mar 2017 13:54:53 +0000 Subject: [PATCH] keycloak logout and auth provider switching --- README.md | 3 +- app/app/authenticators/documize.js | 2 ++ app/app/authenticators/keycloak.js | 5 ++- app/app/components/auth-settings.js | 2 +- app/app/pods/auth/keycloak/route.js | 16 ++++----- app/app/pods/auth/login/route.js | 3 +- app/app/pods/auth/logout/route.js | 19 ++++++----- app/app/pods/auth/logout/template.hbs | 5 ++- app/app/pods/customize/auth/controller.js | 12 +++++-- app/app/services/kc-auth.js | 41 ++++++++++++++++++----- app/app/services/session.js | 9 +++-- core/api/endpoint/keycloak.go | 6 ---- 12 files changed, 78 insertions(+), 45 deletions(-) diff --git a/README.md b/README.md index 0aa7e11a..3de2787c 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ v0.44.0 ## Tech stack -- EmberJS (v2.11.2) +- EmberJS (v2.12.0) - Go (v1.8) - MySQL (v5.7.10+) or Percona (v5.7.16-10+) @@ -38,7 +38,6 @@ Documize is compatible with Auth0 identity as a service. [![JWT Auth for open source projects](https://cdn.auth0.com/oss/badges/a0-badge-dark.png)](https://auth0.com/?utm_source=oss&utm_medium=gp&utm_campaign=oss) - Open Source Identity and Access Management ## Word Conversion to HTML diff --git a/app/app/authenticators/documize.js b/app/app/authenticators/documize.js index 153d6a6b..24714b3b 100644 --- a/app/app/authenticators/documize.js +++ b/app/app/authenticators/documize.js @@ -23,6 +23,7 @@ const { export default Base.extend({ ajax: service(), appMeta: service(), + localStorage: service(), restore(data) { // TODO: verify authentication data @@ -57,6 +58,7 @@ export default Base.extend({ }, invalidate() { + this.get('localStorage').clearAll(); return resolve(); } }); \ No newline at end of file diff --git a/app/app/authenticators/keycloak.js b/app/app/authenticators/keycloak.js index cbf2f00d..0a26ac7a 100644 --- a/app/app/authenticators/keycloak.js +++ b/app/app/authenticators/keycloak.js @@ -22,6 +22,8 @@ const { export default Base.extend({ ajax: service(), appMeta: service(), + kcAuth: service(), + localStorage: service(), restore(data) { // TODO: verify authentication data @@ -46,6 +48,7 @@ export default Base.extend({ }, invalidate() { - return resolve(); + this.get('localStorage').clearAll(); + return this.get('kcAuth').logout(); } }); \ No newline at end of file diff --git a/app/app/components/auth-settings.js b/app/app/components/auth-settings.js index 3703cf5c..62a5d176 100644 --- a/app/app/components/auth-settings.js +++ b/app/app/components/auth-settings.js @@ -18,9 +18,9 @@ const { } = Ember; export default Ember.Component.extend({ + appMeta: Ember.inject.service(), isDocumizeProvider: computed.equal('authProvider', constants.AuthProvider.Documize), isKeycloakProvider: computed.equal('authProvider', constants.AuthProvider.Keycloak), - KeycloakUrlError: computed.empty('keycloakConfig.url'), KeycloakRealmError: computed.empty('keycloakConfig.realm'), KeycloakClientIdError: computed.empty('keycloakConfig.clientId'), diff --git a/app/app/pods/auth/keycloak/route.js b/app/app/pods/auth/keycloak/route.js index 0a6fe961..baab93d0 100644 --- a/app/app/pods/auth/keycloak/route.js +++ b/app/app/pods/auth/keycloak/route.js @@ -25,11 +25,7 @@ export default Ember.Route.extend({ beforeModel(transition) { this.set('mode', is.not.undefined(transition.queryParams.mode) ? transition.queryParams.mode : 'login'); - - let authProvider = this.get('appMeta.authProvider'); - let authConfig = this.get('appMeta.authConfig'); - - if (authProvider !== constants.AuthProvider.Keycloak) { + if (this.get('appMeta.authProvider') !== constants.AuthProvider.Keycloak) { return; } @@ -37,12 +33,12 @@ export default Ember.Route.extend({ return; } - this.get('kcAuth').boot(JSON.parse(authConfig)).then((kc) => { + this.get('kcAuth').boot().then((kc) => { if (!kc.authenticated) { this.get('kcAuth').login().then(() => { }, (reject) => { this.get('localStorage').storeSessionItem('kc-error', reject); - this.transitionTo('auth.keycloak', { queryParams: { mode: 'reject' }}); + this.set('mode', 'reject'); }); } @@ -53,16 +49,16 @@ export default Ember.Route.extend({ this.transitionTo('folders'); }, (reject) => { this.get('localStorage').storeSessionItem('kc-error', reject); - this.transitionTo('auth.keycloak', { queryParams: { mode: 'reject' }}); + this.set('mode', 'reject'); }); }, (reject) => { this.get('localStorage').storeSessionItem('kc-error', reject); - this.transitionTo('auth.keycloak', { queryParams: { mode: 'reject' }}); + this.set('mode', 'reject'); }); }, (reject) => { this.get('localStorage').storeSessionItem('kc-error', reject); - this.transitionTo('auth.keycloak', { queryParams: { mode: 'reject' }}); + this.set('mode', 'reject'); }); }, diff --git a/app/app/pods/auth/login/route.js b/app/app/pods/auth/login/route.js index 73a165e8..8401b4a4 100644 --- a/app/app/pods/auth/login/route.js +++ b/app/app/pods/auth/login/route.js @@ -20,13 +20,12 @@ export default Ember.Route.extend({ beforeModel(/*transition*/) { let authProvider = this.get('appMeta.authProvider'); - let authConfig = this.get('appMeta.authConfig'); switch (authProvider) { case constants.AuthProvider.Keycloak: this.set('showLogin', false); - this.get('kcAuth').boot(JSON.parse(authConfig)).then(() => { + this.get('kcAuth').boot().then(() => { this.get('kcAuth').login().then(() => { }, (reject) => { this.get('localStorage').storeSessionItem('kc-error', reject); diff --git a/app/app/pods/auth/logout/route.js b/app/app/pods/auth/logout/route.js index cf293ecb..88b12d8c 100644 --- a/app/app/pods/auth/logout/route.js +++ b/app/app/pods/auth/logout/route.js @@ -17,18 +17,19 @@ export default Ember.Route.extend({ appMeta: Ember.inject.service(), activate: function () { - this.get('session').invalidate(); - this.audit.record("logged-in"); + this.audit.record("logged-out"); this.audit.stop(); - if (config.environment === 'test') { - this.transitionTo('auth.login'); - } else { - if (this.get("appMeta.allowAnonymousAccess")) { - this.transitionTo('folders'); - } else { + this.get('session').invalidate().then(() => { + if (config.environment === 'test') { this.transitionTo('auth.login'); + } else { + if (this.get("appMeta.allowAnonymousAccess")) { + this.transitionTo('folders'); + } else { + this.transitionTo('auth.login'); + } } - } + }); } }); diff --git a/app/app/pods/auth/logout/template.hbs b/app/app/pods/auth/logout/template.hbs index c24cd689..fc1ac6c2 100644 --- a/app/app/pods/auth/logout/template.hbs +++ b/app/app/pods/auth/logout/template.hbs @@ -1 +1,4 @@ -{{outlet}} +
+

Logging out...

+ +
diff --git a/app/app/pods/customize/auth/controller.js b/app/app/pods/customize/auth/controller.js index 81d7f93d..d703bde0 100644 --- a/app/app/pods/customize/auth/controller.js +++ b/app/app/pods/customize/auth/controller.js @@ -15,6 +15,7 @@ import NotifierMixin from "../../../mixins/notifier"; export default Ember.Controller.extend(NotifierMixin, { global: Ember.inject.service(), appMeta: Ember.inject.service(), + session: Ember.inject.service(), actions: { onSave(provider, config) { @@ -23,8 +24,15 @@ export default Ember.Controller.extend(NotifierMixin, { return this.get('global').saveAuthConfig(data).then(() => { this.showNotification('Saved'); - this.set('appMeta.authProvider', provider); - this.set('appMeta.authConfig', config); + if (provider !== this.get('appMeta.authProvider')) { + this.get('session').logout(); + this.set('appMeta.authProvider', provider); + this.set('appMeta.authConfig', config); + window.location.href= '/'; + } else { + this.set('appMeta.authProvider', provider); + this.set('appMeta.authConfig', config); + } }); } }, diff --git a/app/app/services/kc-auth.js b/app/app/services/kc-auth.js index 259dc97f..07356748 100644 --- a/app/app/services/kc-auth.js +++ b/app/app/services/kc-auth.js @@ -23,11 +23,16 @@ export default Ember.Service.extend({ appMeta: service(), keycloak: null, - boot(options) { - this.set('keycloak', new Keycloak(options)); + init () { + this._super(...arguments); + this.keycloak = null; + }, + + boot() { + this.set('keycloak', new Keycloak(JSON.parse(this.get('appMeta.authConfig')))); return new Ember.RSVP.Promise((resolve, reject) => { - this.keycloak.init().success(() => { + this.get('keycloak').init().success(() => { this.get('audit').record("initialized-keycloak"); resolve(this.get('keycloak')); }).error((err) => { @@ -37,15 +42,35 @@ export default Ember.Service.extend({ }, login() { + this.set('keycloak', new Keycloak(JSON.parse(this.get('appMeta.authConfig')))); let url = netUtil.getAppUrl(netUtil.getSubdomain()) + '/auth/keycloak?mode=login'; return new Ember.RSVP.Promise((resolve, reject) => { - if (this.get('keycloak').authenticated) { - return resolve(this.get('keycloak')); - } + this.boot().then(() => { + this.get('keycloak').login({redirectUri: url}).success(() => { + return resolve(); + }).error(() => { + return reject(new Error('login failed')); + }); + }); + }); + }, - this.get('keycloak').login( {redirectUri: url} ); - return reject(); + logout() { + this.set('keycloak', new Keycloak(JSON.parse(this.get('appMeta.authConfig')))); + + return new Ember.RSVP.Promise((resolve, reject) => { + this.boot().then(() => { + this.get('keycloak').logout(JSON.parse(this.get('appMeta.authConfig'))).success(() => { + this.get('keycloak').clearToken(); + resolve(); + }).error((error) => { + this.get('keycloak').clearToken(); + reject(error); + }); + }, (error) => { + reject(error); + }); }); }, diff --git a/app/app/services/session.js b/app/app/services/session.js index 01c0aac0..7fdad147 100644 --- a/app/app/services/session.js +++ b/app/app/services/session.js @@ -21,7 +21,9 @@ export default SimpleAuthSession.extend({ ajax: service(), appMeta: service(), store: service(), - + localStorage: service(), + folderPermissions: null, + currentFolder: null, isMac: false, isMobile: false, authenticated: computed('user.id', function () { @@ -55,6 +57,7 @@ export default SimpleAuthSession.extend({ } }), - folderPermissions: null, - currentFolder: null + logout() { + this.get('localStorage').clearAll(); + } }); diff --git a/core/api/endpoint/keycloak.go b/core/api/endpoint/keycloak.go index e1e442f2..1e292069 100644 --- a/core/api/endpoint/keycloak.go +++ b/core/api/endpoint/keycloak.go @@ -112,12 +112,6 @@ func AuthenticateKeycloak(w http.ResponseWriter, r *http.Request) { if err == sql.ErrNoRows { log.Info("keycloak add user " + a.Email + " @ " + a.Domain) - p.Context.Transaction, err = request.Db.Beginx() - if err != nil { - writeTransactionError(w, method, err) - return - } - user = entity.User{} user.Firstname = a.Firstname user.Lastname = a.Lastname