* Fixed current authenticators to use "real_name" instead of realName in createuser && modifyuser

* Finished (hopefully) Users add/edit
This commit is contained in:
Adolfo Gómez 2013-12-10 03:16:58 +00:00
parent 75a7a787b9
commit fb1a367e93
12 changed files with 116 additions and 29 deletions

View File

@ -48,6 +48,7 @@ logger = logging.getLogger(__name__)
class Authenticators(ModelHandler):
model = Authenticator
custom_methods = ['search']
detail = { 'users': Users, 'groups':Groups }
save_fields = ['name', 'comments', 'priority', 'small_name']
@ -90,3 +91,24 @@ class Authenticators(ModelHandler):
'type': type_.type(),
}
# Custom "search" method
def search(self, item):
try:
type_ = self._params['type']
if type_ not in ('user', 'group'):
self.invalidRequestException()
term = self._params['term']
auth = item.getInstance()
canDoSearch = type_ == 'user' and (auth.searchUsers != auths.Authenticator.searchUsers) or (auth.searchGroups != auths.Authenticator.searchGroups)
if canDoSearch is False:
self.invalidRequestException()
if type_ == 'user':
return auth.searchUsers(term)
else:
return auth.searchGroups(term)
except:
self.invalidRequestException()

View File

@ -96,18 +96,25 @@ class Users(DetailHandler):
# Extract item db fields
# We need this fields for all
logger.debug('Saving user {0} / {1}'.format(parent, item))
fields = self.readFieldsFromParams(['name', 'real_name', 'comments', 'state', 'staff_member', 'is_admin', 'groups'])
valid_fields = ['name', 'real_name', 'comments', 'state', 'staff_member', 'is_admin']
fields = self.readFieldsFromParams(valid_fields + ['groups'])
try:
auth = parent.getInstance()
groups = fields['groups']
del fields['groups'] # Not update this on user dict
if item is None: # Create new
auth.createUser(fields) # this throws an exception if there is an error (for example, this auth can't create users)
user = parent.users.create(**fields)
toSave = {}
for k in valid_fields:
toSave[k] = fields[k]
user = parent.users.create(**toSave)
else:
auth.modifyUser(fields) # Notifies authenticator
toSave = {}
for k in valid_fields:
toSave[k] = fields[k]
user = parent.users.get(pk=item)
user.__dict__.update(fields)
user.__dict__.update(toSave)
if auth.isExternalSource == False and user.parent == -1:
user.groups = Group.objects.filter(id__in=groups)

View File

@ -319,6 +319,7 @@ class ModelHandler(BaseModelHandler):
needs_staff = True
# Which model does this manage
model = None
custom_methods = [] # If this model respond to "custom" methods, we will declare them here
# If this model has details, which ones
detail = None # Dictionary containing detail routing
# Put needed fields
@ -380,6 +381,8 @@ class ModelHandler(BaseModelHandler):
path = self._path + '/'.join(args[:2])
detail = detailCls(self, path, self._params, *args, parent = item)
method = getattr(detail, self._operation)
except KeyError:
self.invalidMethodException()
except AttributeError:
self.invalidMethodException()
@ -435,11 +438,21 @@ class ModelHandler(BaseModelHandler):
if nArgs != 2:
self.invalidRequestException()
try:
item = self.model.objects.filter(pk=self._args[0])[0]
item = self.model.objects.get(pk=self._args[0])
except:
self.invalidItemException()
return self.getLogs(item)
# if has custom methods
if self._args[1] in self.custom_methods:
try:
operation = getattr(self, self._args[1])
item = self.model.objects.get(pk=self._args[0])
except:
self.invalidMethodException()
return operation(item)
# If has detail and is requesting detail
if self.detail is not None:
return self.processDetail()

View File

@ -295,14 +295,14 @@ class RegexLdap(auths.Authenticator):
External sources already has the user cause they are managed externally, so, it can at most test if the users exists on external source
before accepting it.
Groups are only used in case of internal users (non external sources) that must know to witch groups this user belongs to
@param usrData: Contains data received from user directly, that is, a dictionary with at least: name, realName, comments, state & password
@param usrData: Contains data received from user directly, that is, a dictionary with at least: name, real_name, comments, state & password
@return: Raises an exception (AuthException) it things didn't went fine
'''
res = self.__getUser(usrData['name'])
if res is None:
raise AuthenticatorException(_('Username not found'))
# Fills back realName field
usrData['realName'] = self.__getUserRealName(res)
usrData['real_name'] = self.__getUserRealName(res)
def getRealName(self, username):

View File

@ -275,7 +275,7 @@ class SampleAuth(auths.Authenticator):
to create new users "by hand", i mean, the "new" options from menus will dissapear.
usrData is a dictionary that contains the input parameters from user,
with at least name, realName, comments, state & password.
with at least name, real_name, comments, state & password.
We can modify this parameters, we can modify ALL, but name is not recommended to
modify it unles you know what you are doing.
@ -283,7 +283,7 @@ class SampleAuth(auths.Authenticator):
Here, we will set the state to "Inactive" and realName to the same as username, but twice :-)
'''
from uds.core.util.State import State
usrData['realName'] = usrData['name'] + ' ' + usrData['name']
usrData['real_name'] = usrData['name'] + ' ' + usrData['name']
usrData['state'] = State.INACTIVE
def modifyUser(self, usrData):
@ -295,7 +295,7 @@ class SampleAuth(auths.Authenticator):
it's valid).
usrData is a dictionary that contains the input parameters from user,
with at least name, realName, comments, state & password.
with at least name, real_name, comments, state & password.
We can modify this parameters, we can modify ALL, but name is not recommended to
modify it unless you know what you are doing.
@ -303,5 +303,5 @@ class SampleAuth(auths.Authenticator):
Here, we will simply update the realName of the user, and (we have to take care
this this kind of things) modify the userName to a new one, the original plus '-1'
'''
usrData['realName'] = usrData['name'] + ' ' + usrData['name']
usrData['real_name'] = usrData['name'] + ' ' + usrData['name']
usrData['name'] = usrData['name'] + '-1'

View File

@ -268,7 +268,7 @@ class SimpleLDAPAuthenticator(Authenticator):
if res is None:
raise AuthenticatorException(_('Username not found'))
# Fills back realName field
usrData['realName'] = self.__getUserRealName(res)
usrData['real_name'] = self.__getUserRealName(res)
def getRealName(self, username):
'''

View File

@ -515,7 +515,7 @@ class Authenticator(Module):
Args:
usrData: Contains data received from user directly, that is a dictionary
with at least: name, realName, comments, state & password.
with at least: name, real_name, comments, state & password.
This is an in/out parameter, so you can modify, for example,
**realName**
@ -545,7 +545,7 @@ class Authenticator(Module):
Args:
usrData: Contains data received from user directly, that is a dictionary
with at least: name, realName, comments, state & password.
with at least: name, real_name, comments, state & password.
This is an in/out parameter, so you can modify, for example,
**realName**

View File

@ -250,6 +250,15 @@ BasicModelRest.prototype = {
});
},
// Search
search: function(id, type, term, success_fnc, fail_fnc) {
"use strict";
return this.get({
id: id + '/search?type=' + encodeURIComponent(type) + '&term=' + encodeURIComponent(term),
success: success_fnc,
fail: fail_fnc
});
},
// -------------
// Log methods
// -------------
@ -311,8 +320,6 @@ BasicModelRest.prototype = {
method: 'POST'
});
},
// --------------
// Delete
// --------------

View File

@ -48,22 +48,49 @@ gui.authenticators.link = function(event) {
// Search button event generator for user/group
var searchForm = function(modalId, model, title, searchLabel, resultsLabel, srcSelector) {
$(modalId + ' .button-search').on('click', function() {
var searchForm = function(parentModalId, type, id, title, searchLabel, resultsLabel, srcSelector) {
var errorModal = gui.failRequestModalFnc(gettext('Search error'));
$(parentModalId + ' .button-search').on('click', function() {
api.templates.get('search', function(tmpl) { // Get form template
var modalId = gui.launchModal(title, api.templates.evaluate(tmpl, {
search_label : searchLabel,
results_label : resultsLabel,
}), { actionButton: '<button type="button" class="btn btn-success button-accept">' + gettext('Accept') + '</button>'});
var searchInput = modalId + ' input[name="search"]';
var resultsInput = modalId + ' select';
$(searchInput).val($(srcSelector).val());
var $searchInput = $(modalId + ' input[name="search"]');
var $select = $(modalId + ' select[name="results"]');
var $searchButton = $(modalId + ' .button-do-search');
$searchInput.val($(srcSelector).val());
$(modalId + ' .button-accept').on('click', function(){
gui.doLog('Accepted');
var value = $select.val();
if( value ) {
$(srcSelector).val(value);
$(modalId).modal('hide');
}
});
$searchButton.on('click', function() {
$searchButton.addClass('disabled');
var term = $searchInput.val();
api.authenticators.search(id, type, term, function(data) {
$searchButton.removeClass('disabled');
$select.empty();
gui.doLog(data);
$.each(data, function(undefined, value) {
$select.append('<option value="' + value.id + '">' + value.id + ' (' + value.name + ')</option>');
});
}, function(jqXHR, textStatus, errorThrown) {
$searchButton.removeClass('disabled');
errorModal(jqXHR, textStatus, errorThrown);
});
});
if( $searchInput.val() != '') {
$searchButton.click();
}
});
});
};
@ -143,8 +170,11 @@ gui.authenticators.link = function(event) {
onLoad: function(k) {
gui.tools.unblockUI();
},
onRefresh : function() {
$('#users-log-placeholder').empty(); // Remove logs on detail refresh
},
onEdit: function(value, event, table, refreshFnc) {
var password = "#æð~¬~@æß”¢ß€~½¬@#~½¬@|"; // Garbage for password (to detect change)
var password = "#æð~¬ŋ@æß”¢€~½¬@#~þ¬@|"; // Garbage for password (to detect change)
gui.tools.blockUI();
api.templates.get('user', function(tmpl) { // Get form template
group.rest.overview(function(groups) { // Get groups
@ -228,7 +258,7 @@ gui.authenticators.link = function(event) {
gui.tools.unblockUI();
searchForm(modalId, user, gettext('Search users'), gettext('User'), gettext('Users found'), modalId + ' input[name="name"]'); // Enable search button click, if it exist ofc
searchForm(modalId, 'user', id, gettext('Search users'), gettext('User'), gettext('Users found'), modalId + ' input[name="name"]'); // Enable search button click, if it exist ofc
$(modalId + ' .button-accept').click(function(){
var fields = gui.forms.read(modalId);

View File

@ -1,17 +1,17 @@
{% load i18n %}
{% verbatim %}
<form role="form">
<form role="form" class="do-search-form">
<div class="form-group">
<label for="id_srch_search">{{ search_label }}</label>
<label>{{ search_label }}</label>
<div class="input-group">
<input type="text" class="form-control" name="search">
<span class="input-group-btn">
<button class="btn btn-info" type="button"><i class="fa fa-search"></i> {% endverbatim %}{% trans 'Search' %}{% verbatim %}</button>
<button class="btn btn-info button-do-search" type="button"><i class="fa fa-search"></i> {% endverbatim %}{% trans 'Search' %}{% verbatim %}</button>
</span>
</div><!-- /input-group -->
</div>
<div class="form-group">
<label for="id_srch_search">{{ results_label }}</label>
<label>{{ results_label }}</label>
<select class="form-control" size="8" name="results">
</select>
</div>

View File

@ -7,16 +7,22 @@
<label for="id_username" class="col-sm-2 control-label">{{ username_label }}</label>
<div class="col-sm-10">
{{# if canSearchUsers }}
{{# if username }}
{{ else }}
<div class="input-group">
{{/ if }}
{{/ if }}
<input name="name" value="{{ username }}" type="text" id="id_username" class="form-control modal_field_data"
placeholder="{% endverbatim %}{% trans 'Username' %}{% verbatim %}"{{# if username }}readonly{{/ if }}>
{{# if canSearchUsers }}
{{# if username }}
{{ else }}
<span class="input-group-btn">
<button class="btn btn-info button-search" type="button"><i class="fa fa-search"></i> {% endverbatim %}{% trans 'Search' %}{% verbatim %}</button>
</span>
</div>
{{/ if }}
{{/ if }}
</div>
</div>
<div class="form-group">

View File

@ -90,6 +90,7 @@ def createUser(credentials, usr):
auth = DbAuthenticator.objects.get(pk=usr['idParent'])
try:
authInstance = auth.getInstance()
usr['real_name'] = usr['realName'] # Copy to keep this in the right place
authInstance.createUser(usr) # Remenber, this throws an exception if there is an error
staffMember = isAdmin = False
if credentials.isAdmin is True:
@ -99,7 +100,7 @@ def createUser(credentials, usr):
if authInstance.needsPassword is True:
password = CryptoManager.manager().hash(usr['password'])
user = auth.users.create(name = usr['name'], real_name = usr['realName'], comments = usr['comments'], state = usr['state'],
user = auth.users.create(name = usr['name'], real_name = usr['real_name'], comments = usr['comments'], state = usr['state'],
password = password, staff_member = staffMember, is_admin = isAdmin)
if authInstance.isExternalSource == False:
@ -123,10 +124,11 @@ def modifyUser(credentials, usr):
try:
user = DbUser.objects.get(pk=usr['id'])
auth = user.manager.getInstance()
usr['real_name'] = usr['realName'] # Copy to keep this in the right place
auth.modifyUser(usr) # Notifies authenticator
logger.debug(usr)
user.name = usr['name']
user.real_name = usr['realName']
user.real_name = usr['real_name']
user.comments = usr['comments']
if credentials.isAdmin is True:
logger.debug('Is an admin')