From 30321781c208b47af2a2ab48182afb88e405a86e Mon Sep 17 00:00:00 2001 From: Harvey Kandola Date: Wed, 4 Oct 2017 12:27:56 -0400 Subject: [PATCH] implemented view users permission --- domain/auth/endpoint.go | 2 +- gui/app/pods/customize/folders/template.hbs | 90 ++--- gui/app/pods/customize/users/template.hbs | 2 - gui/app/pods/folder/settings/route.js | 2 +- gui/app/services/ajax.js | 2 +- gui/app/services/session.js | 15 +- gui/app/styles/view/page-customize.scss | 13 +- .../components/customize/auth-settings.hbs | 144 ++++---- .../components/customize/general-settings.hbs | 62 ++-- .../components/customize/global-settings.hbs | 97 ++--- .../components/customize/user-admin.hbs | 332 +++++++++--------- .../components/customize/user-settings.hbs | 42 ++- server/middleware.go | 8 +- 13 files changed, 423 insertions(+), 388 deletions(-) diff --git a/domain/auth/endpoint.go b/domain/auth/endpoint.go index 99e91d51..d91e84f0 100644 --- a/domain/auth/endpoint.go +++ b/domain/auth/endpoint.go @@ -110,7 +110,7 @@ func (h *Handler) Login(w http.ResponseWriter, r *http.Request) { return } - h.Runtime.Log.Info("login " + email + " @ " + dom) + h.Runtime.Log.Info("logged in " + email + " @ " + dom) authModel := auth.AuthenticationModel{} authModel.Token = GenerateJWT(h.Runtime, u.RefID, org.RefID, dom) diff --git a/gui/app/pods/customize/folders/template.hbs b/gui/app/pods/customize/folders/template.hbs index 4814219b..dfa26f76 100644 --- a/gui/app/pods/customize/folders/template.hbs +++ b/gui/app/pods/customize/folders/template.hbs @@ -1,51 +1,51 @@ -{{#if folders}} +
+
-
-
-
{{folders.length}} shared {{label}}
-
View and change shared space ownership
-
-
- {{#each folders as |folder|}} -
- {{#link-to 'folder' folder.id folder.slug class="alt"}}{{folder.name}}{{/link-to}} -
-
-
- delete + {{#if folders}} +
+
{{folders.length}} shared {{label}}
+
View and change shared space ownership
+
+
+ {{#each folders as |folder|}} +
+ {{#link-to 'folder' folder.id folder.slug class="alt"}}{{folder.name}}{{/link-to}} +
+
+
+ delete +
+
+
+ {{/each}} +
+ + - - diff --git a/gui/app/pods/customize/users/template.hbs b/gui/app/pods/customize/users/template.hbs index 4ae3ca9d..398170d1 100644 --- a/gui/app/pods/customize/users/template.hbs +++ b/gui/app/pods/customize/users/template.hbs @@ -1,5 +1,3 @@ {{customize/user-settings add=(action 'add')}} -
- {{customize/user-admin users=model onDelete=(action "onDelete") onSave=(action "onSave") onPassword=(action "onPassword")}} diff --git a/gui/app/pods/folder/settings/route.js b/gui/app/pods/folder/settings/route.js index e7595d5e..b065f731 100644 --- a/gui/app/pods/folder/settings/route.js +++ b/gui/app/pods/folder/settings/route.js @@ -15,7 +15,7 @@ import AuthenticatedRouteMixin from 'ember-simple-auth/mixins/authenticated-rout export default Ember.Route.extend(AuthenticatedRouteMixin, { beforeModel: function (transition) { if (is.equal(transition.targetName, 'folder.settings.index')) { - this.transitionTo('folder.settings.invitation'); + this.transitionTo('folder.settings.security'); } }, diff --git a/gui/app/services/ajax.js b/gui/app/services/ajax.js index 43d4c34c..fc41022e 100644 --- a/gui/app/services/ajax.js +++ b/gui/app/services/ajax.js @@ -42,7 +42,7 @@ export default AjaxService.extend({ if (is.not.empty(userUpdate)) { let latest = JSON.parse(userUpdate); - if (!latest.active || user.editor !== latest.editor || user.admin !== latest.admin) { + if (!latest.active || user.editor !== latest.editor || user.admin !== latest.admin || user.viewUsers !== latest.viewUsers) { window.location.href = 'auth/login'; } } diff --git a/gui/app/services/session.js b/gui/app/services/session.js index 787adc67..90c388c5 100644 --- a/gui/app/services/session.js +++ b/gui/app/services/session.js @@ -26,12 +26,15 @@ export default SimpleAuthSession.extend({ currentFolder: null, isMac: false, isMobile: false, + hasAccounts: computed('isAuthenticated', 'session.content.authenticated.user', function() { return this.get('session.authenticator') !== 'authenticator:anonymous' && this.get('session.content.authenticated.user.accounts').length > 0; }), + accounts: computed('hasAccounts', function() { return this.get('session.content.authenticated.user.accounts'); }), + user: computed('isAuthenticated', 'session.content.authenticated.user', function () { if (this.get('isAuthenticated')) { let user = this.get('session.content.authenticated.user') || { id: '0' }; @@ -39,28 +42,32 @@ export default SimpleAuthSession.extend({ return this.get('store').push(data); } }), + authenticated: computed('session.content.authenticated.user', function () { return this.get('session.authenticator') !== 'authenticator:anonymous' && this.get('session.content.authenticated.user.id') !== '0'; }), + isAdmin: computed('session.content.authenticated.user', function () { - return this.get('session.authenticator') !== 'authenticator:anonymous' && + return this.get('session.authenticator') !== 'authenticator:anonymous' && this.get('session.content.authenticated.user.id') !== '0' && this.get('session.content.authenticated.user.admin') === true; }), + isEditor: computed('session.content.authenticated.user', function () { - return this.get('session.authenticator') !== 'authenticator:anonymous' && + return this.get('session.authenticator') !== 'authenticator:anonymous' && this.get('session.content.authenticated.user.id') !== '0' && this.get('session.content.authenticated.user.editor') === true; }), + isGlobalAdmin: computed('session.content.authenticated.user', function () { - return this.get('session.authenticator') !== 'authenticator:anonymous' && + return this.get('session.authenticator') !== 'authenticator:anonymous' && this.get('session.content.authenticated.user.id') !== '0' && this.get('session.content.authenticated.user.global') === true; }), init() { this._super(...arguments); - + this.set('isMac', is.mac()); this.set('isMobile', is.mobile()); }, diff --git a/gui/app/styles/view/page-customize.scss b/gui/app/styles/view/page-customize.scss index 930bfc38..9c3b3793 100644 --- a/gui/app/styles/view/page-customize.scss +++ b/gui/app/styles/view/page-customize.scss @@ -1,7 +1,16 @@ .page-customize { - @include content-container(); - .user-admin { + > .auth-admin, > .general-admin, > .license-admin, > .smtp-admin, > .space-admin { + @include content-container(); + } + + > .add-user { + @include content-container(); + margin-bottom: 50px; + } + + > .user-admin { + @include content-container(); margin: 30px 0; > .heading { diff --git a/gui/app/templates/components/customize/auth-settings.hbs b/gui/app/templates/components/customize/auth-settings.hbs index c957f87a..6008a359 100644 --- a/gui/app/templates/components/customize/auth-settings.hbs +++ b/gui/app/templates/components/customize/auth-settings.hbs @@ -1,72 +1,76 @@ -
-
-
Authentication
-
Determine the method for user authentication
-
-
- -
External authentication servers, services must be accessible from the server running this Documize instance
- {{#ui/ui-radio selected=isDocumizeProvider onClick=(action 'onDocumize')}}Documize — email/password{{/ui/ui-radio}} - {{#ui/ui-radio selected=isKeycloakProvider onClick=(action 'onKeycloak')}}Keycloak — bring your own authentication server{{/ui/ui-radio}} -
+
+
+ +
+
Authentication
+
Determine the method for user authentication
+
+
+ +
External authentication servers, services must be accessible from the server running this Documize instance
+ {{#ui/ui-radio selected=isDocumizeProvider onClick=(action 'onDocumize')}}Documize — email/password{{/ui/ui-radio}} + {{#ui/ui-radio selected=isKeycloakProvider onClick=(action 'onKeycloak')}}Keycloak — bring your own authentication server{{/ui/ui-radio}} +
- {{#if isKeycloakProvider}} -
-
Keycloak Configuration
-
Connection parameters — create a documize user in Master realm with 'manage-users' role against target realm
-
-
- -
e.g. http://localhost:8888/auth
- {{focus-input id="keycloak-url" type="text" value=keycloakConfig.url class=(if KeycloakUrlError 'error')}} -
-
- -
e.g. main
- {{input id="keycloak-realm" type="text" value=keycloakConfig.realm class=(if keycloakRealmError 'error')}} -
-
- -
Copy the RSA Public Key from Realm Settings → Keys
- {{textarea id="keycloak-publicKey" type="text" value=keycloakConfig.publicKey rows=7 class=(if KeycloakPublicKeyError 'error')}} -
-
- -
e.g. account
- {{input id="keycloak-clientId" type="text" value=keycloakConfig.clientId class=(if KeycloakClientIdError 'error')}} -
-
- -
If you want to sync users in a particular Group (e.g. 'Documize Users'), provide the Group ID (e.g. 511d8b61-1ec8-45f6-bc8d-5de64d54c9d2)
- {{input id="keycloak-group" type="text" value=keycloakConfig.group}} -
-
- -
Used to connect with Keycloak and sync users with Documize (create user under Master Realm and assign 'view-users' role against Realm specified above)
- {{input id="keycloak-admin-user" type="text" value=keycloakConfig.adminUser class=(if KeycloakAdminUserError 'error')}} -
-
- -
Used to connect with Keycloak and sync users with Documize
- {{input id="keycloak-admin-password" type="password" value=keycloakConfig.adminPassword class=(if KeycloakAdminPasswordError 'error')}} -
-
- -
Hide the logout button for Keycloak users
-
- {{input type="checkbox" checked=keycloakConfig.disableLogout}} - -
-
-
- -
Determine if Keycloak sync'ed users permission to add new spaces
-
- {{input type="checkbox" checked=keycloakConfig.defaultPermissionAddSpace}} - -
-
- {{/if}} + {{#if isKeycloakProvider}} +
+
Keycloak Configuration
+
Connection parameters — create a documize user in Master realm with 'manage-users' role against target realm
+
+
+ +
e.g. http://localhost:8888/auth
+ {{focus-input id="keycloak-url" type="text" value=keycloakConfig.url class=(if KeycloakUrlError 'error')}} +
+
+ +
e.g. main
+ {{input id="keycloak-realm" type="text" value=keycloakConfig.realm class=(if keycloakRealmError 'error')}} +
+
+ +
Copy the RSA Public Key from Realm Settings → Keys
+ {{textarea id="keycloak-publicKey" type="text" value=keycloakConfig.publicKey rows=7 class=(if KeycloakPublicKeyError 'error')}} +
+
+ +
e.g. account
+ {{input id="keycloak-clientId" type="text" value=keycloakConfig.clientId class=(if KeycloakClientIdError 'error')}} +
+
+ +
If you want to sync users in a particular Group (e.g. 'Documize Users'), provide the Group ID (e.g. 511d8b61-1ec8-45f6-bc8d-5de64d54c9d2)
+ {{input id="keycloak-group" type="text" value=keycloakConfig.group}} +
+
+ +
Used to connect with Keycloak and sync users with Documize (create user under Master Realm and assign 'view-users' role against Realm specified above)
+ {{input id="keycloak-admin-user" type="text" value=keycloakConfig.adminUser class=(if KeycloakAdminUserError 'error')}} +
+
+ +
Used to connect with Keycloak and sync users with Documize
+ {{input id="keycloak-admin-password" type="password" value=keycloakConfig.adminPassword class=(if KeycloakAdminPasswordError 'error')}} +
+
+ +
Hide the logout button for Keycloak users
+
+ {{input type="checkbox" checked=keycloakConfig.disableLogout}} + +
+
+
+ +
Determine if Keycloak sync'ed users permission to add new spaces
+
+ {{input type="checkbox" checked=keycloakConfig.defaultPermissionAddSpace}} + +
+
+ {{/if}} -
save
- +
save
+ +
+
\ No newline at end of file diff --git a/gui/app/templates/components/customize/general-settings.hbs b/gui/app/templates/components/customize/general-settings.hbs index cb2bed23..5efc774c 100644 --- a/gui/app/templates/components/customize/general-settings.hbs +++ b/gui/app/templates/components/customize/general-settings.hbs @@ -1,30 +1,34 @@ -
-
-
Instance Settings
-
Settings applicable to your Documize instance
-
-
- -
Describe the title of this Documize instance
- {{focus-input id="siteTitle" type="text" value=model.general.title class=(if hasTitleInputError 'error')}} -
-
- -
Describe the purpose of this Documize instance
- {{textarea id="siteMessage" rows="3" value=model.general.message class=(if hasMessageInputError 'error')}} -
-
- -
Content within "Everyone" will be made available to anonymous users
-
- - -
-
-
- -
Endpoint for handling import/export (e.g. https://api.documize.com, view documentation)
- {{focus-input id="conversionEndpoint" type="text" value=model.general.conversionEndpoint class=(if hasConversionEndpointInputError 'error')}} +
+
+ +
+
Instance Settings
+
Settings applicable to your Documize instance
+
+
+ +
Describe the title of this Documize instance
+ {{focus-input id="siteTitle" type="text" value=model.general.title class=(if hasTitleInputError 'error')}} +
+
+ +
Describe the purpose of this Documize instance
+ {{textarea id="siteMessage" rows="3" value=model.general.message class=(if hasMessageInputError 'error')}} +
+
+ +
Content within "Everyone" will be made available to anonymous users
+
+ + +
+
+
+ +
Endpoint for handling import/export (e.g. https://api.documize.com, view documentation)
+ {{focus-input id="conversionEndpoint" type="text" value=model.general.conversionEndpoint class=(if hasConversionEndpointInputError 'error')}} +
+
save
+
-
save
- +
\ No newline at end of file diff --git a/gui/app/templates/components/customize/global-settings.hbs b/gui/app/templates/components/customize/global-settings.hbs index 439c9e02..3e4d0547 100644 --- a/gui/app/templates/components/customize/global-settings.hbs +++ b/gui/app/templates/components/customize/global-settings.hbs @@ -1,48 +1,53 @@ -
-
-
Mail Server Settings
-
Used for sending email notifications
-
-
- -
e.g. my.host.com
- {{focus-input id="smtp-host" type="text" value=model.smtp.host class=(if SMTPHostEmptyError 'error')}} -
-
- -
e.g. 587
- {{input id="smtp-port" type="text" value=model.smtp.port class=(if SMTPPortEmptyError 'error')}} -
-
- -
e.g. noreply@documize.com
- {{input id="smtp-sender" type="text" value=model.smtp.sender class=(if SMTPSenderEmptyError 'error')}} -
-
- -
Your credentials
- {{input id="smtp-userid" type="text" value=model.smtp.userid class=(if SMTPUserIdEmptyError 'error')}} -
-
- -
Your credentials
- {{input id="smtp-password" type="text" value=model.smtp.password class=(if SMTPPasswordEmptyError 'error')}} -
-
save
-
+
+
+
+
+
Mail Server Settings
+
Used for sending email notifications
+
+
+ +
e.g. my.host.com
+ {{focus-input id="smtp-host" type="text" value=model.smtp.host class=(if SMTPHostEmptyError 'error')}} +
+
+ +
e.g. 587
+ {{input id="smtp-port" type="text" value=model.smtp.port class=(if SMTPPortEmptyError 'error')}} +
+
+ +
e.g. noreply@documize.com
+ {{input id="smtp-sender" type="text" value=model.smtp.sender class=(if SMTPSenderEmptyError 'error')}} +
+
+ +
Your credentials
+ {{input id="smtp-userid" type="text" value=model.smtp.userid class=(if SMTPUserIdEmptyError 'error')}} +
+
+ +
Your credentials
+ {{input id="smtp-password" type="text" value=model.smtp.password class=(if SMTPPasswordEmptyError 'error')}} +
+
save
+
+
-
+
+ +
+
+
+
Optional Edition License
+
Only applies to Enterprise Edition
+
+
+ +
XML format accepted
+ {{textarea value=model.license rows="15"}} +
+
save
+
+
- -
-
-
Optional Edition License
-
Only applies to Enterprise Edition
-
-
- -
XML format accepted
- {{textarea value=model.license rows="15"}} -
-
save
-
diff --git a/gui/app/templates/components/customize/user-admin.hbs b/gui/app/templates/components/customize/user-admin.hbs index 6c81906c..a1c78b1f 100644 --- a/gui/app/templates/components/customize/user-admin.hbs +++ b/gui/app/templates/components/customize/user-admin.hbs @@ -1,169 +1,171 @@ -
-
-
User Management
-
Set basic information, passwords and permissions for {{users.length}} users
+
+
+
+
User Management
+
Set basic information, passwords and permissions for {{users.length}} users
+
+ + + + + + + + + + + + + + {{#each users key="id" as |user|}} + + + + + + + + + {{/each}} + +
+
+ {{focus-input type="text" placeholder="< type here to filter users >" value=filter}} +
+
Add SpaceView UsersAdminActive + {{#if hasSelectedUsers}} +
+ delete +
+ {{#dropdown-dialog target="bulk-delete-users" position="bottom right" button="Delete" color="flat-red" onAction=(action 'onBulkDelete')}} +

Are you sure you want to delete selected users?

+ {{/dropdown-dialog}} + {{/if}} +
+
+ {{#if user.me}} + check_box_outline_blank + {{else if user.selected}} + check_box + {{else}} + check_box_outline_blank + {{/if}} +
+
{{ user.fullname }}
+ +
+ {{#if user.editor}} + check_box + {{else}} + check_box_outline_blank + {{/if}} + + {{#if user.viewUsers}} + check_box + {{else}} + check_box_outline_blank + {{/if}} + + {{#if user.me}} + check_box + {{else if user.admin}} + check_box + {{else}} + check_box_outline_blank + {{/if}} + + {{#if user.me}} + check_box + {{else if user.active}} + check_box + {{else}} + check_box_outline_blank + {{/if}} + + {{#if user.me}} +
+ edit +
+ {{else}} +
+ edit +
+
+
+ delete +
+ {{/if}} +
- - - - - - - - - - - - - {{#each users as |user|}} - - - - - - - - - {{/each}} - -
-
- {{focus-input type="text" placeholder="< type here to filter users >" value=filter}} -
-
Add SpaceView UsersAdminActive - {{#if hasSelectedUsers}} -
- delete -
- {{#dropdown-dialog target="bulk-delete-users" position="bottom right" button="Delete" color="flat-red" onAction=(action 'onBulkDelete')}} -

Are you sure you want to delete selected users?

- {{/dropdown-dialog}} - {{/if}} -
-
- {{#if user.selected}} - check_box - {{else if user.me}} - check_box_outline_blank - {{else}} - check_box_outline_blank - {{/if}} -
-
{{ user.fullname }}
- -
- {{#if user.editor}} - check_box - {{else}} - check_box_outline_blank - {{/if}} - - {{#if user.viewUsers}} - check_box - {{else}} - check_box_outline_blank - {{/if}} - - {{#if user.me}} - check_box - {{else if user.admin}} - check_box - {{else}} - check_box_outline_blank - {{/if}} - - {{#if user.me}} - check_box - {{else if user.active}} - check_box - {{else}} - check_box_outline_blank - {{/if}} - - {{#if user.me}} -
- edit -
- {{else}} -
- edit -
-
-
- delete -
- {{/if}} -
-
+ - - - diff --git a/gui/app/templates/components/customize/user-settings.hbs b/gui/app/templates/components/customize/user-settings.hbs index 51ab5471..f256f3d4 100644 --- a/gui/app/templates/components/customize/user-settings.hbs +++ b/gui/app/templates/components/customize/user-settings.hbs @@ -1,21 +1,25 @@ {{#if isAuthProviderDocumize}} -
-
-
Add user
-
New users receive an invitation email with a random password
-
-
- - {{focus-input id="newUserFirstname" type="text" value=newUser.firstname class=(if hasFirstnameEmptyError 'error')}} -
-
- - {{input id="newUserLastname" type="text" value=newUser.lastname class=(if hasLastnameEmptyError 'error')}} -
-
- - {{input id="newUserEmail" type="text" value=newUser.email class=(if hasEmailEmptyError 'error')}} -
-
Add
-
+
+
+
+
+
New User
+
Newly added users receive an invitation email with a random password
+
+
+ + {{focus-input id="newUserFirstname" type="text" value=newUser.firstname class=(if hasFirstnameEmptyError 'error')}} +
+
+ + {{input id="newUserLastname" type="text" value=newUser.lastname class=(if hasLastnameEmptyError 'error')}} +
+
+ + {{input id="newUserEmail" type="text" value=newUser.email class=(if hasEmailEmptyError 'error')}} +
+
Add
+
+
+
{{/if}} \ No newline at end of file diff --git a/server/middleware.go b/server/middleware.go index e83277a4..121489a9 100644 --- a/server/middleware.go +++ b/server/middleware.go @@ -166,14 +166,16 @@ func (m *middleware) Authorize(w http.ResponseWriter, r *http.Request, next http // user state. This helps client-side applications to detect changes in // user state/privileges. var state struct { - Active bool `json:"active"` - Admin bool `json:"admin"` - Editor bool `json:"editor"` + Active bool `json:"active"` + Admin bool `json:"admin"` + Editor bool `json:"editor"` + ViewUsers bool `json:"viewUsers"` } state.Active = u.Active state.Admin = u.Admin state.Editor = u.Editor + state.ViewUsers = u.ViewUsers sb, err := json.Marshal(state) w.Header().Add("X-Documize-Status", string(sb))