Skip to content

Commit

Permalink
Merge branch 'master' of github.com:nursix/eden-asp
Browse files Browse the repository at this point in the history
  • Loading branch information
nursix committed Aug 10, 2023
2 parents 6835282 + 0be46cf commit 9844a04
Show file tree
Hide file tree
Showing 99 changed files with 26,548 additions and 1,586 deletions.
18 changes: 9 additions & 9 deletions controllers/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,19 +52,19 @@ def user():
ADMIN = True
pe_ids = None

elif s3_has_role("ORG_ADMIN"):
pe_ids = auth.get_managed_orgs()
if pe_ids is None:
# OrgAdmin with default realm, but user not affiliated with any org
auth.permission.fail()
elif pe_ids is not True:
# OrgAdmin for certain organisations
elif auth.s3_has_roles(("ORG_ADMIN", "ORG_GROUP_ADMIN")):
pe_ids = auth.permission.permitted_realms("auth_user", "update")
if pe_ids:
# Restricted to certain organisations
otable = s3db.org_organisation
s3.filter = (otable.pe_id.belongs(pe_ids)) & \
(table.organisation_id == otable.id)
elif pe_ids is not None:
# Not allowed for any organisations
auth.permission.fail()
else:
# OrgAdmin with site-wide permission
pe_ids = None
# Allowed for all organisations
pass
else:
auth.permission.fail()

Expand Down
52 changes: 33 additions & 19 deletions modules/core/aaa/auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
from s3dal import Row, Rows, Query, Field, original_tablename

from ..controller import CRUDRequest
from ..model import S3MetaFields, CommentsField
from ..model import MetaFields, CommentsField
from ..tools import IS_ISO639_2_LANGUAGE_CODE, S3Represent, S3Tracker, \
s3_addrow, s3_mark_required, s3_str

Expand Down Expand Up @@ -302,10 +302,10 @@ def define_tables(self, migrate=True, fake_migrate=False):
readable=False, writable=False),
CommentsField(readable=False, writable=False),
# Additional meta fields required for sync:
S3MetaFields.uuid(),
#S3MetaFields.mci(),
S3MetaFields.created_on(),
S3MetaFields.modified_on(),
MetaFields.uuid(),
#MetaFields.mci(),
MetaFields.created_on(),
MetaFields.modified_on(),
]

userfield = settings.login_userfield
Expand Down Expand Up @@ -366,11 +366,11 @@ def define_tables(self, migrate=True, fake_migrate=False):
label = messages.label_description,
),
# Additional meta fields required for sync:
S3MetaFields.created_on(),
S3MetaFields.modified_on(),
S3MetaFields.deleted(),
#S3MetaFields.deleted_fk(),
#S3MetaFields.deleted_rb(),
MetaFields.created_on(),
MetaFields.modified_on(),
MetaFields.deleted(),
#MetaFields.deleted_fk(),
#MetaFields.deleted_rb(),
migrate = migrate,
fake_migrate = fake_migrate,
)
Expand Down Expand Up @@ -398,7 +398,7 @@ def define_tables(self, migrate=True, fake_migrate=False):
),
migrate = migrate,
fake_migrate = fake_migrate,
*S3MetaFields.sync_meta_fields())
*MetaFields.sync_meta_fields())
settings.table_membership = db[settings.table_membership_name]

# Define Eden permission table
Expand Down Expand Up @@ -461,7 +461,7 @@ def define_tables(self, migrate=True, fake_migrate=False):
),
migrate = migrate,
fake_migrate = fake_migrate,
*S3MetaFields.sync_meta_fields())
*MetaFields.sync_meta_fields())
settings.table_event = db[settings.table_event_name]

# -------------------------------------------------------------------------
Expand Down Expand Up @@ -3854,10 +3854,18 @@ def get_system_roles(self):
# -------------------------------------------------------------------------
def get_managed_orgs(self):
"""
Get the pe_ids of all managed organisations (to authorize
role assignments)
Get the pe_ids of all managed organisations, e.g. for filters
TODO use this in admin/user controller
Returns:
- True if unrestricted (i.e. site-wide role)
- list of pe_ids if restricted
- None if user does not manage any orgs
Note:
The result only means that the user has a *_ADMIN role
for those organisations, but that does not imply any
particular permissions =>
use auth.permission.permitted_realms for access control
"""

user = self.user
Expand All @@ -3870,7 +3878,7 @@ def get_managed_orgs(self):
if has_role(sr.ADMIN):
return True

elif has_role(sr.ORG_ADMIN):
elif self.s3_has_roles((sr.ORG_ADMIN, sr.ORG_GROUP_ADMIN)):
if not self.permission.entity_realm:
organisation_id = user.organisation_id
if not organisation_id:
Expand All @@ -3886,9 +3894,15 @@ def get_managed_orgs(self):
)
pe_ids.append(pe_id)
else:
pe_ids = self.user.realms[sr.ORG_ADMIN]
if pe_ids is None:
return True
pe_ids = set()
for role in (sr.ORG_ADMIN, sr.ORG_GROUP_ADMIN):
if role not in self.user.realms:
continue
realm = self.user.realms[role]
if realm is None:
return True
pe_ids.update(realm)
pe_ids = list(pe_ids) if pe_ids else None
return pe_ids

else:
Expand Down
4 changes: 2 additions & 2 deletions modules/core/aaa/permissions.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@

from s3dal import Field, Row, Table, original_tablename

from ..model import S3MetaFields
from ..model import MetaFields
from ..errors import S3PermissionError
from ..tools import s3_get_extension

Expand Down Expand Up @@ -226,7 +226,7 @@ def define_table(self, migrate=True, fake_migrate=False):
),
migrate = migrate,
fake_migrate = fake_migrate,
*S3MetaFields.sync_meta_fields()
*MetaFields.sync_meta_fields()
)
self.table = db[self.tablename]

Expand Down
15 changes: 8 additions & 7 deletions modules/core/methods/rolemgr.py
Original file line number Diff line number Diff line change
Expand Up @@ -814,10 +814,8 @@ def assign_roles(self, r, **attr):
r.unauthorised()

# Require that the target user record belongs to a managed organisation
pe_ids = auth.get_managed_orgs()
if not pe_ids:
r.unauthorised()
elif pe_ids is not True:
pe_ids = auth.permission.permitted_realms("auth_user", "update")
if pe_ids:
otable = current.s3db.org_organisation
utable = auth.settings.table_user
query = (utable.id == r.id) & \
Expand All @@ -828,6 +826,8 @@ def assign_roles(self, r, **attr):
).first()
if not row:
r.unauthorised()
elif pe_ids is not None:
r.unauthorised()

# Which roles can the current user manage for this user?
managed_roles = self.get_managed_roles(r.id)
Expand Down Expand Up @@ -1125,12 +1125,13 @@ def get_managed_users(role_id):

users = {}

pe_ids = auth.get_managed_orgs()
if pe_ids:
pe_ids = auth.permitted_realms("auth_user", "update")
if pe_ids or pe_ids is None:
utable = auth_settings.table_user
query = (utable.deleted == False)

if pe_ids is not True:
if pe_ids is not None:
# Restricted to certain organisations
otable = current.s3db.org_organisation
query &= (otable.id == utable.organisation_id) & \
(otable.pe_id.belongs(pe_ids))
Expand Down
4 changes: 2 additions & 2 deletions modules/core/model/datamodel.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
from ..ui import S3ScriptItem

from .dynamic import DynamicTableModel, DYNAMIC_PREFIX
from .fields import S3MetaFields
from .fields import MetaFields

DEFAULT = lambda: None
MODULE_TYPE = type(sys)
Expand Down Expand Up @@ -467,7 +467,7 @@ def define_table(tablename, *fields, meta=True, **args):
table = getattr(db, tablename)
else:
if meta:
fields = fields + S3MetaFields.all_meta_fields()
fields = fields + MetaFields.all_meta_fields()
table = db.define_table(tablename, *fields, **args)
return table

Expand Down
6 changes: 3 additions & 3 deletions modules/core/model/fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
"LanguageField",
"TimeField",
"FieldTemplate",
"S3MetaFields",
"MetaFields",
"s3_fieldmethod",
"s3_meta_fields",
"s3_all_meta_field_names",
Expand Down Expand Up @@ -239,7 +239,7 @@ def dummy(fname="dummy_id", ftype="integer"):
)

# -----------------------------------------------------------------------------
class S3MetaFields:
class MetaFields:
""" Class to standardize meta-fields """

# -------------------------------------------------------------------------
Expand Down Expand Up @@ -550,7 +550,7 @@ def s3_meta_fields():
tuple of Field instances
"""

return S3MetaFields.all_meta_fields()
return MetaFields.all_meta_fields()

def s3_all_meta_field_names():
"""
Expand Down
6 changes: 3 additions & 3 deletions modules/s3db/auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -607,9 +607,9 @@ def model(self):
Field("custom", "json",
requires = IS_EMPTY_OR(IS_JSONS3()),
),
S3MetaFields.uuid(),
S3MetaFields.created_on(),
S3MetaFields.modified_on(),
MetaFields.uuid(),
MetaFields.created_on(),
MetaFields.modified_on(),
meta = False,
)

Expand Down
52 changes: 50 additions & 2 deletions modules/s3db/dvr.py
Original file line number Diff line number Diff line change
Expand Up @@ -7012,12 +7012,22 @@ def registration_form(self, r, **attr):
# Whether the event registration is actionable
actionable = event_code is not None

label_input = self.label_input
use_qr_code = settings.get_org_site_check_in_qrcode()
if use_qr_code:
if use_qr_code is True:
label_input = S3QRInput()
elif isinstance(use_qr_code, tuple):
pattern, index = use_qr_code[:2]
label_input = S3QRInput(pattern=pattern, index=index)

# Standard form fields and data
formfields = [Field("label",
label = T("ID"),
requires = [IS_NOT_EMPTY(error_message=T("Enter or scan an ID")),
IS_LENGTH(512, minsize=1),
],
widget = label_input,
),
Field("person",
label = "",
Expand Down Expand Up @@ -7079,7 +7089,7 @@ def registration_form(self, r, **attr):
buttons = [check_btn, submit_btn]

# Add the cancel-action
buttons.append(A(T("Cancel"), _class = "cancel-action action-lnk"))
buttons.append(A(T("Cancel"), _class = "cancel-action cancel-form-btn action-lnk"))

resourcename = r.resource.name

Expand Down Expand Up @@ -7112,7 +7122,8 @@ def registration_form(self, r, **attr):
output.update(header)

# ZXing Barcode Scanner Launch Button
output["zxing"] = self.get_zxing_launch_button(event_code)
#output["zxing"] = self.get_zxing_launch_button(event_code)
output["zxing"] = ""

# Custom view
response.view = self._view(r, "dvr/register_case_event.html")
Expand All @@ -7134,6 +7145,43 @@ def registration_form(self, r, **attr):

return output

# -------------------------------------------------------------------------
@staticmethod
def label_input(field, value, **attributes):
"""
Custom widget for label input, providing a clear-button
(for ease of use on mobile devices where no ESC exists)
Args:
field: the Field
value: the current value
attributes: HTML attributes
Note:
expects Foundation theme
"""

from gluon.sqlhtml import StringWidget

default = {"value": (value is not None and str(value)) or ""}
attr = StringWidget._attributes(field, default, **attributes)

placeholder = current.T("Enter or scan ID")
attr["_placeholder"] = placeholder

postfix = ICON("fa fa-close")

widget = DIV(DIV(INPUT(**attr),
_class="small-11 columns",
),
DIV(SPAN(postfix, _class="postfix clear-btn"),
_class="small-1 columns",
),
_class="row collapse",
)

return widget

# -------------------------------------------------------------------------
# Configuration
# -------------------------------------------------------------------------
Expand Down
2 changes: 1 addition & 1 deletion modules/s3db/msg.py
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ def model(self):
define_table(tablename,
# @ToDo: Make it per-channel
#channel_id(),
*S3MetaFields.timestamps(),
*MetaFields.timestamps(),
meta = False,
)

Expand Down
14 changes: 13 additions & 1 deletion modules/s3db/org.py
Original file line number Diff line number Diff line change
Expand Up @@ -1461,6 +1461,18 @@ def model(self):
else:
# Functionality is disabled but model is being loaded via load_all_models()
label = "Group"
crud_strings[tablename] = Storage(
label_create = T("Create Organization Group"),
title_display = T("Organization Group Details"),
title_list = T("Organization Groups"),
title_update = T("Edit Organization Group"),
label_list_button = T("List Organization Groups"),
label_delete_button = T("Delete Organization Group"),
msg_record_created = T("Organization Group added"),
msg_record_modified = T("Organization Group updated"),
msg_record_deleted = T("Organization Group deleted"),
msg_list_empty = T("No Organization Groups currently registered"),
)

configure(tablename,
list_fields = ["name",
Expand Down Expand Up @@ -3159,7 +3171,7 @@ def model(self):
writable = False,
),
Field("comments", "text"),
*S3MetaFields.owner_meta_fields())
*MetaFields.owner_meta_fields())

# ---------------------------------------------------------------------
settings = current.deployment_settings
Expand Down
2 changes: 1 addition & 1 deletion modules/s3db/s3.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ def model(self):
default = False,
),
Field("hierarchy", "json"),
*S3MetaFields.timestamps(),
*MetaFields.timestamps(),
meta = False,
)

Expand Down
2 changes: 1 addition & 1 deletion modules/s3db/supply.py
Original file line number Diff line number Diff line change
Expand Up @@ -891,7 +891,7 @@ def model(self):
default = 1.0,
label = T("Quantity"),
),
*S3MetaFields.owner_meta_fields())
*MetaFields.owner_meta_fields())

# Reusable Field
item_id = lambda: super_link("item_entity_id", "supply_item_entity",
Expand Down
Loading

0 comments on commit 9844a04

Please sign in to comment.