manager: implement role view
This commit is contained in:
parent
c9716ef62b
commit
dd1ffa8a04
|
@ -0,0 +1,18 @@
|
|||
import sys
|
||||
|
||||
class AppSettings(object):
|
||||
__PREFIX = 'A2_MANAGER_'
|
||||
__DEFAULTS = {
|
||||
'HOMEPAGE_URL': None,
|
||||
'LOGOUT_URL': None,
|
||||
}
|
||||
|
||||
def __getattr__(self, name):
|
||||
from django.conf import settings
|
||||
if name not in self.__DEFAULTS:
|
||||
raise AttributeError
|
||||
return getattr(settings, self.__PREFIX + name, self.__DEFAULTS[name])
|
||||
|
||||
app_settings = AppSettings()
|
||||
app_settings.__name__ = __name__
|
||||
sys.modules[__name__] = app_settings
|
|
@ -0,0 +1,20 @@
|
|||
from django_select2 import AutoSelect2Field, NO_ERR_RESP
|
||||
|
||||
from . import utils
|
||||
|
||||
class ChooseUserField(AutoSelect2Field):
|
||||
def security_check(self, request, *args, **kwargs):
|
||||
return True
|
||||
|
||||
def get_results(self, request, term, page, context):
|
||||
return (NO_ERR_RESP, False, [(u.ref, u.name) for u in utils.search_user(term)])
|
||||
|
||||
def get_val_txt(self, value):
|
||||
"""
|
||||
The problem of issue #66 was here. I was not overriding this.
|
||||
When using AutoSelect2MultipleField you should implement get_val_txt in this case.
|
||||
I think that this is because there should be an unique correspondence between
|
||||
the referenced value and the shown value
|
||||
In this particular example, the referenced value and the shown value are the same
|
||||
"""
|
||||
return unicode(value)
|
|
@ -0,0 +1,17 @@
|
|||
from django.utils.translation import ugettext_lazy as _
|
||||
from django import forms
|
||||
|
||||
from . import utils, fields
|
||||
|
||||
class RoleAddForm(forms.Form):
|
||||
name = forms.CharField(
|
||||
label=_('Role name'))
|
||||
|
||||
def save(self):
|
||||
return utils.role_add(self.cleaned_data['name'])
|
||||
|
||||
|
||||
class ChooseUserForm(forms.Form):
|
||||
user = fields.ChooseUserField(label=_('user'))
|
||||
|
||||
|
|
@ -0,0 +1,77 @@
|
|||
function displayPopup(event)
|
||||
{
|
||||
var $anchor = $(this);
|
||||
var url = $anchor.attr('href');
|
||||
var selector = $anchor.data('selector') || 'form';
|
||||
|
||||
function ajaxform_submit (data, status, xhr, form) {
|
||||
if ('location' in data) {
|
||||
var location = $.url(data.location);
|
||||
var href = $.url(window.location.href);
|
||||
if (location.attr('protocol') == href.attr('protocol') &&
|
||||
location.attr('host') == href.attr('host') &&
|
||||
location.attr('relative') == href.attr('relative')) {
|
||||
var e = $.Event('popup-success');
|
||||
$anchor.trigger(e);
|
||||
if (! e.isDefaultPrevented()) {
|
||||
window.location.reload(true);
|
||||
}
|
||||
}
|
||||
// set anchor if it changed
|
||||
window.location = data.location;
|
||||
} else {
|
||||
var html = data.content;
|
||||
$(form).empty().append($(html).find(selector).children());
|
||||
$(form).find('.buttons').hide();
|
||||
}
|
||||
}
|
||||
|
||||
$.ajax({
|
||||
url: url,
|
||||
success: function(html) {
|
||||
var is_json = typeof html != 'string';
|
||||
if (is_json) {
|
||||
var html = html.content;
|
||||
} else {
|
||||
var html = html;
|
||||
}
|
||||
var form = $(html).find(selector);
|
||||
var title = $(html).find('#appbar h2').text();
|
||||
var dialog = $(form).dialog({modal: true, 'title': title, width: 'auto'});
|
||||
var buttons = Array();
|
||||
if (! form.prop('action')) {
|
||||
form.prop('action', url);
|
||||
}
|
||||
$(dialog).find('.buttons').hide();
|
||||
$(html).find('.buttons button, .buttons a').each(function(idx, elem) {
|
||||
var button = Object();
|
||||
button.text = $(elem).text();
|
||||
if ($(elem).hasClass('cancel')) {
|
||||
button.click = function() { dialog.dialog('destroy'); return false; };
|
||||
} else {
|
||||
button.click = function() { form.find('button').click(); return false; };
|
||||
}
|
||||
if ($(elem).hasClass('submit-button')) {
|
||||
button.class = 'submit-button';
|
||||
} else if ($(elem).hasClass('delete-button')) {
|
||||
button.class = 'delete-button';
|
||||
}
|
||||
buttons.push(button);
|
||||
});
|
||||
buttons.reverse();
|
||||
$(dialog).dialog('option', 'buttons', buttons);
|
||||
if ($(dialog).find('input:visible').length) {
|
||||
$(dialog).find('input:visible')[0].focus();
|
||||
}
|
||||
if (is_json && $.fn.url != undefined && $.fn.ajaxForm != undefined) {
|
||||
$(form).ajaxForm({success: ajaxform_submit});
|
||||
}
|
||||
return false;
|
||||
}
|
||||
});
|
||||
return false;
|
||||
}
|
||||
|
||||
$(function() {
|
||||
$('a[rel=popup]').click(displayPopup);
|
||||
});
|
|
@ -0,0 +1,9 @@
|
|||
import django_tables2 as tables
|
||||
from django.contrib.auth.models import User
|
||||
|
||||
class UserTable(tables.Table):
|
||||
class Meta:
|
||||
model = User
|
||||
attrs = {'class': 'main', 'id': 'user-table'}
|
||||
fields = ('username', 'email', 'first_name', 'last_name',
|
||||
'is_active')
|
|
@ -0,0 +1,185 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="fr">
|
||||
<head>
|
||||
<meta charset="utf-8"/>
|
||||
<title>Portail Admin</title>
|
||||
<link rel="stylesheet" type="text/css" media="all" href="css/style.css"/>
|
||||
<script src="js/jquery-1.7.2.min.js"></script>
|
||||
<script src="js/jquery-ui-1.8.21.custom.min.js"></script>
|
||||
<link rel="stylesheet" type="text/css" media="all" href="css/smoothness/jquery-ui-1.8.21.custom.css"/>
|
||||
<link rel="stylesheet" type="text/css" media="all" href="js/select2/select2.css"/>
|
||||
<script src="js/select2/select2.js"></script>
|
||||
<script src="js/mockups.js"></script>
|
||||
<script>
|
||||
function unselect_all() {
|
||||
$('.popover-container').css('display', 'none');
|
||||
$('table tbody tr').removeClass('active');
|
||||
$('table tbody tr input:checked').parents('tr').addClass('active');
|
||||
return true;
|
||||
}
|
||||
|
||||
$(function() {
|
||||
$('select').select2();
|
||||
$('#add-role-btn').click(function() {
|
||||
unselect_all();
|
||||
$('#role-add').dialog({title: 'Ajouter un rôle',
|
||||
width: '400px',
|
||||
modal: true,
|
||||
buttons: [
|
||||
{ text: "Annuler",
|
||||
click: function() { $(this).dialog("close"); } },
|
||||
{ text: "Ajouter",
|
||||
click: function() { $(this).dialog("close"); } }]}
|
||||
);
|
||||
return false;
|
||||
});
|
||||
$('ul.roles a').click(function() {
|
||||
unselect_all();
|
||||
$('ul.roles a').removeClass('active');
|
||||
$(this).addClass('active');
|
||||
$('div.big-msg-info').hide();
|
||||
$('div.role-info h3').text('Utilisateurs disposant du rôle : ' + $(this).text());
|
||||
$('div.role-info').show();
|
||||
return false;
|
||||
});
|
||||
|
||||
$('html').click(unselect_all);
|
||||
|
||||
$('table td:first-child').click(function(ev) {ev.stopPropagation();});
|
||||
$('table td:first-child input').change(function(ev) {
|
||||
ev.stopPropagation();
|
||||
$('.popover-container').css('display', 'none');
|
||||
if ($(this).prop('checked')) {
|
||||
$(this).prop('checked', true);
|
||||
$(this).parents('tr').addClass('active');
|
||||
} else {
|
||||
$(this).prop('checked', false);
|
||||
$(this).parents('tr').removeClass('active');
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
||||
$('table tbody tr').click(function(ev) {
|
||||
if ($(this).find('input:checked').length == 0) {
|
||||
$('table tbody tr input:checked').parents('tr').removeClass('active');
|
||||
$('table tbody tr input:checked').prop('checked', false);
|
||||
if ($(this).hasClass('active')) {
|
||||
$('.popover-container').css('display', 'none');
|
||||
$(this).removeClass('active');
|
||||
return false;
|
||||
}
|
||||
$('table tbody tr').removeClass('active');
|
||||
}
|
||||
$(this).addClass('active');
|
||||
$('.popover-container').css('visibility', 'hidden').css('display', 'block');
|
||||
$('.popover-container').css('left', ev.pageX - $('#content').offset().left - 20
|
||||
).css('top', ev.pageY - $('#content').offset().top +
|
||||
$('.popover').height() + 25
|
||||
).css('visibility', 'visible');
|
||||
return false;
|
||||
});
|
||||
|
||||
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="wrap-large">
|
||||
<div id="header">
|
||||
<h1><a href="accueil.html">Portail Admin</a></h1>
|
||||
</div>
|
||||
<div id="splash" class="cmpp">
|
||||
<div id="user-links">
|
||||
<a href="index.html">Déconnexion</a>
|
||||
</div>
|
||||
</div>
|
||||
<div id="more-user-links">
|
||||
<a href="accueil.html" class="icon-home-space">Accueil</a>
|
||||
</div>
|
||||
<div id="content">
|
||||
|
||||
<div id="appbar">
|
||||
<h2>Liste des rôles</h2>
|
||||
</div>
|
||||
|
||||
<div id="sidebar">
|
||||
<ul class="roles">
|
||||
<li><a href="#">Administrateur</a></li>
|
||||
<li><a href="#">Gestionnaire des annonces</a></li>
|
||||
<li><a href="#">Gestionnaire des rôles</a></li>
|
||||
<li><a href="#">Gestionnaire des sites communaux</a></li>
|
||||
<li><a href="#">Gestionnaire des textes</a></li>
|
||||
<li><a href="#">Gestionnaire des utilisateurs</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="content">
|
||||
|
||||
<div class="popover-container">
|
||||
<ul class="popover">
|
||||
<li><a>Retirer</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<div class="big-msg-info">
|
||||
Utilisez les filtres sur sur la gauche de l'écran pour afficher
|
||||
les membres du rôle correspondant.
|
||||
</div>
|
||||
|
||||
<div class="role-info" style="display: none;">
|
||||
<h3></h3>
|
||||
<table class="main">
|
||||
<thead>
|
||||
<tr>
|
||||
<th></th>
|
||||
<th>Nom d'utilisateur</th>
|
||||
<th>Email</th>
|
||||
<th>Prénom</th>
|
||||
<th>Nom</th>
|
||||
<th>Actif</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr><td class="checkbox"><input type="checkbox"/></td><td>foobar</td><td>foobar@example.net</td><td>Foo</td><td>Bar</td><td>×</td></tr>
|
||||
<tr><td class="checkbox"><input type="checkbox"/></td><td>foobar</td><td>foobar@example.net</td><td>Foo</td><td>Bar</td><td>×</td></tr>
|
||||
<tr><td class="checkbox"><input type="checkbox"/></td><td>foobar</td><td>foobar@example.net</td><td>Foo</td><td>Bar</td><td>×</td></tr>
|
||||
<tr><td class="checkbox"><input type="checkbox"/></td><td>foobar</td><td>foobar@example.net</td><td>Foo</td><td>Bar</td><td>×</td></tr>
|
||||
<tr><td class="checkbox"><input type="checkbox"/></td><td>foobar</td><td>foobar@example.net</td><td>Foo</td><td>Bar</td><td>×</td></tr>
|
||||
<tr><td class="checkbox"><input type="checkbox"/></td><td>foobar</td><td>foobar@example.net</td><td>Foo</td><td>Bar</td><td>×</td></tr>
|
||||
</tbody>
|
||||
|
||||
</table>
|
||||
|
||||
<form id="add-user-role">
|
||||
Ajouter un utilisateur à ce rôle :
|
||||
<select><option></option><option>foobar</option></select>
|
||||
<button>Valider</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div id="footer">
|
||||
Logiciel Portail Admin - Copyright © 2014 Entr'ouvert
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="role-edit" style="display: none;">
|
||||
<form>
|
||||
<label><span>Nom :</span> <input type="text" size="30" value="Foo"/></label></br>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div id="role-add" style="display: none;">
|
||||
<form>
|
||||
<label><span>Nom du rôle :</span> <input type="text" size="30"/></label></br>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,83 @@
|
|||
{% load i18n staticfiles %}<!DOCTYPE html>
|
||||
<html lang="fr">
|
||||
<head>
|
||||
<meta charset="utf-8"/>
|
||||
|
||||
<title>{% block title %}{% trans "Management" %}{% endblock %}</title>
|
||||
|
||||
<link rel="stylesheet" type="text/css" media="all" href="{% static "authentic2/manager/css/style.css" %}"/>
|
||||
|
||||
{% if debug %}
|
||||
<script src="http://code.jquery.com/jquery-1.11.1.js"></script>
|
||||
<script src="http://code.jquery.com/ui/1.10.4/jquery-ui.js"></script>
|
||||
<script src="{% static "jquery/js/jquery.form.js" %}"></script>
|
||||
<script src="{% static "jquery-ui-contextmenu-1.5.0/jquery.ui-contextmenu.js" %}"></script>
|
||||
{% else %}
|
||||
<script src="http://code.jquery.com/jquery-1.11.1.min.js"></script>
|
||||
<script src="http://code.jquery.com/ui/1.11.0/jquery-ui.min.js"></script>
|
||||
<script src="{% static "jquery/js/jquery.form.min.js" %}"></script>
|
||||
<script src="{% static "jquery-ui-contextmenu-1.5.0/jquery.ui-contextmenu.min.js" %}"></script>
|
||||
{% endif %}
|
||||
<script src="{% static "authentic2/js/purl.js" %}"></script>
|
||||
<script src="{% static "authentic2/manager/js/manager.js" %}"></script>
|
||||
<link rel="stylesheet" type="text/css" media="all" href="http://code.jquery.com/ui/1.10.4/themes/smoothness/jquery-ui.css"/>
|
||||
|
||||
{% block extra_scripts %}
|
||||
{% endblock %}
|
||||
</head>
|
||||
<body>
|
||||
<div id="wrap-large">
|
||||
<div id="header">
|
||||
{% block header %}<h1><a href="{{ management_homepage_url }}">{% trans "Management" %}</a></h1>{% endblock %}
|
||||
</div>
|
||||
|
||||
<div id="splash" class="cmpp">
|
||||
{% block splash %}
|
||||
<div id="user-links">
|
||||
{% block user-links %}
|
||||
<a href="{{ management_logout_url }}">{% trans "Logout" %}</a>
|
||||
{% endblock %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
{% if messages %}
|
||||
<ul class="messages">
|
||||
{% for message in messages %}
|
||||
<li{% if message.tags %} class="{{ message.tags }}"{% endif %}>
|
||||
{{ message }}
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<div id="more-user-links">
|
||||
{% block more-user-links %}
|
||||
<a href="{{ management_homepage_url }}" class="icon-home-space">{% trans "Homepage" %}</a>
|
||||
{% endblock %}
|
||||
</div>
|
||||
|
||||
<div id="content">
|
||||
<div id="appbar">
|
||||
{% block appbar %}
|
||||
<h2>{% block page_title %}{% endblock %}</h2>
|
||||
{% endblock %}
|
||||
</div>
|
||||
|
||||
<div id="sidebar">
|
||||
{% block sidebar %}
|
||||
{% endblock %}
|
||||
</div>
|
||||
|
||||
<div class="content">
|
||||
{% block content %}{% endblock %}
|
||||
</div>
|
||||
|
||||
<div id="footer">
|
||||
Authentic2 Manager - Copyright © 2014 Entr'ouvert
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% block end_content%}
|
||||
{% endblock %}
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,18 @@
|
|||
{% extends "authentic2/manager/base.html" %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block content %}
|
||||
<div id="content">
|
||||
{% if title %}
|
||||
<div id="appbar"><h2>{{ title }}</h2></div>
|
||||
{% endif %}
|
||||
<form method="post">
|
||||
{% csrf_token %}
|
||||
{{ form.as_p }}
|
||||
<div class="buttons">
|
||||
<button>{% trans "Create" %}</button>
|
||||
<a class="cancel" href="..">Annuler</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
{% endblock %}
|
|
@ -0,0 +1,85 @@
|
|||
{% extends "authentic2/manager/roles.html" %}
|
||||
{% load i18n staticfiles django_tables2 %}
|
||||
|
||||
{% block extra_scripts %}
|
||||
{{ block.super }}
|
||||
<script>
|
||||
$(function () {
|
||||
$('#search-input').change(function () {
|
||||
var params = $.url().param();
|
||||
if ($(this).val()) {
|
||||
params.search = $(this).val();
|
||||
} else {
|
||||
if ('search' in params) {
|
||||
delete params.search;
|
||||
}
|
||||
}
|
||||
var href = $.url().attr('path')
|
||||
if ($.param(params)) {
|
||||
href += '?' + $.param(params);
|
||||
}
|
||||
window.location.href = href;
|
||||
});
|
||||
$('#search-input-clear-btn').click(function () {
|
||||
$('#search-input').val('').trigger('change');
|
||||
});
|
||||
$('.content').on('click', '.paginator a', function () {
|
||||
var href = $(this).attr('href');
|
||||
$.get(href, '', function (response_text) {
|
||||
var content = $(response_text).find('.table-container');
|
||||
$('.table-container').replaceWith(content);
|
||||
history.pushState(null, href, href);
|
||||
setup_menu();
|
||||
});
|
||||
return false;
|
||||
});
|
||||
function remove_user(event, ui) {
|
||||
var user = $(ui.target).parent('tr').data('ref');
|
||||
if (! user) {
|
||||
return;
|
||||
}
|
||||
$.post('', {
|
||||
csrfmiddlewaretoken: '{{ csrf_token }}',
|
||||
action: 'remove',
|
||||
'user': user
|
||||
},
|
||||
function () {
|
||||
$.get('', function (html) {
|
||||
$('#user-table').replaceWith($(html).find('#user-table'));
|
||||
setup_menu();
|
||||
});
|
||||
}
|
||||
)
|
||||
}
|
||||
function setup_menu() {
|
||||
$('#user-table').contextmenu({
|
||||
delegate: 'tbody tr',
|
||||
menu: [
|
||||
{title: '{% trans "Remove" %}', action: remove_user}
|
||||
]
|
||||
});
|
||||
}
|
||||
setup_menu();
|
||||
|
||||
})
|
||||
</script>
|
||||
{{ choose_user_form.media }}
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="role-info">
|
||||
<h3>{% trans "Users with role" %}: {{ active_role.name }}</h3>
|
||||
<div id="search-form">
|
||||
{% trans "Search" %}: <input id="search-input" type="text" value="{{ request.GET.search }}"><button id="search-input-clear-btn">Effacer</button>
|
||||
</div>
|
||||
|
||||
{% render_table users "authentic2/manager/table.html" %}
|
||||
|
||||
<form method="post" id="add-user-role">
|
||||
Ajouter un utilisateur à ce rôle :
|
||||
{% csrf_token %}
|
||||
{{ choose_user_form }}
|
||||
<button>Valider</button>
|
||||
</form>
|
||||
</div>
|
||||
{% endblock %}
|
|
@ -0,0 +1,55 @@
|
|||
{% extends "authentic2/manager/base.html" %}
|
||||
{% load i18n staticfiles %}
|
||||
|
||||
{% block title %}{{ block.super }} - {% trans "Role management" %}{% endblock %}
|
||||
|
||||
{% block page_title %}{% trans "Role management" %}{% endblock %}
|
||||
|
||||
{% block extra_scripts %}
|
||||
<script>
|
||||
$(function () {
|
||||
function refresh_page() {
|
||||
$.get('', '', function (response_text) {
|
||||
$('#sidebar').replaceWith($(response_text).find('#sidebar'));
|
||||
});
|
||||
};
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
||||
{% block sidebar %}
|
||||
<ul class="roles">
|
||||
{% for role in roles %}
|
||||
<li>
|
||||
<a href="{% url "a2-manager-role" role_ref=role.ref %}"
|
||||
{% if role.ref == active_role.ref %}class="active"{% endif %}>
|
||||
{{ role.name }}
|
||||
</a>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
<a href="{% url "a2-manager-role-add" %}" rel="popup">{% trans "Add role" %}</a>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="big-msg-info">
|
||||
Utilisez les filtres sur sur la gauche de l'écran pour afficher
|
||||
les membres du rôle correspondant.
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block end_content %}
|
||||
<div id="role-edit" style="display: none;">
|
||||
<form>
|
||||
<label><span>Nom :</span> <input type="text" size="30" value="Foo"/></label></br>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div id="role-add" style="display: none;">
|
||||
<form id="role-add-form" method="post" action="{% url "a2-manager-role-add" %}">
|
||||
{% csrf_token %}
|
||||
{{ role_add_form }}
|
||||
</form>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
|
@ -0,0 +1,40 @@
|
|||
{% extends "django_tables2/table.html" %}
|
||||
|
||||
{% load django_tables2 %}
|
||||
|
||||
{% block table.tbody.row %}
|
||||
<tr data-ref="{{ row.record.id }}" class="{{ forloop.counter|divisibleby:2|yesno:"even,odd" }}"> {# avoid cycle for Django 1.2-1.6 compatibility #}
|
||||
{% for column, cell in row.items %}
|
||||
<td {{ column.attrs.td.as_html }}>{% if column.localize == None %}{{ cell }}{% else %}{% if column.localize %}{{ cell|localize }}{% else %}{{ cell|unlocalize }}{% endif %}{% endif %}</td>
|
||||
{% endfor %}
|
||||
</tr>
|
||||
{% endblock table.tbody.row %}
|
||||
|
||||
{% block pagination %}
|
||||
<p class="paginator">
|
||||
{% if table.page.number > 1 %}
|
||||
{% if table.page.previous_page_number != 1 %}
|
||||
<a href="{% querystring table.prefixed_page_field=1 %}">1</a>
|
||||
...
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
{% if table.page.has_previous %}
|
||||
<a href="{% querystring table.prefixed_page_field=table.page.previous_page_number %}">{{ table.page.previous_page_number }}</a>
|
||||
{% endif %}
|
||||
|
||||
<span class="this-page">{{ table.page.number }}</span>
|
||||
|
||||
{% if table.page.has_next %}
|
||||
<a href="{% querystring table.prefixed_page_field=table.page.next_page_number %}">{{ table.page.next_page_number }}</a>
|
||||
{% endif %}
|
||||
{% if table.page.number != table.page.paginator.num_pages %}
|
||||
{% if table.page.paginator.num_pages > 1 %}
|
||||
{% if table.page.next_page_number != table.page.paginator.num_pages %}
|
||||
...
|
||||
<a href="{% querystring table.prefixed_page_field=table.page.paginator.num_pages %}">{{ table.page.paginator.num_pages }}</a>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
</p>
|
||||
{% endblock %}
|
|
@ -0,0 +1,10 @@
|
|||
from django.conf.urls import patterns, url, include
|
||||
|
||||
from . import views
|
||||
|
||||
urlpatterns = patterns('authentic2.views',
|
||||
url(r'^roles/$', views.roles, name='a2-manager-roles'),
|
||||
url(r'^roles/add/$', views.role_add, name='a2-manager-role-add'),
|
||||
url(r'^roles/(?P<role_ref>[^/]*)/$', views.role, name='a2-manager-role'),
|
||||
url(r'^', include('django_select2.urls')),
|
||||
)
|
|
@ -0,0 +1,44 @@
|
|||
from django.contrib.auth.models import Group, User
|
||||
from django.db.models.query import Q
|
||||
|
||||
|
||||
class Role(object):
|
||||
def __init__(self, name, ref):
|
||||
self.name = name
|
||||
self.ref = ref
|
||||
|
||||
class RoleUser(Role):
|
||||
pass
|
||||
|
||||
|
||||
def get_roles():
|
||||
return [Role(g.name, g.id) for g in Group.objects.order_by('name')]
|
||||
|
||||
def get_role(ref):
|
||||
g = Group.objects.get(id=ref)
|
||||
return Role(g.name, g.id)
|
||||
|
||||
def filter_user(qs, search):
|
||||
return qs.filter(Q(username__contains=search)
|
||||
| Q(first_name__contains=search)
|
||||
| Q(last_name__contains=search)
|
||||
| Q(email__contains=search))
|
||||
|
||||
def get_role_users(role, search=None):
|
||||
qs = User.objects.filter(groups__id=role.ref)
|
||||
if search:
|
||||
qs = filter_user(qs, search)
|
||||
return qs
|
||||
|
||||
def role_add(name):
|
||||
g, created = Group.objects.get_or_create(name=name)
|
||||
return g.id
|
||||
|
||||
def search_user(term):
|
||||
return [RoleUser(u.get_full_name(), u.id) for u in filter_user(User.objects.all(), term)[:10]]
|
||||
|
||||
def add_user_to_role(role, user):
|
||||
User.objects.get(id=user).groups.add(Group.objects.get(id=role.ref))
|
||||
|
||||
def remove_user_from_role(role, user):
|
||||
User.objects.get(id=user).groups.remove(Group.objects.get(id=role.ref))
|
|
@ -0,0 +1,101 @@
|
|||
import json
|
||||
|
||||
from django.views.generic import TemplateView, FormView
|
||||
from django.http import HttpResponse, HttpResponseRedirect
|
||||
from django.shortcuts import redirect
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from django_tables2 import RequestConfig
|
||||
|
||||
from . import app_settings, utils, tables, forms
|
||||
|
||||
class ManagerMixin(object):
|
||||
def get_context_data(self, **kwargs):
|
||||
ctx = super(ManagerMixin, self).get_context_data(**kwargs)
|
||||
ctx['management_homepage_url'] = app_settings.HOMEPAGE_URL or '/'
|
||||
ctx['management_logout_url'] = app_settings.LOGOUT_URL or '/accounts/logout'
|
||||
return ctx
|
||||
|
||||
class RolesMixin(ManagerMixin):
|
||||
def get_context_data(self, **kwargs):
|
||||
ctx = super(ManagerMixin, self).get_context_data(**kwargs)
|
||||
ctx['roles'] = utils.get_roles()
|
||||
ctx['role_add_form'] = forms.RoleAddForm()
|
||||
return ctx
|
||||
|
||||
class AjaxFormViewMixin(object):
|
||||
template_name = 'authentic2/manager/form.html'
|
||||
success_url = '.'
|
||||
|
||||
def form_valid(self, form):
|
||||
if hasattr(form, 'save'):
|
||||
self.form_result = form.save()
|
||||
return super(AjaxFormViewMixin, self).form_valid(form)
|
||||
|
||||
def dispatch(self, request, *args, **kwargs):
|
||||
response = super(AjaxFormViewMixin, self).dispatch(request, *args, **kwargs)
|
||||
if not request.is_ajax():
|
||||
return response
|
||||
data = {}
|
||||
if 'Location' in response:
|
||||
data['location'] = response['Location']
|
||||
if hasattr(response, 'render'):
|
||||
response.render()
|
||||
data['content'] = response.content
|
||||
return HttpResponse(json.dumps(data), content_type='application/json')
|
||||
|
||||
class RolesView(RolesMixin, TemplateView):
|
||||
template_name = 'authentic2/manager/roles.html'
|
||||
|
||||
class TitleMixin(object):
|
||||
title = None
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
ctx = super(TitleMixin, self).get_context_data(**kwargs)
|
||||
if self.title:
|
||||
ctx['title'] = self.title
|
||||
return ctx
|
||||
|
||||
class RoleAddView(TitleMixin, AjaxFormViewMixin, FormView):
|
||||
form_class = forms.RoleAddForm
|
||||
title = _('Add new role')
|
||||
|
||||
def form_valid(self, form):
|
||||
super(RoleAddView, self).form_valid(form)
|
||||
return redirect('a2-manager-role', role_ref=self.form_result)
|
||||
|
||||
|
||||
|
||||
class RoleView(RolesMixin, TemplateView):
|
||||
template_name = 'authentic2/manager/role.html'
|
||||
|
||||
def get_role(self):
|
||||
return utils.get_role(self.kwargs['role_ref'])
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
ctx = super(RoleView, self).get_context_data(**kwargs)
|
||||
ctx['active_role'] = self.get_role()
|
||||
kwargs = {}
|
||||
if 'search' in self.request.GET:
|
||||
kwargs = {'search': self.request.GET['search']}
|
||||
users = utils.get_role_users(ctx['active_role'], **kwargs)
|
||||
table = tables.UserTable(users)
|
||||
RequestConfig(self.request).configure(table)
|
||||
ctx['users'] = table
|
||||
ctx['choose_user_form'] = forms.ChooseUserForm()
|
||||
return ctx
|
||||
|
||||
def post(self, request, *args, **kwargs):
|
||||
role = self.get_role()
|
||||
ref = request.POST.get('user')
|
||||
if ref:
|
||||
action = request.POST.get('action', 'add')
|
||||
if action == 'add':
|
||||
utils.add_user_to_role(role, ref)
|
||||
elif action == 'remove':
|
||||
utils.remove_user_from_role(role, ref)
|
||||
return HttpResponseRedirect('')
|
||||
|
||||
roles = RolesView.as_view()
|
||||
role_add = RoleAddView.as_view()
|
||||
role = RoleView.as_view()
|
|
@ -173,6 +173,8 @@ INSTALLED_APPS = (
|
|||
'admin_tools.dashboard',
|
||||
'django.contrib.admin',
|
||||
'registration',
|
||||
'django_select2',
|
||||
'django_tables2',
|
||||
'authentic2.nonce',
|
||||
'authentic2.saml',
|
||||
'authentic2.idp',
|
||||
|
@ -180,6 +182,7 @@ INSTALLED_APPS = (
|
|||
'authentic2.auth2_auth',
|
||||
'authentic2.attribute_aggregator',
|
||||
'authentic2.disco_service',
|
||||
'authentic2.manager',
|
||||
'authentic2',
|
||||
)
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@ not_homepage_patterns += patterns('',
|
|||
url(r'^admin/', include(admin.site.urls)),
|
||||
url(r'^admin_tools/', include('admin_tools.urls')),
|
||||
url(r'^idp/', include('authentic2.idp.urls')),
|
||||
url(r'^manager/', include('authentic2.manager.urls')),
|
||||
)
|
||||
|
||||
if getattr(settings, 'AUTH_OPENID', False):
|
||||
|
|
|
@ -8,3 +8,5 @@ django-debug-toolbar<1.0.0
|
|||
--allow-unverified django-admin-tools
|
||||
django-admin-tools>=0.5.1
|
||||
dnspython
|
||||
django-select2
|
||||
django-tables2
|
||||
|
|
Loading…
Reference in New Issue