# Monday, June 29, 2015¶

Uff! Adapting the permissions system of Lino Welfare to the new class-based paradigm took me a whole day!

Nevertheless it is clear that this was a good and important step for Lino. I am glad to have test cases like General overview of Lino Welfare.

Old content of setup_user_profiles():

from django.utils.translation import ugettext_lazy as _
from lino.modlib.users.choicelists import UserProfiles

UserProfiles.reset(
'* office coaching integ courses cbss newcomers debts '
'reception beid')
add('000', _("Anonymous"),                   '_ _ _ _ _ _ _ _ _ _',
name='anonymous',
authenticated=False)
add('100', _("Integration Agent"),           'U U U U U U _ _ _ U')
add('110', _("Integration Agent (Manager)"), 'U M M M M U _ _ _ U')
add('200', _("Newcomers consultant"),        'U U U _ _ U U _ _ U')
add('210', _("Reception clerk"),             'U U _ _ _ _ _ _ U U')
add('300', _("Debts consultant"),            'U U U _ _ _ U U _ U')
add('400', _("Social agent"),                'U U U _ U U _ _ _ U')
add('410', _("Social agent (Manager)"),      'U M M _ M U _ _ _ U')
add('900', _("Administrator"),               'A A A A A A A A A U',


Basically this code does not change much… except that we replaced the system of “U M A _” strings by classes, and that we define these classes in a separate module lino_welfare.modlib.welfare.roles:

from lino.modlib.users.choicelists import UserProfiles
from lino_welfare.modlib.welfare.roles import *

UserProfiles.clear()


Maybe an inheritance-diagram can help to visualize the complexity:

## Cannot create a consistent method resolution order¶

Here is a side effect of having class-based permissions: since we use a rather complex form of multiple inheritance, I needed to learn how to analyze error messages like this one:

\$ python -m lino_welfare.modlib.welfare.roles
Traceback (most recent call last):
File "/usr/lib/python2.7/runpy.py", line 162, in _run_module_as_main
File "/usr/lib/python2.7/runpy.py", line 72, in _run_code
exec code in run_globals
File "/home/luc/hgwork/welfare/lino_welfare/modlib/welfare/roles.py", line 29, in <module>
class IntegrationStaff(IntegrationAgent, IntegrationStaff):
TypeError: Error when calling the metaclass bases
Cannot create a consistent method resolution
order (MRO) for bases CBSSUser, OfficeOperator


This error comes when I specify a “nonsense” or “illegal” inheritence line. But in above case I did not see immediately where exactly the problem was. So I tried to write out the full genealogic tree:

IntegrationStaff(IntegrationAgent, SocialStaff, CareerStaff)
- IntegrationAgent(SocialAgent, CareerUser)
- SocialAgent(OfficeUser, CBSSUser)
- OfficeUser(ContactsUser)
- ContactsUser(SiteUser)
- CBSSUser(ContactsUser)
- ContactsUser(SiteUser)
- CareerUser(SiteUser)
- SocialStaff(OfficeStaff, SocialAgent)
- OfficeStaff(OfficeUser, OfficeOperator, ContactsStaff)
- OfficeUser(ContactsUser)
- ContactsUser(SiteUser)
- OfficeOperator(ContactsUser)
- ContactsUser(SiteUser)
- ContactsStaff(ContactsUser)
- ContactsUser(SiteUser)
- SocialAgent(OfficeUser, CBSSUser)
- OfficeUser(ContactsUser)
- ContactsUser(SiteUser)
- CBSSUser(ContactsUser)
- ContactsUser(SiteUser)
- CareerStaff(CareerUser)
- CareerUser(SiteUser)

Thanks to Sixty North for writing a good blog entry about it.

A disadvantage of the class-based permission system is (or was) the fact that e.g. Watching database changes which uses lino.modlib.contacts was now forced to define user roles. Even though the example does not care about them. Because otherwise even the site administrator has no access to the contacts menu.

The new attribute lino.core.site.Site.disable_user_roles is a workaround for this, or maybe even a cool thing: setting this to True will “disable” all lino.core.utils.Permittable.required_roles.