diff --git a/app/app/components/auth-settings.js b/app/app/components/auth-settings.js
index 2f815dd4..d2c8b66a 100644
--- a/app/app/components/auth-settings.js
+++ b/app/app/components/auth-settings.js
@@ -25,11 +25,15 @@ export default Ember.Component.extend({
KeycloakRealmError: computed.empty('keycloakConfig.realm'),
KeycloakClientIdError: computed.empty('keycloakConfig.clientId'),
KeycloakPublicKeyError: computed.empty('keycloakConfig.publicKey'),
+ KeycloakAdminUserError: computed.empty('keycloakConfig.adminUser'),
+ KeycloakAdminPasswordError: computed.empty('keycloakConfig.adminPassword'),
keycloakConfig: {
url: '',
realm: '',
clientId: '',
publicKey: '',
+ adminUser: '',
+ adminPassword: ''
},
didReceiveAttrs() {
@@ -89,16 +93,14 @@ export default Ember.Component.extend({
this.$("#keycloak-publicKey").focus();
return;
}
-
- // let pk = this.get('keycloakConfig.publicKey');
- // if (is.not.startWith(pk, '-----BEGIN PUBLIC KEY-----')) {
- // pk = '-----BEGIN PUBLIC KEY-----' + pk;
- // }
- // if (is.not.endWith(pk, '-----END PUBLIC KEY-----')) {
- // pk = pk + '-----END PUBLIC KEY-----' ;
- // }
-
- // this.set('keycloakConfig.publicKey', pk);
+ if (this.get('KeycloakAdminUserError')) {
+ this.$("#keycloak-admin-user").focus();
+ return;
+ }
+ if (this.get('KeycloakAdminPasswordError')) {
+ this.$("#keycloak-admin-password").focus();
+ return;
+ }
config = Ember.copy(this.get('keycloakConfig'));
Ember.set(config, 'publicKey', encoding.Base64.encode(this.get('keycloakConfig.publicKey')));
diff --git a/app/app/pods/auth/keycloak/route.js b/app/app/pods/auth/keycloak/route.js
index f1445dd1..05c3f995 100644
--- a/app/app/pods/auth/keycloak/route.js
+++ b/app/app/pods/auth/keycloak/route.js
@@ -15,7 +15,8 @@ import constants from '../../../utils/constants';
export default Ember.Route.extend({
session: Ember.inject.service(),
appMeta: Ember.inject.service(),
- kcAuth: Ember.inject.service(),
+ kcAuth: Ember.inject.service(),
+ localStorage: Ember.inject.service(),
queryParams: {
mode: {
refreshModel: false
@@ -33,11 +34,16 @@ export default Ember.Route.extend({
return;
}
+ if (this.get('mode') === 'reject') {
+ return;
+ }
+
this.get('kcAuth').boot(JSON.parse(authConfig)).then((kc) => {
if (!kc.authenticated) {
this.get('kcAuth').login().then(() => {
}, (reject) => {
- console.log(reject);
+ this.get('localStorage').storeSessionItem('kc-error', reject);
+ this.transitionTo('auth.keycloak', { queryParams: { mode: 'reject' }});
});
}
@@ -47,16 +53,23 @@ export default Ember.Route.extend({
this.get('audit').record("logged-in-keycloak");
this.transitionTo('folders');
}, (reject) => {
- debugger;
- console.log(">>>>> Documize Keycloak authentication failure");
- this.transitionTo('auth.login');
+ this.get('localStorage').storeSessionItem('kc-error', reject);
+ this.transitionTo('auth.keycloak', { queryParams: { mode: 'reject' }});
});
- }, (err) => {
- console.log(err);
+ }, (reject) => {
+ this.get('localStorage').storeSessionItem('kc-error', reject);
+ this.transitionTo('auth.keycloak', { queryParams: { mode: 'reject' }});
});
- }, (reason) => {
- console.log(reason);
+ }, (reject) => {
+ this.get('localStorage').storeSessionItem('kc-error', reject);
+ this.transitionTo('auth.keycloak', { queryParams: { mode: 'reject' }});
});
},
+
+ model() {
+ return {
+ mode: this.get('mode')
+ }
+ }
});
diff --git a/app/app/pods/auth/keycloak/template.hbs b/app/app/pods/auth/keycloak/template.hbs
index 9f545853..c62a27ca 100644
--- a/app/app/pods/auth/keycloak/template.hbs
+++ b/app/app/pods/auth/keycloak/template.hbs
@@ -1,4 +1,12 @@
-
-
Authenticating with Keycloak...
-

-
+{{#if (is-equal model.mode 'login')}}
+
+
Authenticating with Keycloak...
+

+
+{{/if}}
+
+{{#if (is-equal model.mode 'reject')}}
+
+
Keycloak Authentication Failure
+
+{{/if}}
diff --git a/app/app/pods/auth/login/route.js b/app/app/pods/auth/login/route.js
index 53a14bcc..73a165e8 100644
--- a/app/app/pods/auth/login/route.js
+++ b/app/app/pods/auth/login/route.js
@@ -15,6 +15,7 @@ import constants from '../../../utils/constants';
export default Ember.Route.extend({
appMeta: Ember.inject.service(),
kcAuth: Ember.inject.service(),
+ localStorage: Ember.inject.service(),
showLogin: false,
beforeModel(/*transition*/) {
@@ -28,13 +29,16 @@ export default Ember.Route.extend({
this.get('kcAuth').boot(JSON.parse(authConfig)).then(() => {
this.get('kcAuth').login().then(() => {
}, (reject) => {
- console.log(reject);
+ this.get('localStorage').storeSessionItem('kc-error', reject);
+ this.transitionTo('auth.keycloak', { queryParams: { mode: 'reject' }});
});
}, (reject) => {
- console.log(reject);
+ this.get('localStorage').storeSessionItem('kc-error', reject);
+ this.transitionTo('auth.keycloak', { queryParams: { mode: 'reject' }});
});
break;
+
default:
this.set('showLogin', true);
break;
diff --git a/app/app/templates/components/auth-settings.hbs b/app/app/templates/components/auth-settings.hbs
index 6c46eb4c..dfca4b7c 100644
--- a/app/app/templates/components/auth-settings.hbs
+++ b/app/app/templates/components/auth-settings.hbs
@@ -13,7 +13,7 @@
{{#if isKeycloakProvider}}
+
+
{{/if}}
save
diff --git a/core/api/endpoint/keycloak.go b/core/api/endpoint/keycloak.go
index b8d26602..bfdbc359 100644
--- a/core/api/endpoint/keycloak.go
+++ b/core/api/endpoint/keycloak.go
@@ -17,14 +17,18 @@ import (
"fmt"
"io/ioutil"
"net/http"
+ "net/url"
"strings"
+ "bytes"
+ "errors"
"github.com/documize/community/core/api/endpoint/models"
"github.com/documize/community/core/api/entity"
"github.com/documize/community/core/api/request"
"github.com/documize/community/core/api/util"
"github.com/documize/community/core/log"
"github.com/documize/community/core/utility"
+ "strconv"
)
// AuthenticateKeycloak checks Keycloak authentication credentials.
@@ -158,6 +162,11 @@ func AuthenticateKeycloak(w http.ResponseWriter, r *http.Request) {
return
}
+ err = SyncUsers(ac)
+ if err != nil {
+ log.Error("su", err)
+ }
+
writeSuccessBytes(w, json)
}
@@ -240,6 +249,79 @@ func addUser(p request.Persister, a keycloakAuthRequest) (u entity.User, err err
return p.GetUser(userID)
}
+// SyncUsers gets list of Keycloak users for specified Realm, Client Id
+func SyncUsers(c keycloakConfig) (err error) {
+ form := url.Values{}
+ form.Add("username", c.AdminUser)
+ form.Add("password", c.AdminPassword)
+ form.Add("client_id", "admin-cli")
+ form.Add("grant_type", "password")
+
+ req, err := http.NewRequest("POST",
+ fmt.Sprintf("%s/realms/master/protocol/openid-connect/token", c.URL),
+ bytes.NewBufferString(form.Encode()))
+
+ req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
+ req.Header.Add("Content-Length", strconv.Itoa(len(form.Encode())))
+
+ client := &http.Client{}
+ res, err := client.Do(req)
+ if err != nil {
+ return err
+ }
+
+ defer res.Body.Close()
+ body, err := ioutil.ReadAll(res.Body)
+ if err != nil {
+ return err
+ }
+
+ ka := keycloakAPIAuth{}
+ err = json.Unmarshal(body, &ka)
+ if err != nil {
+ return err
+ }
+
+ if res.StatusCode != http.StatusOK {
+ return errors.New("Keycloak authentication failed " + res.Status)
+ }
+
+ req, err = http.NewRequest("GET",
+ fmt.Sprintf("%s/admin/realms/%s/users?max=500", c.URL, c.Realm),
+ nil)
+
+ req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", ka.AccessToken))
+
+ client = &http.Client{}
+ res, err = client.Do(req)
+ if err != nil {
+ return err
+ }
+
+ defer res.Body.Close()
+ body, err = ioutil.ReadAll(res.Body)
+ if err != nil {
+ return err
+ }
+
+ u := []keycloakUser{}
+ err = json.Unmarshal(body, &u)
+ if err != nil {
+ return err
+ }
+
+ if res.StatusCode != http.StatusOK {
+ return errors.New("Keycloak /users call failed " + res.Status)
+ }
+
+ log.Info(fmt.Sprintf("%d", res.StatusCode))
+
+ fmt.Println(fmt.Sprintf("%d len", len(u)))
+ fmt.Println(u[0].Email)
+
+ return nil
+}
+
// Data received via Keycloak client library
type keycloakAuthRequest struct {
Domain string `json:"domain"`
@@ -254,8 +336,25 @@ type keycloakAuthRequest struct {
// Keycloak server configuration
type keycloakConfig struct {
- URL string `json:"url"`
- Realm string `json:"realm"`
- ClientID string `json:"clientId"`
- PublicKey string `json:"publicKey"`
+ URL string `json:"url"`
+ Realm string `json:"realm"`
+ ClientID string `json:"clientId"`
+ PublicKey string `json:"publicKey"`
+ AdminUser string `json:"adminUser"`
+ AdminPassword string `json:"adminPassword"`
+}
+
+// keycloakAPIAuth is returned when authenticating with Keycloak REST API.
+type keycloakAPIAuth struct {
+ AccessToken string `json:"access_token"`
+}
+
+// keycloakUser details user record returned by Keycloak
+type keycloakUser struct {
+ ID string `json:"id"`
+ Username string `json:"username"`
+ Email string `json:"email"`
+ Firstname string `json:"firstName"`
+ Lastname string `json:"lastName"`
+ Enabled bool `json:"enabled"`
}