libreForms / libreForms-flask

Flask implementation of the libreForms API
https://libreforms.readthedocs.io
GNU Affero General Public License v3.0
4 stars 1 forks source link

Add support for user groups/roles to restrict access to forms and views #16

Closed signebedi closed 1 year ago

signebedi commented 2 years ago

We should introduce user groups/classes that allow for restricted access to key features, as well as to certain forms.

In the case of group-based form access, introduce support for group-based access in the API (perhaps under the validators tag) and define default behavior (allow all).

signebedi commented 2 years ago

The @roles_required decorator provided by Flask-User is unmaintained but potentially instructive, see

signebedi commented 2 years ago

Maybe we can create a separate groups database, see https://stackoverflow.com/questions/35595184/best-way-to-store-member-of-group-in-mysql-table.

signebedi commented 1 year ago

Additionally, this feature should optionally enable the creation of new users and management of existing ones.

signebedi commented 1 year ago

There are a few ways we can build the data model to support this - but all approaches that provide granular, form-by-form permissions are complicated by the fact that the forms themselves may vary at runtime...

admin-defined permissions based on arbitrary classes of users seem like the best approach because it forces managers to think about what categories of users they want to be able to access forms. We have a one-to-one group/role to user mapping (users can only be one role, so that means that we devolve into very specific group access procedures...). Newly registered users get a set of default privileges. This, then, will need to be implemented in our data model...

  1. admin: full site access (start with just libreforms)
  2. default: minimal site / resource access
  3. anonymous: users accessing the site via signing key
  4. ... any other arbitrary groups.

We can define the add'l groups in display.py as follows:

'user_groups': [
  'reporters',
  'purchasers',
  'accounting',
]

Then, in each form, we define a form-wide config, as well as a table and dashboard specific config, to limit what groups have access to each using a list mapping. Maybe, though this might be overkill, we support restrict access to certain form fields to certain user groups. Here it will be important to define default behavior. For example, take a situation where we have three roles: admin, default, and web-users. We want to allow all groups accept default to fill out Form_1. However, we also don't want web-users to be able to complete Field_2, nor view the dashboard. Let's say we want everybody to be able to view the tabular submission data, because it serves as a sort of billboard for the organization. Maybe the following form structure might work:

forms = {
  'Form_1': {
    'Field_1': { ... },
    'Field_2': { ... '_group_access': { 'allow': [], 'deny': ['web-users']}},
    '_dashboard': { ... , '_group_access': { 'allow': [], 'deny': ['default', 'web-users']},},
    '_table': { ... , '_group_access': { 'allow': [], 'deny': []},},
    '_group_access': { 'allow': [], 'deny': ['default']},
  }
}

I like the idea of forcing the allow and deny sub fields into this because it permits greater granularity, at the expense of a more complex data structure to need to make sense of...

signebedi commented 1 year ago

We can also define the set_default_group field to define the basic group we'll use for users on this system...

signebedi commented 1 year ago

How about we set config display['allow_all_groups_default'] = True - meaning that by default we allow all groups to access forms with undefined authorization limits...?

signebedi commented 1 year ago

How do we handle this for external form submission? I think, in reality, we either need a separate group called 'anon' ...

signebedi commented 1 year ago

With 0455ad6, we've implemented what makes sense for this issue. In the future, it may be appropriate to revisit and assess whether this system is sufficient in the resources it grants restricts access to, and if it is appropriate for the needs of the admin console #28 .

signebedi commented 1 year ago

Okay, so we're going to deprecate allowing end users to define default allow / deny behavior. Instead, we'll opt of allow-by-default and a form, field, _dash, and _table config that allows admins to deny_group_access: [list, of, groups].