1
0
Fork 0
mirror of https://github.com/documize/community.git synced 2025-07-19 21:29:42 +02:00

Set user admin max results and Keycloak sync option

This commit is contained in:
McMatts 2018-08-20 17:17:25 +01:00
parent 2c8b757ff6
commit 351b8dcc12
13 changed files with 100 additions and 31 deletions

View file

@ -94,7 +94,7 @@ func (h *Handler) Sync(w http.ResponseWriter, r *http.Request) {
}
// User list from Documize
dmzUsers, err := h.Store.User.GetUsersForOrganization(ctx, "")
dmzUsers, err := h.Store.User.GetUsersForOrganization(ctx, "", 99999)
if err != nil {
result.Message = "Error: unable to fetch Documize users"
result.IsError = true

View file

@ -115,7 +115,7 @@ type UserStorer interface {
GetByToken(ctx RequestContext, token string) (u user.User, err error)
GetBySerial(ctx RequestContext, serial string) (u user.User, err error)
GetActiveUsersForOrganization(ctx RequestContext) (u []user.User, err error)
GetUsersForOrganization(ctx RequestContext, filter string) (u []user.User, err error)
GetUsersForOrganization(ctx RequestContext, filter string, limit int) (u []user.User, err error)
GetSpaceUsers(ctx RequestContext, spaceID string) (u []user.User, err error)
GetUsersForSpaces(ctx RequestContext, spaces []string) (u []user.User, err error)
UpdateUser(ctx RequestContext, u user.User) (err error)

View file

@ -248,6 +248,11 @@ func (h *Handler) GetOrganizationUsers(w http.ResponseWriter, r *http.Request) {
active = false
}
limit, _ := strconv.Atoi(request.Query(r, "limit"))
if limit == 0 {
limit = 100
}
u := []user.User{}
if active {
@ -258,7 +263,7 @@ func (h *Handler) GetOrganizationUsers(w http.ResponseWriter, r *http.Request) {
return
}
} else {
u, err = h.Store.User.GetUsersForOrganization(ctx, filter)
u, err = h.Store.User.GetUsersForOrganization(ctx, filter, limit)
if err != nil && err != sql.ErrNoRows {
response.WriteServerError(w, method, err)
h.Runtime.Log.Error(method, err)

View file

@ -132,7 +132,7 @@ func (s Scope) GetActiveUsersForOrganization(ctx domain.RequestContext) (u []use
// GetUsersForOrganization returns a slice containing all of the user records for the organizaiton
// identified in the Persister.
func (s Scope) GetUsersForOrganization(ctx domain.RequestContext, filter string) (u []user.User, err error) {
func (s Scope) GetUsersForOrganization(ctx domain.RequestContext, filter string, limit int) (u []user.User, err error) {
u = []user.User{}
filter = strings.TrimSpace(strings.ToLower(filter))
@ -146,7 +146,7 @@ func (s Scope) GetUsersForOrganization(ctx domain.RequestContext, filter string)
u.global, a.active, a.editor, a.admin, a.users AS viewusers, a.analytics
FROM user u, account a
WHERE u.refid=a.userid AND a.orgid=? `+likeQuery+
`ORDER BY u.firstname, u.lastname LIMIT 100`, ctx.OrgID)
`ORDER BY u.firstname, u.lastname LIMIT `+strconv.Itoa(limit), ctx.OrgID)
if err == sql.ErrNoRows {
err = nil

View file

@ -34,8 +34,11 @@ export default Base.extend({
authenticate(data) {
data.domain = netUtil.getSubdomain();
if (!isPresent(data.token) || !isPresent(data.email)) {
return reject("invalid");
if (!isPresent(data.token)) {
return reject("data.token is empty");
}
if (!isPresent(data.email)) {
return reject("data.email is empty");
}
return this.get('ajax').post('public/authenticate/keycloak', {

View file

@ -12,9 +12,9 @@
import $ from 'jquery';
import { inject as service } from '@ember/service';
import { schedule, debounce } from '@ember/runloop';
import Component from '@ember/component';
import AuthProvider from '../../mixins/auth';
import ModalMixin from '../../mixins/modal';
import Component from '@ember/component';
export default Component.extend(AuthProvider, ModalMixin, {
groupSvc: service('group'),
@ -230,6 +230,15 @@ export default Component.extend(AuthProvider, ModalMixin, {
this.get('groupSvc').join(groupId, userId).then(() => {
this.filterUsers();
});
},
onSync() {
this.get('onSync')();
},
onLimit(limit) {
this.set('userLimit', limit);
this.filterUsers();
}
}
});

View file

@ -41,7 +41,11 @@ export default Route.extend({
this.get("session").authenticate('authenticator:keycloak', data).then(() => {
this.transitionTo('folders');
}, (reject) => {
if (is.not.undefined(reject.Error)) {
this.set('message', reject.Error);
} else {
this.set('message', reject);
}
this.set('mode', 'reject');
resolve();
});

View file

@ -14,9 +14,12 @@ import Controller from '@ember/controller';
export default Controller.extend({
userService: service('user'),
globalSvc: service('global'),
syncInProgress: false,
userLimit: 100,
loadUsers(filter) {
this.get('userService').getComplete(filter).then((users) => {
this.get('userService').getComplete(filter, this.get('userLimit')).then((users) => {
this.set('model', users);
});
},
@ -52,6 +55,14 @@ export default Controller.extend({
onFilter(filter) {
this.loadUsers(filter);
},
onSync() {
this.set('syncInProgress', true);
this.get('globalSvc').syncExternalUsers().then(() => {
this.set('syncInProgress', false);
this.loadUsers('');
});
}
}
});

View file

@ -16,7 +16,6 @@ import AuthenticatedRouteMixin from 'ember-simple-auth/mixins/authenticated-rout
export default Route.extend(AuthenticatedRouteMixin, {
userService: service('user'),
global: service('global'),
appMeta: service(),
beforeModel () {
@ -27,20 +26,10 @@ export default Route.extend(AuthenticatedRouteMixin, {
model() {
return new EmberPromise((resolve) => {
let constants = this.get('constants');
if (this.get('appMeta.authProvider') == constants.AuthProvider.Keycloak) {
this.get('global').syncExternalUsers().then(() => {
this.get('userService').getComplete('').then((users) =>{
this.get('userService').getComplete('', 100).then((users) => {
resolve(users);
});
});
} else {
this.get('userService').getComplete('').then((users) => {
resolve(users);
});
}
});
},
activate() {

View file

@ -3,6 +3,9 @@
onAddUsers=(action 'onAddUsers')}}
{{customize/user-list users=model
syncInProgress=syncInProgress
userLimit=userLimit
onSync=(action "onSync")
onFilter=(action "onFilter")
onDelete=(action "onDelete")
onSave=(action "onSave")

View file

@ -68,11 +68,12 @@ export default Service.extend({
// Returns all active and inactive users for organization.
// Only available for admins and limits results to max. 100 users.
// Takes filter for user search criteria.
getComplete(filter) {
getComplete(filter, limit) {
filter = filter.trim();
if (filter.length > 0) filter = encodeURIComponent(filter);
if (is.null(limit) || is.undefined(limit)) limit = 100;
return this.get('ajax').request(`users?active=0&filter=${filter}`).then((response) => {
return this.get('ajax').request(`users?active=0&filter=${filter}&limit=${limit}`).then((response) => {
if (is.not.array(response)) response = [];
return response.map((obj) => {

View file

@ -157,4 +157,8 @@
}
}
}
> .max-results {
float: right;
}
}

View file

@ -1,4 +1,11 @@
<div class="view-customize my-5">
{{#if isAuthProviderKeycloak}}
{{#if syncInProgress}}
<div class="btn btn-secondary mt-3 mb-3">Keycloak user sync running...</div>
{{else}}
<div class="btn btn-success mt-3 mb-3" {{action 'onSync'}}>Sync with Keycloak</div>
{{/if}}
{{/if}}
<div class="my-2">
<span class="font-weight-bold">Spaces</span>
@ -26,6 +33,39 @@
<small class="form-text text-muted">search firstname, lastname, email</small>
</div>
<div class="max-results py-3">
<div class="btn-group btn-group-toggle">
<label class="btn btn-outline-secondary {{if (eq userLimit 1) 'active'}}">
<input type="radio" name="options" autocomplete="off" {{action 'onLimit' 1}}>1
</label>
<label class="btn btn-outline-secondary {{if (eq userLimit 10) 'active'}}">
<input type="radio" name="options" autocomplete="off" {{action 'onLimit' 10}}>10
</label>
<label class="btn btn-outline-secondary {{if (eq userLimit 25) 'active'}}">
<input type="radio" name="options" autocomplete="off" {{action 'onLimit' 25}}>25
</label>
<label class="btn btn-outline-secondary {{if (eq userLimit 50) 'active'}}">
<input type="radio" name="options" autocomplete="off" {{action 'onLimit' 50}}>50
</label>
<label class="btn btn-outline-secondary {{if (eq userLimit 100) 'active'}}">
<input type="radio" name="options" autocomplete="off" {{action 'onLimit' 100}}>100
</label>
<label class="btn btn-outline-secondary {{if (eq userLimit 250) 'active'}}">
<input type="radio" name="options" autocomplete="off" {{action 'onLimit' 250}}>250
</label>
<label class="btn btn-outline-secondary {{if (eq userLimit 500) 'active'}}">
<input type="radio" name="options" autocomplete="off" {{action 'onLimit' 500}}>500
</label>
<label class="btn btn-outline-secondary {{if (eq userLimit 1000) 'active'}}">
<input type="radio" name="options" autocomplete="off" {{action 'onLimit' 1000}}>1,000
</label>
<label class="btn btn-outline-secondary {{if (eq userLimit 99999) 'active'}}">
<input type="radio" name="options" autocomplete="off" {{action 'onLimit' 99999}}>all
</label>
</div>
</div>
<table class="table table-responsive table-borderless user-table">
<thead>
<tr>