More standalone operation stuff.
Stop using `edbob.db.engine`, stop using all edbob templates, etc.
This commit is contained in:
parent
2a50e704ef
commit
7d19700c3c
|
@ -31,7 +31,7 @@ from pyramid.config import Configurator
|
||||||
import os.path
|
import os.path
|
||||||
import edbob
|
import edbob
|
||||||
|
|
||||||
import edbob.db
|
from sqlalchemy import engine_from_config
|
||||||
from .db import Session
|
from .db import Session
|
||||||
from zope.sqlalchemy import ZopeTransactionExtension
|
from zope.sqlalchemy import ZopeTransactionExtension
|
||||||
|
|
||||||
|
@ -55,12 +55,11 @@ def main(global_config, **settings):
|
||||||
|
|
||||||
# Initialize edbob, dammit.
|
# Initialize edbob, dammit.
|
||||||
edbob.init('rattail', os.path.abspath(settings['edbob.config']))
|
edbob.init('rattail', os.path.abspath(settings['edbob.config']))
|
||||||
edbob.init_modules(['edbob.time', 'edbob.db', 'rattail.db'])
|
edbob.init_modules(['edbob.time'])
|
||||||
|
|
||||||
# Configure the primary database session. For now, this leverages edbob's
|
# Configure the primary database session.
|
||||||
# initialization to define the engine connection.
|
engine = engine_from_config(settings)
|
||||||
assert edbob.db.engine
|
Session.configure(bind=engine)
|
||||||
Session.configure(bind=edbob.db.engine)
|
|
||||||
Session.configure(extension=ZopeTransactionExtension())
|
Session.configure(extension=ZopeTransactionExtension())
|
||||||
|
|
||||||
# Configure user authentication / authorization.
|
# Configure user authentication / authorization.
|
||||||
|
|
|
@ -32,7 +32,7 @@ from pyramid.security import Everyone, Authenticated
|
||||||
|
|
||||||
from .db import Session
|
from .db import Session
|
||||||
from rattail.db.model import User
|
from rattail.db.model import User
|
||||||
from edbob.db.auth import has_permission
|
from rattail.db.auth import has_permission
|
||||||
|
|
||||||
|
|
||||||
@implementer(IAuthorizationPolicy)
|
@implementer(IAuthorizationPolicy)
|
||||||
|
@ -43,9 +43,9 @@ class TailboneAuthorizationPolicy(object):
|
||||||
if userid not in (Everyone, Authenticated):
|
if userid not in (Everyone, Authenticated):
|
||||||
user = Session.query(User).get(userid)
|
user = Session.query(User).get(userid)
|
||||||
assert user
|
assert user
|
||||||
return has_permission(user, permission)
|
return has_permission(Session(), user, permission)
|
||||||
if Everyone in principals:
|
if Everyone in principals:
|
||||||
return has_permission(None, permission, session=Session())
|
return has_permission(Session(), None, permission)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def principals_allowed_by_permission(self, context, permission):
|
def principals_allowed_by_permission(self, context, permission):
|
||||||
|
|
34
tailbone/static/css/login.css
Normal file
34
tailbone/static/css/login.css
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
|
||||||
|
/******************************
|
||||||
|
* login.css
|
||||||
|
******************************/
|
||||||
|
|
||||||
|
#logo {
|
||||||
|
margin: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.form {
|
||||||
|
margin: auto;
|
||||||
|
float: none;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.field-wrapper {
|
||||||
|
margin: 10px auto;
|
||||||
|
width: 300px;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.field-wrapper label {
|
||||||
|
margin: 0px;
|
||||||
|
padding-top: 3px;
|
||||||
|
text-align: right;
|
||||||
|
width: 100px;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.field-wrapper input {
|
||||||
|
width: 150px;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.buttons input {
|
||||||
|
margin: auto 5px;
|
||||||
|
}
|
24
tailbone/static/js/login.js
Normal file
24
tailbone/static/js/login.js
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
|
||||||
|
$(function() {
|
||||||
|
|
||||||
|
$('form').submit(function() {
|
||||||
|
if (! $('#username').val()) {
|
||||||
|
with ($('#username').get(0)) {
|
||||||
|
select();
|
||||||
|
focus();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (! $('#password').val()) {
|
||||||
|
with ($('#password').get(0)) {
|
||||||
|
select();
|
||||||
|
focus();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#username').focus();
|
||||||
|
|
||||||
|
});
|
|
@ -105,6 +105,13 @@ $(function() {
|
||||||
autoExpand: true
|
autoExpand: true
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Fix buttons.
|
||||||
|
*/
|
||||||
|
$('button').button();
|
||||||
|
$('input[type=submit]').button();
|
||||||
|
$('input[type=reset]').button();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* When filter labels are clicked, (un)check the associated checkbox.
|
* When filter labels are clicked, (un)check the associated checkbox.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -33,7 +33,7 @@ from . import helpers
|
||||||
from pyramid.security import authenticated_userid
|
from pyramid.security import authenticated_userid
|
||||||
from .db import Session
|
from .db import Session
|
||||||
from rattail.db.model import User
|
from rattail.db.model import User
|
||||||
from edbob.db.auth import has_permission
|
from rattail.db.auth import has_permission
|
||||||
|
|
||||||
|
|
||||||
def before_render(event):
|
def before_render(event):
|
||||||
|
@ -70,12 +70,12 @@ def context_found(event):
|
||||||
request.user = Session.query(User).get(uuid)
|
request.user = Session.query(User).get(uuid)
|
||||||
|
|
||||||
def has_perm(perm):
|
def has_perm(perm):
|
||||||
return has_permission(request.user, perm, session=Session())
|
return has_permission(Session(), request.user, perm)
|
||||||
request.has_perm = has_perm
|
request.has_perm = has_perm
|
||||||
|
|
||||||
def has_any_perm(perms):
|
def has_any_perm(perms):
|
||||||
for perm in perms:
|
for perm in perms:
|
||||||
if has_permission(request.user, perm, session=Session()):
|
if has_permission(Session(), request.user, perm):
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
request.has_any_perm = has_any_perm
|
request.has_any_perm = has_any_perm
|
||||||
|
|
13
tailbone/templates/form.mako
Normal file
13
tailbone/templates/form.mako
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
<%inherit file="/base.mako" />
|
||||||
|
|
||||||
|
<%def name="context_menu_items()"></%def>
|
||||||
|
|
||||||
|
<div class="form-wrapper">
|
||||||
|
|
||||||
|
<ul class="context-menu">
|
||||||
|
${self.context_menu_items()}
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
${form.render()|n}
|
||||||
|
|
||||||
|
</div>
|
39
tailbone/templates/forms/fieldset.mako
Normal file
39
tailbone/templates/forms/fieldset.mako
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
<% _focus_rendered = False %>
|
||||||
|
|
||||||
|
% for error in fieldset.errors.get(None, []):
|
||||||
|
<div class="fieldset-error">${error}</div>
|
||||||
|
% endfor
|
||||||
|
|
||||||
|
% for field in fieldset.render_fields.itervalues():
|
||||||
|
|
||||||
|
% if field.requires_label:
|
||||||
|
<div class="field-wrapper ${field.name}">
|
||||||
|
% for error in field.errors:
|
||||||
|
<div class="field-error">${error}</div>
|
||||||
|
% endfor
|
||||||
|
${field.label_tag()|n}
|
||||||
|
<div class="field">
|
||||||
|
${field.render()|n}
|
||||||
|
</div>
|
||||||
|
% if 'instructions' in field.metadata:
|
||||||
|
<span class="instructions">${field.metadata['instructions']}</span>
|
||||||
|
% endif
|
||||||
|
</div>
|
||||||
|
|
||||||
|
% if not _focus_rendered and (fieldset.focus == field or fieldset.focus is True):
|
||||||
|
% if not field.is_readonly() and getattr(field.renderer, 'needs_focus', True):
|
||||||
|
<script language="javascript" type="text/javascript">
|
||||||
|
$(function() {
|
||||||
|
% if hasattr(field.renderer, 'focus_name'):
|
||||||
|
$('#${field.renderer.focus_name}').focus();
|
||||||
|
% else:
|
||||||
|
$('#${field.renderer.name}').focus();
|
||||||
|
% endif
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
<% _focus_rendered = True %>
|
||||||
|
% endif
|
||||||
|
% endif
|
||||||
|
% endif
|
||||||
|
|
||||||
|
% endfor
|
12
tailbone/templates/forms/fieldset_readonly.mako
Normal file
12
tailbone/templates/forms/fieldset_readonly.mako
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
<div class="fieldset">
|
||||||
|
% for field in fieldset.render_fields.itervalues():
|
||||||
|
% if field.requires_label:
|
||||||
|
<div class="field-wrapper ${field.name}">
|
||||||
|
${field.label_tag()|n}
|
||||||
|
<div class="field">
|
||||||
|
${field.render_readonly()}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
% endif
|
||||||
|
% endfor
|
||||||
|
</div>
|
15
tailbone/templates/forms/form.mako
Normal file
15
tailbone/templates/forms/form.mako
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
<div class="form">
|
||||||
|
${h.form(form.action_url, enctype='multipart/form-data')}
|
||||||
|
|
||||||
|
${form.fieldset.render()|n}
|
||||||
|
|
||||||
|
<div class="buttons">
|
||||||
|
${h.submit('create', form.create_label if form.creating else form.update_label)}
|
||||||
|
% if form.creating and form.allow_successive_creates:
|
||||||
|
${h.submit('create_and_continue', form.successive_create_label)}
|
||||||
|
% endif
|
||||||
|
<button type="button" onclick="location.href = '${form.cancel_url}';">Cancel</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
${h.end_form()}
|
||||||
|
</div>
|
3
tailbone/templates/forms/form_readonly.mako
Normal file
3
tailbone/templates/forms/form_readonly.mako
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
<div class="form">
|
||||||
|
${form.fieldset.render()|n}
|
||||||
|
</div>
|
37
tailbone/templates/grid.mako
Normal file
37
tailbone/templates/grid.mako
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
<%inherit file="/base.mako" />
|
||||||
|
|
||||||
|
<%def name="context_menu_items()"></%def>
|
||||||
|
|
||||||
|
<%def name="form()">
|
||||||
|
% if search:
|
||||||
|
${search.render()}
|
||||||
|
% else:
|
||||||
|
|
||||||
|
% endif
|
||||||
|
</%def>
|
||||||
|
|
||||||
|
<%def name="tools()"></%def>
|
||||||
|
|
||||||
|
<div class="grid-wrapper">
|
||||||
|
|
||||||
|
<table class="grid-header">
|
||||||
|
<tr>
|
||||||
|
<td rowspan="2" class="form">
|
||||||
|
${self.form()}
|
||||||
|
</td>
|
||||||
|
<td class="context-menu">
|
||||||
|
<ul>
|
||||||
|
${self.context_menu_items()}
|
||||||
|
</ul>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="tools">
|
||||||
|
${self.tools()}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table><!-- grid-header -->
|
||||||
|
|
||||||
|
${grid}
|
||||||
|
|
||||||
|
</div><!-- grid-wrapper -->
|
36
tailbone/templates/grids/search.mako
Normal file
36
tailbone/templates/grids/search.mako
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
<div class="filters" url="${search.request.current_route_url()}">
|
||||||
|
${search.begin()}
|
||||||
|
${search.hidden('filters', 'true')}
|
||||||
|
<% visible = [] %>
|
||||||
|
% for f in search.sorted_filters():
|
||||||
|
<div class="filter" id="filter-${f.name}"${' style="display: none;"' if not search.config.get('include_filter_'+f.name) else ''|n}>
|
||||||
|
${search.checkbox('include_filter_'+f.name)}
|
||||||
|
<label for="${f.name}">${f.label}</label>
|
||||||
|
${f.types_select()}
|
||||||
|
<div class="value">
|
||||||
|
${f.value_control()}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
% if search.config.get('include_filter_'+f.name):
|
||||||
|
<% visible.append(f.name) %>
|
||||||
|
% endif
|
||||||
|
% endfor
|
||||||
|
<div class="buttons">
|
||||||
|
${search.add_filter(visible)}
|
||||||
|
${search.submit('submit', "Search", style='display: none;' if not visible else None)}
|
||||||
|
<button type="reset"${' style="display: none;"' if not visible else ''|n}>Reset</button>
|
||||||
|
</div>
|
||||||
|
${search.end()}
|
||||||
|
% if visible:
|
||||||
|
<script language="javascript" type="text/javascript">
|
||||||
|
filters_to_disable = [
|
||||||
|
% for field in visible:
|
||||||
|
'${field}',
|
||||||
|
% endfor
|
||||||
|
];
|
||||||
|
$(function() {
|
||||||
|
disable_filter_options();
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
% endif
|
||||||
|
</div>
|
37
tailbone/templates/login.mako
Normal file
37
tailbone/templates/login.mako
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
<%inherit file="/base.mako" />
|
||||||
|
|
||||||
|
<%def name="title()">Login</%def>
|
||||||
|
|
||||||
|
<%def name="head_tags()">
|
||||||
|
${parent.head_tags()}
|
||||||
|
${h.javascript_link(request.static_url('tailbone:static/js/login.js'))}
|
||||||
|
${h.stylesheet_link(request.static_url('tailbone:static/css/login.css'))}
|
||||||
|
</%def>
|
||||||
|
|
||||||
|
${h.image(request.static_url('tailbone:static/img/home_logo.png'), "Rattail Logo", id='logo')}
|
||||||
|
|
||||||
|
<div class="form">
|
||||||
|
${h.form('')}
|
||||||
|
<input type="hidden" name="referrer" value="${referrer}" />
|
||||||
|
|
||||||
|
% if error:
|
||||||
|
<div class="error">${error}</div>
|
||||||
|
% endif
|
||||||
|
|
||||||
|
<div class="field-wrapper">
|
||||||
|
<label for="username">Username</label>
|
||||||
|
<input type="text" name="username" id="username" value="" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="field-wrapper">
|
||||||
|
<label for="password">Password</label>
|
||||||
|
<input type="password" name="password" id="password" value="" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="buttons">
|
||||||
|
${h.submit('submit', "Login")}
|
||||||
|
<input type="reset" value="Reset" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
${h.end_form()}
|
||||||
|
</div>
|
11
tailbone/templates/people/index.mako
Normal file
11
tailbone/templates/people/index.mako
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
<%inherit file="/grid.mako" />
|
||||||
|
|
||||||
|
<%def name="title()">People</%def>
|
||||||
|
|
||||||
|
<%def name="context_menu_items()">
|
||||||
|
## % if request.has_perm('people.create'):
|
||||||
|
## <li>${h.link_to("Create a new Person", url('person.new'))}</li>
|
||||||
|
## % endif
|
||||||
|
</%def>
|
||||||
|
|
||||||
|
${parent.body()}
|
18
tailbone/templates/roles/crud.mako
Normal file
18
tailbone/templates/roles/crud.mako
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
<%inherit file="edbob.pyramid:templates/crud.mako" />
|
||||||
|
|
||||||
|
<%def name="head_tags()">
|
||||||
|
${parent.head_tags()}
|
||||||
|
${h.stylesheet_link(request.static_url('edbob.pyramid:static/css/perms.css'))}
|
||||||
|
</%def>
|
||||||
|
|
||||||
|
<%def name="context_menu_items()">
|
||||||
|
<li>${h.link_to("Back to Roles", url('roles'))}</li>
|
||||||
|
% if form.readonly:
|
||||||
|
<li>${h.link_to("Edit this Role", url('role.update', uuid=form.fieldset.model.uuid))}</li>
|
||||||
|
% elif form.updating:
|
||||||
|
<li>${h.link_to("View this Role", url('role.read', uuid=form.fieldset.model.uuid))}</li>
|
||||||
|
% endif
|
||||||
|
<li>${h.link_to("Delete this Role", url('role.delete', uuid=form.fieldset.model.uuid), class_='delete')}</li>
|
||||||
|
</%def>
|
||||||
|
|
||||||
|
${parent.body()}
|
11
tailbone/templates/roles/index.mako
Normal file
11
tailbone/templates/roles/index.mako
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
<%inherit file="/grid.mako" />
|
||||||
|
|
||||||
|
<%def name="title()">Roles</%def>
|
||||||
|
|
||||||
|
<%def name="context_menu_items()">
|
||||||
|
% if request.has_perm('roles.create'):
|
||||||
|
<li>${h.link_to("Create a new Role", url('role.create'))}</li>
|
||||||
|
% endif
|
||||||
|
</%def>
|
||||||
|
|
||||||
|
${parent.body()}
|
11
tailbone/templates/users/index.mako
Normal file
11
tailbone/templates/users/index.mako
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
<%inherit file="/grid.mako" />
|
||||||
|
|
||||||
|
<%def name="title()">Users</%def>
|
||||||
|
|
||||||
|
<%def name="context_menu_items()">
|
||||||
|
% if request.has_perm('users.create'):
|
||||||
|
<li>${h.link_to("Create a new User", url('user.create'))}</li>
|
||||||
|
% endif
|
||||||
|
</%def>
|
||||||
|
|
||||||
|
${parent.body()}
|
|
@ -35,7 +35,7 @@ from ..forms.simpleform import FormRenderer
|
||||||
|
|
||||||
import edbob
|
import edbob
|
||||||
from ..db import Session
|
from ..db import Session
|
||||||
from edbob.db.auth import authenticate_user, set_user_password
|
from rattail.db.auth import authenticate_user, set_user_password
|
||||||
|
|
||||||
|
|
||||||
class UserLogin(formencode.Schema):
|
class UserLogin(formencode.Schema):
|
||||||
|
@ -58,9 +58,9 @@ def login(request):
|
||||||
|
|
||||||
form = Form(request, schema=UserLogin)
|
form = Form(request, schema=UserLogin)
|
||||||
if form.validate():
|
if form.validate():
|
||||||
user = authenticate_user(form.data['username'],
|
user = authenticate_user(Session(),
|
||||||
form.data['password'],
|
form.data['username'],
|
||||||
session=Session())
|
form.data['password'])
|
||||||
if user:
|
if user:
|
||||||
request.session.flash("%s logged in at %s" % (
|
request.session.flash("%s logged in at %s" % (
|
||||||
user.display_name,
|
user.display_name,
|
||||||
|
|
|
@ -26,12 +26,11 @@
|
||||||
Batch Row Views
|
Batch Row Views
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
from .. import SearchableAlchemyGridView, CrudView
|
||||||
from pyramid.httpexceptions import HTTPFound
|
from pyramid.httpexceptions import HTTPFound
|
||||||
|
|
||||||
from ...db import Session
|
from ...db import Session
|
||||||
from .. import SearchableAlchemyGridView, CrudView
|
from rattail.db.model import Batch, LabelProfile
|
||||||
|
|
||||||
import rattail
|
|
||||||
from ...forms import GPCFieldRenderer
|
from ...forms import GPCFieldRenderer
|
||||||
|
|
||||||
|
|
||||||
|
@ -41,8 +40,8 @@ def field_with_renderer(field, column):
|
||||||
field = field.with_renderer(GPCFieldRenderer)
|
field = field.with_renderer(GPCFieldRenderer)
|
||||||
|
|
||||||
elif column.sil_name == 'F95': # Shelf Tag Type
|
elif column.sil_name == 'F95': # Shelf Tag Type
|
||||||
q = Session.query(rattail.LabelProfile)
|
q = Session.query(LabelProfile)
|
||||||
q = q.order_by(rattail.LabelProfile.ordinal)
|
q = q.order_by(LabelProfile.ordinal)
|
||||||
field = field.dropdown(options=[(x.description, x.code) for x in q])
|
field = field.dropdown(options=[(x.description, x.code) for x in q])
|
||||||
|
|
||||||
return field
|
return field
|
||||||
|
@ -50,7 +49,7 @@ def field_with_renderer(field, column):
|
||||||
|
|
||||||
def BatchRowsGrid(request):
|
def BatchRowsGrid(request):
|
||||||
uuid = request.matchdict['uuid']
|
uuid = request.matchdict['uuid']
|
||||||
batch = Session.query(rattail.Batch).get(uuid) if uuid else None
|
batch = Session.query(Batch).get(uuid) if uuid else None
|
||||||
if not batch:
|
if not batch:
|
||||||
return HTTPFound(location=request.route_url('batches'))
|
return HTTPFound(location=request.route_url('batches'))
|
||||||
|
|
||||||
|
@ -141,7 +140,7 @@ def batch_rows_delete(request):
|
||||||
|
|
||||||
def batch_row_crud(request, attr):
|
def batch_row_crud(request, attr):
|
||||||
batch_uuid = request.matchdict['batch_uuid']
|
batch_uuid = request.matchdict['batch_uuid']
|
||||||
batch = Session.query(rattail.Batch).get(batch_uuid)
|
batch = Session.query(Batch).get(batch_uuid)
|
||||||
if not batch:
|
if not batch:
|
||||||
return HTTPFound(location=request.route_url('batches'))
|
return HTTPFound(location=request.route_url('batches'))
|
||||||
|
|
||||||
|
|
|
@ -26,43 +26,121 @@
|
||||||
Role Views
|
Role Views
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
from . import SearchableAlchemyGridView, CrudView
|
||||||
from pyramid.httpexceptions import HTTPFound
|
from pyramid.httpexceptions import HTTPFound
|
||||||
|
|
||||||
|
from ..db import Session
|
||||||
|
from rattail.db.model import Role
|
||||||
|
from rattail.db.auth import has_permission, administrator_role, guest_role
|
||||||
|
|
||||||
import formalchemy
|
import formalchemy
|
||||||
from webhelpers.html import tags
|
from webhelpers.html import tags
|
||||||
from webhelpers.html.builder import HTML
|
from webhelpers.html import HTML
|
||||||
|
|
||||||
from edbob.db import auth
|
|
||||||
|
|
||||||
from ..db import Session
|
|
||||||
from . import SearchableAlchemyGridView, CrudView
|
|
||||||
from rattail.db.model import Role
|
|
||||||
|
|
||||||
|
|
||||||
default_permissions = [
|
default_permissions = [
|
||||||
|
("Batches", [
|
||||||
|
('batches.list', "List Batches"),
|
||||||
|
('batches.read', "View Batches"),
|
||||||
|
('batches.create', "Create Batches"),
|
||||||
|
('batches.update', "Edit Batches"),
|
||||||
|
('batches.delete', "Delete Batches"),
|
||||||
|
('batches.execute', "Execute Batches"),
|
||||||
|
('batch_rows.read', "View Batch Rows"),
|
||||||
|
('batch_rows.update', "Edit Batch Rows"),
|
||||||
|
('batch_rows.delete', "Delete Batch Rows"),
|
||||||
|
]),
|
||||||
|
("Brands", [
|
||||||
|
('brands.list', "List Brands"),
|
||||||
|
('brands.read', "View Brands"),
|
||||||
|
('brands.create', "Create Brands"),
|
||||||
|
('brands.update', "Edit Brands"),
|
||||||
|
('brands.delete', "Delete Brands"),
|
||||||
|
('brands.force_sync', "Forcibly Sync Brands"),
|
||||||
|
]),
|
||||||
|
("Customers", [
|
||||||
|
('customers.list', "List Customers"),
|
||||||
|
('customers.read', "View Customers"),
|
||||||
|
('customers.force_sync', "Forcibly Sync Customers"),
|
||||||
|
('customer_groups.list', "List Customer Groups"),
|
||||||
|
('customer_groups.read', "View Customer Groups"),
|
||||||
|
('customer_groups.force_sync', "Forcibly Sync Customer Groups"),
|
||||||
|
]),
|
||||||
|
("Departments", [
|
||||||
|
('departments.list', "List Departments"),
|
||||||
|
('departments.read', "View Departments"),
|
||||||
|
('departments.create', "Create Departments"),
|
||||||
|
('departments.update', "Edit Departments"),
|
||||||
|
('departments.delete', "Delete Departments"),
|
||||||
|
('departments.force_sync', "Forcibly Sync Departments"),
|
||||||
|
]),
|
||||||
|
("Employees", [
|
||||||
|
('employees.list', "List Employees"),
|
||||||
|
('employees.force_sync', "Forcibly Sync Employees"),
|
||||||
|
]),
|
||||||
|
("Label Profiles", [
|
||||||
|
('label_profiles.list', "List Label Profiles"),
|
||||||
|
('label_profiles.view', "View Label Profiles"),
|
||||||
|
('label_profiles.create', "Create Label Profiles"),
|
||||||
|
('label_profiles.update', "Edit Label Profiles"),
|
||||||
|
('label_profiles.delete', "Delete Label Profiles"),
|
||||||
|
]),
|
||||||
("People", [
|
("People", [
|
||||||
('people.list', "List People"),
|
('people.list', "List People"),
|
||||||
('people.read', "View Person"),
|
('people.read', "View People"),
|
||||||
('people.create', "Create Person"),
|
('people.create', "Create People"),
|
||||||
('people.update', "Edit Person"),
|
('people.update', "Edit People"),
|
||||||
('people.delete', "Delete Person"),
|
('people.delete', "Delete People"),
|
||||||
|
('people.force_sync', "Forcibly Sync People"),
|
||||||
|
]),
|
||||||
|
("Products", [
|
||||||
|
('products.list', "List Products"),
|
||||||
|
('products.read', "View Products"),
|
||||||
|
('products.create', "Create Products"),
|
||||||
|
('products.update', "Edit Products"),
|
||||||
|
('products.delete', "Delete Products"),
|
||||||
|
('products.print_labels', "Print Product Labels"),
|
||||||
|
('products.force_sync', "Forcibly Sync Products"),
|
||||||
]),
|
]),
|
||||||
|
|
||||||
("Roles", [
|
("Roles", [
|
||||||
('roles.list', "List Roles"),
|
('roles.list', "List Roles"),
|
||||||
('roles.read', "View Role"),
|
('roles.read', "View Roles"),
|
||||||
('roles.create', "Create Role"),
|
('roles.create', "Create Roles"),
|
||||||
('roles.update', "Edit Role"),
|
('roles.update', "Edit Roles"),
|
||||||
('roles.delete', "Delete Role"),
|
('roles.delete', "Delete Roles"),
|
||||||
|
]),
|
||||||
|
("Stores", [
|
||||||
|
('stores.list', "List Stores"),
|
||||||
|
('stores.read', "View Stores"),
|
||||||
|
('stores.create', "Create Stores"),
|
||||||
|
('stores.update', "Edit Stores"),
|
||||||
|
('stores.delete', "Delete Stores"),
|
||||||
|
('stores.force_sync', "Forcibly Sync Stores"),
|
||||||
|
]),
|
||||||
|
("Subdepartments", [
|
||||||
|
('subdepartments.list', "List Subdepartments"),
|
||||||
|
('subdepartments.read', "View Subdepartments"),
|
||||||
|
('subdepartments.create', "Create Subdepartments"),
|
||||||
|
('subdepartments.update', "Edit Subdepartments"),
|
||||||
|
('subdepartments.delete', "Delete Subdepartments"),
|
||||||
|
('subdepartments.force_sync', "Forcibly Sync Subdepartments"),
|
||||||
]),
|
]),
|
||||||
|
|
||||||
("Users", [
|
("Users", [
|
||||||
('users.list', "List Users"),
|
('users.list', "List Users"),
|
||||||
('users.read', "View User"),
|
('users.read', "View Users"),
|
||||||
('users.create', "Create User"),
|
('users.create', "Create Users"),
|
||||||
('users.update', "Edit User"),
|
('users.update', "Edit Users"),
|
||||||
('users.delete', "Delete User"),
|
('users.delete', "Delete Users"),
|
||||||
|
('users.force_sync', "Forcibly Sync Users"),
|
||||||
|
]),
|
||||||
|
("Vendors", [
|
||||||
|
('vendors.list', "List Vendors"),
|
||||||
|
('vendors.read', "View Vendors"),
|
||||||
|
('vendors.create', "Create Vendors"),
|
||||||
|
('vendors.update', "Edit Vendors"),
|
||||||
|
('vendors.delete', "Delete Vendors"),
|
||||||
|
('vendors.import_catalog', "Import Vendor Catalogs"),
|
||||||
|
('vendors.force_sync', "Forcibly Sync Vendors"),
|
||||||
]),
|
]),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -129,7 +207,7 @@ def PermissionsFieldRenderer(permissions, *args, **kwargs):
|
||||||
|
|
||||||
def _render(self, readonly=False, **kwargs):
|
def _render(self, readonly=False, **kwargs):
|
||||||
role = self.field.model
|
role = self.field.model
|
||||||
admin = auth.administrator_role(Session())
|
admin = administrator_role(Session())
|
||||||
if role is admin:
|
if role is admin:
|
||||||
html = HTML.tag('p', c="This is the administrative role; "
|
html = HTML.tag('p', c="This is the administrative role; "
|
||||||
"it has full access to the entire system.")
|
"it has full access to the entire system.")
|
||||||
|
@ -140,8 +218,8 @@ def PermissionsFieldRenderer(permissions, *args, **kwargs):
|
||||||
for group, perms in self.permissions:
|
for group, perms in self.permissions:
|
||||||
inner = HTML.tag('p', c=group)
|
inner = HTML.tag('p', c=group)
|
||||||
for perm, title in perms:
|
for perm, title in perms:
|
||||||
checked = auth.has_permission(
|
checked = has_permission(
|
||||||
role, perm, include_guest=False, session=Session())
|
Session(), role, perm, include_guest=False)
|
||||||
if readonly:
|
if readonly:
|
||||||
span = HTML.tag('span', c="[X]" if checked else "[ ]")
|
span = HTML.tag('span', c="[X]" if checked else "[ ]")
|
||||||
inner += HTML.tag('p', class_='perm', c=span + ' ' + title)
|
inner += HTML.tag('p', class_='perm', c=span + ' ' + title)
|
||||||
|
@ -179,8 +257,8 @@ class RoleCrud(CrudView):
|
||||||
return fs
|
return fs
|
||||||
|
|
||||||
def pre_delete(self, model):
|
def pre_delete(self, model):
|
||||||
admin = auth.administrator_role(Session())
|
admin = administrator_role(Session())
|
||||||
guest = auth.guest_role(Session())
|
guest = guest_role(Session())
|
||||||
if model in (admin, guest):
|
if model in (admin, guest):
|
||||||
self.request.session.flash("You may not delete the %s role." % str(model), 'error')
|
self.request.session.flash("You may not delete the %s role." % str(model), 'error')
|
||||||
return HTTPFound(location=self.request.get_referrer())
|
return HTTPFound(location=self.request.get_referrer())
|
||||||
|
|
|
@ -35,7 +35,7 @@ from . import SearchableAlchemyGridView, CrudView
|
||||||
from ..forms import PersonFieldRenderer
|
from ..forms import PersonFieldRenderer
|
||||||
from ..db import Session
|
from ..db import Session
|
||||||
from rattail.db.model import User, Person, Role
|
from rattail.db.model import User, Person, Role
|
||||||
from edbob.db.auth import guest_role
|
from rattail.db.auth import guest_role
|
||||||
|
|
||||||
from webhelpers.html import tags
|
from webhelpers.html import tags
|
||||||
from webhelpers.html import HTML
|
from webhelpers.html import HTML
|
||||||
|
|
Loading…
Reference in a new issue