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 <[email protected]
> 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 <
> [email protected]> 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 <
>> [email protected]> 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 <[email protected]>wrote:
>>>
>>>> will look asap. Thank you.
>>>>
>>>> On Sep 22, 11:49 am, Richard Vézina <[email protected]>
>>>> 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 <
>>>> [email protected]
>>>> >
>>>> > > 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 <[email protected]
>>>> >wrote:
>>>> >
>>>> > >> no and it is very much needed. Any takers?
>>>> >
>>>> > >> On Sep 17, 8:50 am, Richard Vézina <[email protected]>
>>>> > >> 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