mirror of
https://github.com/documize/community.git
synced 2025-07-20 05:39:42 +02:00
Set user admin max results and Keycloak sync option
This commit is contained in:
parent
2c8b757ff6
commit
351b8dcc12
13 changed files with 100 additions and 31 deletions
|
@ -94,7 +94,7 @@ func (h *Handler) Sync(w http.ResponseWriter, r *http.Request) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// User list from Documize
|
// User list from Documize
|
||||||
dmzUsers, err := h.Store.User.GetUsersForOrganization(ctx, "")
|
dmzUsers, err := h.Store.User.GetUsersForOrganization(ctx, "", 99999)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
result.Message = "Error: unable to fetch Documize users"
|
result.Message = "Error: unable to fetch Documize users"
|
||||||
result.IsError = true
|
result.IsError = true
|
||||||
|
|
|
@ -115,7 +115,7 @@ type UserStorer interface {
|
||||||
GetByToken(ctx RequestContext, token string) (u user.User, err error)
|
GetByToken(ctx RequestContext, token string) (u user.User, err error)
|
||||||
GetBySerial(ctx RequestContext, serial string) (u user.User, err error)
|
GetBySerial(ctx RequestContext, serial string) (u user.User, err error)
|
||||||
GetActiveUsersForOrganization(ctx RequestContext) (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)
|
GetSpaceUsers(ctx RequestContext, spaceID string) (u []user.User, err error)
|
||||||
GetUsersForSpaces(ctx RequestContext, spaces []string) (u []user.User, err error)
|
GetUsersForSpaces(ctx RequestContext, spaces []string) (u []user.User, err error)
|
||||||
UpdateUser(ctx RequestContext, u user.User) (err error)
|
UpdateUser(ctx RequestContext, u user.User) (err error)
|
||||||
|
|
|
@ -248,6 +248,11 @@ func (h *Handler) GetOrganizationUsers(w http.ResponseWriter, r *http.Request) {
|
||||||
active = false
|
active = false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
limit, _ := strconv.Atoi(request.Query(r, "limit"))
|
||||||
|
if limit == 0 {
|
||||||
|
limit = 100
|
||||||
|
}
|
||||||
|
|
||||||
u := []user.User{}
|
u := []user.User{}
|
||||||
|
|
||||||
if active {
|
if active {
|
||||||
|
@ -258,7 +263,7 @@ func (h *Handler) GetOrganizationUsers(w http.ResponseWriter, r *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
u, err = h.Store.User.GetUsersForOrganization(ctx, filter)
|
u, err = h.Store.User.GetUsersForOrganization(ctx, filter, limit)
|
||||||
if err != nil && err != sql.ErrNoRows {
|
if err != nil && err != sql.ErrNoRows {
|
||||||
response.WriteServerError(w, method, err)
|
response.WriteServerError(w, method, err)
|
||||||
h.Runtime.Log.Error(method, err)
|
h.Runtime.Log.Error(method, err)
|
||||||
|
|
|
@ -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
|
// GetUsersForOrganization returns a slice containing all of the user records for the organizaiton
|
||||||
// identified in the Persister.
|
// 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{}
|
u = []user.User{}
|
||||||
|
|
||||||
filter = strings.TrimSpace(strings.ToLower(filter))
|
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
|
u.global, a.active, a.editor, a.admin, a.users AS viewusers, a.analytics
|
||||||
FROM user u, account a
|
FROM user u, account a
|
||||||
WHERE u.refid=a.userid AND a.orgid=? `+likeQuery+
|
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 {
|
if err == sql.ErrNoRows {
|
||||||
err = nil
|
err = nil
|
||||||
|
|
|
@ -34,8 +34,11 @@ export default Base.extend({
|
||||||
authenticate(data) {
|
authenticate(data) {
|
||||||
data.domain = netUtil.getSubdomain();
|
data.domain = netUtil.getSubdomain();
|
||||||
|
|
||||||
if (!isPresent(data.token) || !isPresent(data.email)) {
|
if (!isPresent(data.token)) {
|
||||||
return reject("invalid");
|
return reject("data.token is empty");
|
||||||
|
}
|
||||||
|
if (!isPresent(data.email)) {
|
||||||
|
return reject("data.email is empty");
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.get('ajax').post('public/authenticate/keycloak', {
|
return this.get('ajax').post('public/authenticate/keycloak', {
|
||||||
|
|
|
@ -12,9 +12,9 @@
|
||||||
import $ from 'jquery';
|
import $ from 'jquery';
|
||||||
import { inject as service } from '@ember/service';
|
import { inject as service } from '@ember/service';
|
||||||
import { schedule, debounce } from '@ember/runloop';
|
import { schedule, debounce } from '@ember/runloop';
|
||||||
import Component from '@ember/component';
|
|
||||||
import AuthProvider from '../../mixins/auth';
|
import AuthProvider from '../../mixins/auth';
|
||||||
import ModalMixin from '../../mixins/modal';
|
import ModalMixin from '../../mixins/modal';
|
||||||
|
import Component from '@ember/component';
|
||||||
|
|
||||||
export default Component.extend(AuthProvider, ModalMixin, {
|
export default Component.extend(AuthProvider, ModalMixin, {
|
||||||
groupSvc: service('group'),
|
groupSvc: service('group'),
|
||||||
|
@ -230,6 +230,15 @@ export default Component.extend(AuthProvider, ModalMixin, {
|
||||||
this.get('groupSvc').join(groupId, userId).then(() => {
|
this.get('groupSvc').join(groupId, userId).then(() => {
|
||||||
this.filterUsers();
|
this.filterUsers();
|
||||||
});
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
onSync() {
|
||||||
|
this.get('onSync')();
|
||||||
|
},
|
||||||
|
|
||||||
|
onLimit(limit) {
|
||||||
|
this.set('userLimit', limit);
|
||||||
|
this.filterUsers();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -41,7 +41,11 @@ export default Route.extend({
|
||||||
this.get("session").authenticate('authenticator:keycloak', data).then(() => {
|
this.get("session").authenticate('authenticator:keycloak', data).then(() => {
|
||||||
this.transitionTo('folders');
|
this.transitionTo('folders');
|
||||||
}, (reject) => {
|
}, (reject) => {
|
||||||
|
if (is.not.undefined(reject.Error)) {
|
||||||
this.set('message', reject.Error);
|
this.set('message', reject.Error);
|
||||||
|
} else {
|
||||||
|
this.set('message', reject);
|
||||||
|
}
|
||||||
this.set('mode', 'reject');
|
this.set('mode', 'reject');
|
||||||
resolve();
|
resolve();
|
||||||
});
|
});
|
||||||
|
|
|
@ -14,9 +14,12 @@ import Controller from '@ember/controller';
|
||||||
|
|
||||||
export default Controller.extend({
|
export default Controller.extend({
|
||||||
userService: service('user'),
|
userService: service('user'),
|
||||||
|
globalSvc: service('global'),
|
||||||
|
syncInProgress: false,
|
||||||
|
userLimit: 100,
|
||||||
|
|
||||||
loadUsers(filter) {
|
loadUsers(filter) {
|
||||||
this.get('userService').getComplete(filter).then((users) => {
|
this.get('userService').getComplete(filter, this.get('userLimit')).then((users) => {
|
||||||
this.set('model', users);
|
this.set('model', users);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
@ -52,6 +55,14 @@ export default Controller.extend({
|
||||||
|
|
||||||
onFilter(filter) {
|
onFilter(filter) {
|
||||||
this.loadUsers(filter);
|
this.loadUsers(filter);
|
||||||
|
},
|
||||||
|
|
||||||
|
onSync() {
|
||||||
|
this.set('syncInProgress', true);
|
||||||
|
this.get('globalSvc').syncExternalUsers().then(() => {
|
||||||
|
this.set('syncInProgress', false);
|
||||||
|
this.loadUsers('');
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -16,7 +16,6 @@ import AuthenticatedRouteMixin from 'ember-simple-auth/mixins/authenticated-rout
|
||||||
|
|
||||||
export default Route.extend(AuthenticatedRouteMixin, {
|
export default Route.extend(AuthenticatedRouteMixin, {
|
||||||
userService: service('user'),
|
userService: service('user'),
|
||||||
global: service('global'),
|
|
||||||
appMeta: service(),
|
appMeta: service(),
|
||||||
|
|
||||||
beforeModel () {
|
beforeModel () {
|
||||||
|
@ -27,20 +26,10 @@ export default Route.extend(AuthenticatedRouteMixin, {
|
||||||
|
|
||||||
model() {
|
model() {
|
||||||
return new EmberPromise((resolve) => {
|
return new EmberPromise((resolve) => {
|
||||||
let constants = this.get('constants');
|
this.get('userService').getComplete('', 100).then((users) => {
|
||||||
|
|
||||||
if (this.get('appMeta.authProvider') == constants.AuthProvider.Keycloak) {
|
|
||||||
this.get('global').syncExternalUsers().then(() => {
|
|
||||||
this.get('userService').getComplete('').then((users) =>{
|
|
||||||
resolve(users);
|
resolve(users);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
} else {
|
|
||||||
this.get('userService').getComplete('').then((users) => {
|
|
||||||
resolve(users);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
|
|
||||||
activate() {
|
activate() {
|
||||||
|
|
|
@ -3,6 +3,9 @@
|
||||||
onAddUsers=(action 'onAddUsers')}}
|
onAddUsers=(action 'onAddUsers')}}
|
||||||
|
|
||||||
{{customize/user-list users=model
|
{{customize/user-list users=model
|
||||||
|
syncInProgress=syncInProgress
|
||||||
|
userLimit=userLimit
|
||||||
|
onSync=(action "onSync")
|
||||||
onFilter=(action "onFilter")
|
onFilter=(action "onFilter")
|
||||||
onDelete=(action "onDelete")
|
onDelete=(action "onDelete")
|
||||||
onSave=(action "onSave")
|
onSave=(action "onSave")
|
||||||
|
|
|
@ -68,11 +68,12 @@ export default Service.extend({
|
||||||
// Returns all active and inactive users for organization.
|
// Returns all active and inactive users for organization.
|
||||||
// Only available for admins and limits results to max. 100 users.
|
// Only available for admins and limits results to max. 100 users.
|
||||||
// Takes filter for user search criteria.
|
// Takes filter for user search criteria.
|
||||||
getComplete(filter) {
|
getComplete(filter, limit) {
|
||||||
filter = filter.trim();
|
filter = filter.trim();
|
||||||
if (filter.length > 0) filter = encodeURIComponent(filter);
|
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 = [];
|
if (is.not.array(response)) response = [];
|
||||||
|
|
||||||
return response.map((obj) => {
|
return response.map((obj) => {
|
||||||
|
|
|
@ -157,4 +157,8 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
> .max-results {
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,11 @@
|
||||||
<div class="view-customize my-5">
|
<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">
|
<div class="my-2">
|
||||||
<span class="font-weight-bold">Spaces</span>
|
<span class="font-weight-bold">Spaces</span>
|
||||||
|
@ -26,6 +33,39 @@
|
||||||
<small class="form-text text-muted">search firstname, lastname, email</small>
|
<small class="form-text text-muted">search firstname, lastname, email</small>
|
||||||
</div>
|
</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">
|
<table class="table table-responsive table-borderless user-table">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue