Hello,

There is still problem with the design... The function is not protecting
from the definition of group set that could include an other group the in
which the user is already involved. The user is allowed to change from only
one group, so if we use other groups for other purpose (like restricting
entry of dropbox) it important to not include those other group in the group
set in auth_group_allowed.

I am asking myself if a task base privilege could not be better. I mean the
user has all the privilege he needs, but depending of the task he needs to
do, he could be restricted by a given function to certain actions...

Richard

On Fri, Sep 24, 2010 at 10:19 AM, Richard Vézina <
ml.richard.vez...@gmail.com> wrote:

> Here new version!
>
> - It check if user is allowed to change his role.
> - It protect in case the membership of the user is allowed to modify does
> not exist
> - It protect also in case the allowed group set is not define for a
> particular user (new table auth_group_allowed)
>
> What to do :
>
> Add this model :
>
> db.define_table('auth_group_allowed',
>     Field('id','id'),
>     Field('user_id','db.auth_user'),
>     Field('group_id','db.auth_group'),
>     Field('active_gr','boolean'),
>     migrate=False,
>     sequence_name='auth_group_allowed_id_seq')
>
> db.auth_group_allowed.user_id.requires=IS_IN_DB(db,'auth_user.id','%(first_name)s
> %(last_name)s (%(id)s)')
> db.auth_group_allowed.group_id.requires=IS_IN_DB(db,'auth_group.id','%(role)s
> (%(id)s)')
>
> For convenience add representation for auth_membership table :
>
> db.auth_membership.user_id.represent=\
>     lambda value: "%(first_name)s %(last_name)s (%(id)s)"
> %db.auth_user[value]
> db.auth_membership.group_id.represent=\
>     lambda value: "%(role)s (%(id)s)" %db.auth_group[value]
>
>
> Then this controller do the job :
>
> def chmembershiptr():
>     if auth.has_membership(auth.id_group('chrole')):
>         try:
>             if db(db.auth_group_allowed.user_id==auth.user.id)\
>
>  .select(db.auth_group_allowed.user_id,distinct=True).first().user_id==
> auth.user.id:
>                 active_gr=db((db.auth_group_allowed.user_id==auth.user.id
> )\
>                            & (db.auth_group_allowed.active_gr=='TRUE'))\
>
> .select(db.auth_group_allowed.group_id).first().group_id
>                 try:
>                     if db((db.auth_membership.group_id==active_gr)\
>                         & (db.auth_membership.user_id==auth.user.id))\
>
>  .select(db.auth_membership.user_id).first().user_id==auth.user.id:
>                             rows=db(db.auth_group_allowed.user_id==
> auth.user.id).select(db.auth_group_allowed.group_id)
>                             groupSet={}
>                             for row in rows:
>                                 authgrouprole=db(db.auth_group.id
> ==row.group_id).select(db.auth_group.role).first().role
>                                 groupSet[row.group_id]=authgrouprole
>                             chmbshp = SQLFORM.factory(
>                                 Field('user_id', writable=False,
> readable=False),
>                                 Field('group_id',
> requires=IS_IN_SET(groupSet),\
>
>  widget=SQLFORM.widgets.radio.widget,\
>                                                   default=active_gr))
>                             if chmbshp.accepts(request.vars, session,
> keepvalues=True):
>                                 response.flash = T('form accepted')
>                                 db((db.auth_group_allowed.user_id==
> auth.user.id)\
>                                  &
> (db.auth_group_allowed.active_gr=='TRUE')).update(active_gr='FALSE')
>                                 db((db.auth_group_allowed.user_id==
> auth.user.id)\
>                                  &
> (db.auth_group_allowed.group_id==chmbshp.vars.group_id)).update(active_gr='TRUE')
>
>  db((db.auth_membership.group_id==active_gr)\
>                                  & (db.auth_membership.user_id==
> auth.user.id))\
>                                  .update(group_id=chmbshp.vars.group_id)
>                             elif chmbshp.errors:
>                                 response.flash = T('form has errors')
>                             return dict(chmbshp=chmbshp)
>                 except AttributeError:
>                     return dict(chmbshp='You are not allowed (Permission
> denied : sync role)')
>         except AttributeError:
>             return dict(chmbshp='You are not allowed (Permission denied :
> no alternate role)')
>     else:
>         return dict(chmbshp='You are not allowed (Permission denied :
> chrole)')
>
> I will try to make a web2py slice in the near future...
>
> Any suggestions are wellcome.
>
> Now I must find a way to tell the user which group he is permanently
>
>
> Richard
>
>
> On Thu, Sep 23, 2010 at 4:26 PM, Richard Vézina <
> ml.richard.vez...@gmail.com> wrote:
>
>> New solution much cleaner since the user does not needing to edit the
>> auth_membership table :
>>
>>
>> def chmembershiptr():
>>     try:
>>         if db(db.auth_group_allowed.user_id==auth.user.id)\
>>
>>  .select(db.auth_group_allowed.user_id,distinct=True).first().user_id==
>> auth.user.id:
>>             if auth.has_membership(auth.id_group('technician'))\
>>              or auth.has_membership(auth.id_group('coordinator'))\
>>             or auth.has_membership(auth.id_group('admin')):
>>                 active_gr=db((db.auth_group_allowed.user_id==auth.user.id
>> )\
>>                                 &
>> (db.auth_group_allowed.active_gr=='TRUE'))\
>>
>>  .select(db.auth_group_allowed.group_id).first().group_id
>>                 membershipID=db((db.auth_membership.group_id==active_gr)\
>>                                 & (db.auth_membership.user_id==
>> auth.user.id))\
>>                                 .select(db.auth_membership.id).first().id
>>                 rows=db(db.auth_group_allowed.user_id==auth.user.id
>> ).select(db.auth_group_allowed.group_id)
>>                 groupSet={}
>>                 for row in rows:
>>                     authgrouprole=db(db.auth_group.id
>> ==row.group_id).select(db.auth_group.role).first().role
>>                     groupSet[row.group_id]=authgrouprole
>>                 chmbshp = SQLFORM.factory(
>>                     Field('user_id', writable=False, readable=False),
>>                     Field('group_id', requires=IS_IN_SET(groupSet),\
>>
>>  widget=SQLFORM.widgets.radio.widget,\
>>                                       default=active_gr))
>>                 if chmbshp.accepts(request.vars, session):
>>                     response.flash = 'form accepted'
>>                     session.user_id = auth.user.id
>>                     session.group_id = chmbshp.vars.group_id
>>                     db((db.auth_group_allowed.user_id==auth.user.id)\
>>                                 &
>> (db.auth_group_allowed.active_gr=='TRUE')).update(active_gr='FALSE')
>>                     db((db.auth_group_allowed.user_id==auth.user.id)\
>>                                 &
>> (db.auth_group_allowed.group_id==chmbshp.vars.group_id)).update(active_gr='TRUE')
>>                      db((db.auth_membership.group_id==active_gr)\
>>                                 & (db.auth_membership.user_id==
>> auth.user.id))\
>>                                 .update(group_id=chmbshp.vars.group_id)
>>                 elif chmbshp.errors:
>>                     response.flash = 'form has errors'
>>                 return dict(chmbshp=chmbshp)
>>     except AttributeError:
>>         pass
>>
>> Richard
>>
>>
>> On Thu, Sep 23, 2010 at 3:05 PM, Richard Vézina <
>> ml.richard.vez...@gmail.com> wrote:
>>
>>> I had syntax error :
>>>
>>> @auth.requires_login()
>>> def chmembership():
>>>     try:
>>>         if db(db.auth_group_allowed.user_id==auth.user.id)\
>>>
>>>  .select(db.auth_group_allowed.user_id,distinct=True).first().user_id==
>>> auth.user.id:
>>>             if auth.has_membership(auth.id_group('technician'))\
>>>              or auth.has_membership(auth.id_group('coordinator'))\
>>>             or auth.has_membership(auth.id_group('admin')):
>>>                 active_gr=db((db.auth_group_allowed.user_id==
>>> auth.user.id)\
>>>                                 &
>>> (db.auth_group_allowed.active_gr=='TRUE'))\
>>>
>>>  .select(db.auth_group_allowed.group_id).first().group_id
>>>                 membershipID=db(
>>> (db.auth_membership.group_id==active_gr)\
>>>                                 & (db.auth_membership.user_id==
>>> auth.user.id))\
>>>                                  .select(db.auth_membership.id
>>> ).first().id
>>>                 rows=db(db.auth_group_allowed.user_id==auth.user.id
>>> ).select(db.auth_group_allowed.group_id)
>>>                 groupSet={}
>>>                 for row in rows:
>>>                     authgrouprole=db(db.auth_group.id
>>> ==row.group_id).select(db.auth_group.role).first().role
>>>                     groupSet[row.group_id]=authgrouprole
>>>                 db.auth_membership.group_id.requires=IS_IN_SET(groupSet)
>>>                 db.auth_membership.user_id.readable=\
>>>                 db.auth_membership.user_id.writable=False
>>>                 chmbshp =
>>> crud.update(db.auth_membership,membershipID,deletable=False)
>>>                 new_gr=db(db.auth_membership.id
>>> ==membershipID).select(db.auth_membership.group_id).first().group_id
>>>                 db(db.auth_group_allowed.user_id==auth.user.id\
>>>                                 and
>>> db.auth_group_allowed.active_gr=='TRUE').update(active_gr='FALSE')
>>>                 db(db.auth_group_allowed.user_id==auth.user.id\
>>>                                 and
>>> db.auth_group_allowed.group_id==new_gr).update(active_gr='TRUE')
>>>                 return dict(chmbshp=chmbshp, active_gr=active_gr,
>>> membershipID=membershipID, groupSet=groupSet)
>>>     except AttributeError:
>>>         pass
>>>
>>> There is a major threat with that design... The the permission to the
>>> auth_membership table has to be open to any user...
>>>
>>> The only other solution I can see for now is to triggering the change on
>>> the active_gr field of the added table auth_group_allowed...
>>>
>>> Richard
>>>
>>>
>>> On Wed, Sep 22, 2010 at 3:08 PM, Richard Vézina <
>>> ml.richard.vez...@gmail.com> wrote:
>>>
>>>> Forgot to "writable=False" :
>>>>
>>>> db.auth_membership.user_id.represent=\
>>>>     lambda value: "%(first_name)s %(last_name)s (%(id)s)"
>>>> %db.auth_user[value]
>>>> db.auth_membership.group_id.represent=\
>>>>     lambda value: "%(role)s (%(id)s)" %db.auth_group[value]
>>>>
>>>> db.define_table('auth_group_allowed',
>>>>     Field('id','id'),
>>>>     Field('user_id','db.auth_user'),
>>>>     Field('group_id','db.auth_group'),
>>>>     Field('active_gr','boolean'),
>>>>     migrate=False,
>>>>     sequence_name='auth_group_allowed_id_seq')
>>>>
>>>> db.auth_group_allowed.user_id.requires=IS_IN_DB(db,'auth_user.id','%(first_name)s
>>>> %(last_name)s (%(id)s)')
>>>> db.auth_group_allowed.group_id.requires=IS_IN_DB(db,'auth_group.id','%(role)s
>>>> (%(id)s)')
>>>>
>>>> @auth.requires_login()
>>>> def chmembership():
>>>>     try:
>>>>         if db(db.auth_group_allowed.user_id==auth.user.id)\
>>>>
>>>>  .select(db.auth_group_allowed.user_id,distinct=True).first().user_id==
>>>> auth.user.id:
>>>>             if auth.has_membership(auth.id_group('technician')) or
>>>> auth.has_membership(auth.id_group('coordinator')) or
>>>> auth.has_membership(auth.id_group('admin')):
>>>>                 active_gr=db(db.auth_group_allowed.user_id==
>>>> auth.user.id\
>>>>                                 and
>>>> db.auth_group_allowed.active_gr=='TRUE')\
>>>>
>>>>  .select(db.auth_group_allowed.group_id).first().group_id
>>>>                 membershipID=db(db.auth_membership.group_id==active_gr\
>>>>                                 and db.auth_membership.user_id==
>>>> auth.user.id)\
>>>>                                 .select(db.auth_membership.id
>>>> ).first().id
>>>>                 rows=db(db.auth_group_allowed.user_id==auth.user.id
>>>> ).select(db.auth_group_allowed.group_id)
>>>>                 groupSet={}
>>>>                 for row in rows:
>>>>                     authgrouprole=db(db.auth_group.id
>>>> ==row.group_id).select(db.auth_group.role).first().role
>>>>                     groupSet[row.group_id]=authgrouprole
>>>>                 db.auth_membership.group_id.requires=IS_IN_SET(groupSet)
>>>>                 db.auth_membership.user_id.writable=False
>>>>                 form = crud.update(db.auth_membership,membershipID)
>>>>                 new_gr=db(db.auth_membership.id
>>>> ==membershipID).select(db.auth_membership.group_id).first().group_id
>>>>                 db(db.auth_group_allowed.user_id==auth.user.id\
>>>>                                 and
>>>> db.auth_group_allowed.active_gr=='TRUE').update(active_gr='FALSE')
>>>>                 db(db.auth_group_allowed.user_id==auth.user.id\
>>>>                                 and
>>>> db.auth_group_allowed.group_id==new_gr).update(active_gr='TRUE')
>>>>                 return dict(form=form, active_gr=active_gr,
>>>> membershipID=membershipID, groupSet=groupSet)
>>>>     except AttributeError:
>>>>         redirect(URL(request.application,'accueil','index'))
>>>>         session.flash = T('invalid request')
>>>>
>>>> Thanks.
>>>>
>>>> Richard
>>>>
>>>> On Wed, Sep 22, 2010 at 2:53 PM, mdipierro <mdipie...@cs.depaul.edu>wrote:
>>>>
>>>>> will look asap. Thank you.
>>>>>
>>>>> On Sep 22, 11:49 am, Richard Vézina <ml.richard.vez...@gmail.com>
>>>>> wrote:
>>>>> > Here an improved version of the controller that takes care if user
>>>>> has
>>>>> > membership to differents groups. The "try" is to check if the user
>>>>> has a set
>>>>> > of group allowed... It could be better in the future to make a
>>>>> function
>>>>> > "has_group_allowed".
>>>>> >
>>>>> > You need to add this model :
>>>>> >
>>>>> > db.define_table('auth_group_allowed',
>>>>> >     Field('id','id'),
>>>>> >     Field('user_id','db.auth_user'),
>>>>> >     Field('group_id','db.auth_group'),
>>>>> >     Field('active_gr','boolean'),
>>>>> >     migrate=False,
>>>>> >     sequence_name='auth_group_allowed_id_seq')
>>>>> >
>>>>> > db.auth_group_allowed.user_id.requires=IS_IN_DB(db,'auth_user.id
>>>>> ','%(first_name)s
>>>>> > %(last_name)s (%(id)s)')
>>>>> > db.auth_group_allowed.group_id.requires=IS_IN_DB(db,'auth_group.id
>>>>> ','%(role)s
>>>>> > (%(id)s)')
>>>>> >
>>>>> > Then configure your RBAC correctly... Add to user you want the
>>>>> permission to
>>>>> > change his role by adding the set of allowed roles he is allowed.
>>>>> Then
>>>>> > specify wich role he is already in or the function chmembership will
>>>>> fix it
>>>>> > automatically anyway at first execution.
>>>>> >
>>>>> > Here the function :
>>>>> >
>>>>> > @auth.requires_login()
>>>>> > def chmembership():
>>>>> >     try:
>>>>> >         if db(db.auth_group_allowed.user_id==auth.user.id)\
>>>>> >
>>>>> >
>>>>>  .select(db.auth_group_allowed.user_id,distinct=True).first().user_id==
>>>>> > auth.user.id:
>>>>> >             if auth.has_membership(auth.id_group('technician')) or
>>>>> > auth.has_membership(auth.id_group('coordinator')) or
>>>>> > auth.has_membership(auth.id_group('admin')):
>>>>> >                 active_gr=db(db.auth_group_allowed.user_id==
>>>>> auth.user.id\
>>>>> >                                 and
>>>>> > db.auth_group_allowed.active_gr=='TRUE')\
>>>>> >
>>>>> >  .select(db.auth_group_allowed.group_id).first().group_id
>>>>> >
>>>>> membershipID=db(db.auth_membership.group_id==active_gr\
>>>>> >                                 and db.auth_membership.user_id==
>>>>> auth.user.id
>>>>> > )\
>>>>> >                                 .select(db.auth_membership.id
>>>>> ).first().id
>>>>> >                 rows=db(db.auth_group_allowed.user_id==auth.user.id
>>>>> > ).select(db.auth_group_allowed.group_id)
>>>>> >                 groupSet={}
>>>>> >                 for row in rows:
>>>>> >                     authgrouprole=db(db.auth_group.id
>>>>> > ==row.group_id).select(db.auth_group.role).first().role
>>>>> >                     groupSet[row.group_id]=authgrouprole
>>>>> >
>>>>> db.auth_membership.group_id.requires=IS_IN_SET(groupSet)
>>>>> >                 form = crud.update(db.auth_membership,membershipID)
>>>>> >                 new_gr=db(db.auth_membership.id
>>>>> > ==membershipID).select(db.auth_membership.group_id).first().group_id
>>>>> >                 db(db.auth_group_allowed.user_id==auth.user.id\
>>>>> >                                 and
>>>>> > db.auth_group_allowed.active_gr=='TRUE').update(active_gr='FALSE')
>>>>> >                 db(db.auth_group_allowed.user_id==auth.user.id\
>>>>> >                                 and
>>>>> > db.auth_group_allowed.group_id==new_gr).update(active_gr='TRUE')
>>>>> >                 return dict(form=form, active_gr=active_gr,
>>>>> > membershipID=membershipID, groupSet=groupSet)
>>>>> >     except AttributeError:
>>>>> >         redirect(URL(request.application,'default','index'))
>>>>> >         session.flash = T('invalid request')
>>>>> >
>>>>> > It is not correctly tested so there is no garranty ;-)
>>>>> >
>>>>> > I appreciate feed back!
>>>>> >
>>>>> > Regards
>>>>> >
>>>>> > Richard
>>>>> >
>>>>> > On Tue, Sep 21, 2010 at 7:09 PM, Richard Vézina <
>>>>> ml.richard.vez...@gmail.com
>>>>> >
>>>>> > > wrote:
>>>>> > > Hello Massimo,
>>>>> >
>>>>> > > Here what I found as a temporarily solution :
>>>>> >
>>>>> > > I made a auth_group_allowed that is a m2m relation between
>>>>> auth_user and
>>>>> > > auth_group. So, we can attribute each user a set of groups in which
>>>>> he is
>>>>> > > allowed to change with.
>>>>> >
>>>>> > > Then this controller can let the user pick the group he want :
>>>>> >
>>>>> > > @auth.requires_login()
>>>>> > > def chmembership():
>>>>> > >     j=db(db.auth_membership.user_id==auth.user.id).select(
>>>>> > > db.auth_membership.id).first().id
>>>>> > >     rows=db(db.auth_group_allowed.user_id==auth.user.id
>>>>> > > ).select(db.auth_group_allowed.group_id)
>>>>> > >     groupSet={}
>>>>> > >     for row in rows:
>>>>> > >         authgrouprole=db(db.auth_group.id
>>>>> > > ==row.group_id).select(db.auth_group.role).first().role
>>>>> > >         groupSet[row.group_id]=authgrouprole
>>>>> > >     db.auth_membership.group_id.requires=IS_IN_SET(groupSet)
>>>>> > >     form = crud.update(db.auth_membership,j)
>>>>> >
>>>>> > >     return dict(form=form, j=j, groupSet=groupSet)
>>>>> >
>>>>> > > It's just the beginning since I can't handle the case were a user
>>>>> is
>>>>> > > involve in more then one group for now.
>>>>> >
>>>>> > > Please comment?
>>>>> >
>>>>> > > Regards
>>>>> >
>>>>> > > Richard
>>>>> >
>>>>> > > On Fri, Sep 17, 2010 at 9:56 AM, mdipierro <
>>>>> mdipie...@cs.depaul.edu>wrote:
>>>>> >
>>>>> > >> no and it is very much needed. Any takers?
>>>>> >
>>>>> > >> On Sep 17, 8:50 am, Richard Vézina <ml.richard.vez...@gmail.com>
>>>>> > >> wrote:
>>>>> > >> > Hello,
>>>>> >
>>>>> > >> > I need to let some of my user changing of membership into a
>>>>> plage of
>>>>> > >> > existing members number. Is there mechanism already existing in
>>>>> web2py
>>>>> > >> or do
>>>>> > >> > I have to program it from scratch?
>>>>> >
>>>>> > >> > Thanks
>>>>> >
>>>>> > >> > Richard
>>>>> >
>>>>> >
>>>>>
>>>>
>>>>
>>>
>>
>

Reply via email to