Skip to content
Permalink
Browse files

document users; add email field

Signed-off-by: Chris Warrick <kwpolska@gmail.com>
  • Loading branch information
Kwpolska committed Jan 11, 2015
1 parent f970ac6 commit cfb2ba438cddb8b2acb96f1f8ae69664b69a10e0
@@ -21,10 +21,13 @@
<h3 class="panel-title">Profile</h3>
</div>
<div class="panel-body">

<div class="form-group">
<label for="name" class="col-sm-2 control-label">Real name</label>
<div class="col-sm-10"><input class="form-control" id="realname" name="realname" value="${current_user.realname}" placeholder="Real name"></div>
<div class="col-sm-10"><input class="form-control" id="realname" name="realname" value="${current_user.realname}" placeholder="Real name" required></div>
</div>
<div class="form-group">
<label for="name" class="col-sm-2 control-label">E-mail address</label>
<div class="col-sm-10"><input class="form-control" id="email" name="email" type="email" value="${current_user.email}" placeholder="E-mail address" required></div>
</div>
<div class="form-group">
<label for="oldpwd" class="col-sm-2 control-label">Old password</label>
@@ -19,12 +19,12 @@ $('#deleteModal').on('show.bs.modal', function (event) {
modal.find('.del-noun').text('deletion');
modal.find('.del-verb').text('delete');
modal.find('.del-verb-capital').text('Delete');
modal.find('.del-verb-capital').addClass('btn-danger');
modal.find('.del-verb-capital').addClass('btn btn-sm-danger');
} else {
modal.find('.del-noun').text('undeletion');
modal.find('.del-verb').text('undelete');
modal.find('.del-verb-capital').text('Undelete');
modal.find('.del-verb-capital').addClass('btn-success');
modal.find('.del-verb-capital').addClass('btn btn-sm-success');
}
});
</script>
@@ -43,6 +43,7 @@ $('#deleteModal').on('show.bs.modal', function (event) {
<th class="uid">#</th>
<th class="username">Username</th>
<th class="realname">Real name</th>
<th class="email">E-mail address</th>
<th class="is_admin">Admin</th>
<th class="actions">Actions</th>
</tr></thead>
@@ -55,6 +56,7 @@ $('#deleteModal').on('show.bs.modal', function (event) {
<td class="uid">${uid}</td>
<td class="username">${user.username}</td>
<td class="realname">${user.realname}</td>
<td class="email">${user.email}</td>
<td class="actions">
% if user.is_admin:
<i class="fa fa-check"></i>
@@ -68,15 +70,15 @@ $('#deleteModal').on('show.bs.modal', function (event) {
<input type="hidden" name="action" value="edit">
<div class="btn-group" role="group">
% if user.active:
<button type="submit" class="btn btn-info" title="Edit"><i class="fa fa-pencil fa-fw"></i> Edit</button>
% if user == current_user:
<button type="button" class="btn btn-danger" title="Delete" disabled><i class="fa fa-trash fa-fw"></i> Delete</button>
<button type="submit" class="btn btn-sm btn-info" title="Edit"><i class="fa fa-pencil fa-fw"></i> Edit</button>
% if user.uid == current_user.uid:
<button type="button" class="btn btn-sm btn-danger" title="Delete" disabled><i class="fa fa-trash fa-fw"></i> Delete</button>
% else:
<button type="button" class="btn btn-danger" data-toggle="modal" data-target="#deleteModal" data-username="${user.username}" data-uid="${uid}" data-direction="del" title="Delete"><i class="fa fa-trash fa-fw"></i> Delete</button>
<button type="button" class="btn btn-sm btn-danger" data-toggle="modal" data-target="#deleteModal" data-username="${user.username}" data-uid="${uid}" data-direction="del" title="Delete"><i class="fa fa-trash fa-fw"></i> Delete</button>
% endif
% else:
<button type="button" class="btn btn-info" title="Edit" disabled><i class="fa fa-pencil fa-fw"></i> Edit</button>
<button type="button" class="btn btn-success" data-toggle="modal" data-target="#deleteModal" data-username="${user.username}" data-uid="${uid}" data-direction="undel" title="Undelete"><i class="fa fa-trash-o fa-fw"></i> Undelete</button>
<button type="button" class="btn btn-sm btn-info" title="Edit" disabled><i class="fa fa-pencil fa-fw"></i> Edit</button>
<button type="button" class="btn btn-sm btn-success" data-toggle="modal" data-target="#deleteModal" data-username="${user.username}" data-uid="${uid}" data-direction="undel" title="Undelete"><i class="fa fa-trash-o fa-fw"></i> Undelete</button>
% endif
</div>
</form>
@@ -87,7 +89,8 @@ $('#deleteModal').on('show.bs.modal', function (event) {
<td><input name="username" placeholder="New user" class="form-control"></td>
<td><input name="action" value="new" type="hidden"></td>
<td></td>
<td><button type="submit" class="btn btn-primary"><i class="fa fa-plus-square fa-fw"></i> Create</button></td>
<td></td>
<td><button type="submit" class="btn btn-sm btn-primary"><i class="fa fa-plus-square fa-fw"></i> Create</button></td>
</form></tr>
</table>

@@ -105,7 +108,7 @@ $('#deleteModal').on('show.bs.modal', function (event) {
<form method="POST" action="/users/delete" class="delete-button">
<input type="hidden" name="uid" class="del-uid">
<input type="hidden" name="direction" class="del-direction">
<button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
<button type="button" class="btn btn btn-sm-default" data-dismiss="modal">Cancel</button>
<button type="submit" class="btn del-verb-capital">Delete</button>
</div>
</div>
@@ -36,6 +36,10 @@
<label for="name" class="col-sm-2 control-label">Real name</label>
<div class="col-sm-10"><input class="form-control" id="realname" name="realname" value="${user.realname}" placeholder="Real name" required></div>
</div>
<div class="form-group">
<label for="name" class="col-sm-2 control-label">E-mail address</label>
<div class="col-sm-10"><input class="form-control" id="email" name="email" type="email" value="${user.email}" placeholder="E-mail address" required></div>
</div>
% if user.password:
<div class="form-group">
<label for="newpwd1" class="col-sm-2 control-label">New password</label>
@@ -85,7 +89,7 @@
% if user.is_admin:
checked
% endif
% if user == current_user:
% if user.uid == current_user.uid:
disabled
% endif
> User is an administrator
@@ -11,14 +11,16 @@ $(document).ready(function() {

for (var i = 0; i < PERMISSIONS.length; i++) {
var p = PERMISSIONS[i];
// .active is significant in Bootstrap, so we're changing the name here
if (p == 'active') { p = 'is_active'; }
$('th.' + p + ' button.select_all-perm').click(function() {
p = this.attributes['data-perm'].value;
$('.' + p + ' input').each(function() { this.checked = true; });
});
$('th.' + p + ' button.select_none-perm').click(function() {
p = this.attributes['data-perm'].value;
$('.' + p + ' input').each(function() {
if (p != 'is_admin' || this.attributes['data-uid'].value != ${current_user.uid}) {
if ((p != 'is_admin' && p != 'is_active') || this.attributes['data-uid'].value != ${current_user.uid}) {
this.checked = false;
}
});
@@ -34,7 +36,7 @@ $(document).ready(function() {
$('.u' + uid + ' button.select_none-user').click(function() {
uid = this.attributes['data-uid'].value;
$('input.u' + uid).each(function() {
if (uid != current_uid || this.attributes['data-perm'].value != 'is_admin') { this.checked = false; }
if (uid != current_uid || ((this.attributes['data-perm'].value != 'is_admin') && (this.attributes['data-perm'].value != 'is_active'))) { this.checked = false; }
});
});
}
@@ -32,10 +32,10 @@

__all__ = ['PERMISSIONS', 'USER_FIELDS', 'USER_ALL', 'parse_redis', 'ask', 'ask_yesno']

USER_FIELDS = ['username', 'realname', 'password', 'email']
PERMISSIONS = ['active', 'is_admin', 'can_edit_all_posts', 'wants_all_posts',
'can_upload_attachments', 'can_rebuild_site',
'can_transfer_post_authorship']
USER_FIELDS = ['username', 'realname', 'password',]
USER_ALL = USER_FIELDS + PERMISSIONS


@@ -306,15 +306,16 @@ def log_request(resp):

class User(object):
"""An user. Compatible with Flask-Login."""
def __init__(self, uid, username, realname, password, active, is_admin,
can_edit_all_posts, wants_all_posts,
def __init__(self, uid, username, realname, password, email, active,
is_admin, can_edit_all_posts, wants_all_posts,
can_upload_attachments, can_rebuild_site,
can_transfer_post_authorship):
"""Initialize an user with specified settings."""
self.uid = int(uid)
self.username = username
self.realname = realname
self.password = password
self.email = email
self.active = active
self.is_admin = is_admin
self.can_edit_all_posts = can_edit_all_posts
@@ -665,6 +666,7 @@ def acp_user_account():
alert_status = 'danger'
action = 'save_fail'
current_user.realname = data['realname']
current_user.email = data['email']
current_user.wants_all_posts = 'wants_all_posts' in data
write_user(current_user)

@@ -750,6 +752,7 @@ def acp_users_edit():
user.username = data['username']
db.hset('users', user.username, user.uid)
user.realname = data['realname']
user.email = data['email']
for p in PERMISSIONS:
setattr(user, p, p in data)
user.active = True
@@ -806,6 +809,7 @@ def acp_users_permissions():
setattr(user, perm, False)
if uid == current_user.uid:
user.is_admin = True # cannot deadmin oneself
user.active = True # cannot deactivate oneself
write_user(user)
users[uid] = user
action = 'save'
@@ -821,9 +825,12 @@ def display_permission(user, permission):
disabled = 'disabled'
else:
disabled = ''
permission_a = permission
if permission == 'active':
permission_a = 'is_active'
d = ('<input type="checkbox" name="{0}.{1}" data-uid="{0}" '
'data-perm="{1}" class="u{0}" {2} {3}>')
return d.format(user.uid, permission, checked, disabled)
'data-perm="{4}" class="u{0}" {2} {3}>')
return d.format(user.uid, permission, checked, disabled, permission_a)

for uid in range(1, last_uid + 1):
users[uid] = get_user(uid)
@@ -0,0 +1,79 @@
=====
Users
=====

.. index:: users

.. contents::

Users of Comet are stored in the Redis database.

Information stored
==================

The following data about users is stored:

Profile
-------

============ ============== =======================================
Name In Account Notes
============ ============== =======================================
``username`` Username Used to log in
``realname`` Real name Prominently displayed on posts
``email`` E-mail address Used by administrators to contact users
``password`` Password Hashed and salted using bcrypt
============ ============== =======================================

Preferences
-----------

================== ======================================= ==============
Name In Account In Permissions
================== ======================================= ==============
``want_all_posts`` Show me posts of other users by default Want all posts
================== ======================================= ==============

Permissions
-----------

Comet uses a very granular permission system. Each user can have a different
set of permissions, depending on the needs of the organization.

================================ ============================= ===================
Name In Account In Permissions
================================ ============================= ===================
``active`` n/a Active
``is_admin`` User is an administrator Admin
``can_edit_all_posts`` Can edit posts of other users Can all posts
``can_upload_attachments`` Can upload attachments Attachments
``can_rebuild_site`` Can rebuild the site Rebuild
``can_transfer_post_authorship`` Can transfer post authorship Transfer authorship
================================ ============================= ===================

Managing users and permissions
==============================

All administrators (people with the ``is_admin`` permission) get access to user
management views, accessible from the user menu. They are:

Manage users
------------

This is a table of all users. You can add new users at the bottom by typing in
a name and clicking *Create*. You can also *Edit*, *Delete* or *Undelete*.

Deleting and undeleting users
`````````````````````````````

Even when you press the *Delete* button, the user stays in the database. You can then *Undelete* them if you change your mind.

You could delete the user straight from Redis, but this is **not recommended** and
can have unexpected side effects.

Permissions
-----------

This is a table of all permissions in the system. It can be used to quickly
modify the permission list for groups of users. The teal buttons can be used
to select the permission for all users.

0 comments on commit cfb2ba4

Please sign in to comment.
You can’t perform that action at this time.