Hi!
>> > > Which steps, and in which order, do we have to follow?
>> >
>> > You'd need to apply fireroles to roles.
>> [...]
>>
>> Oh, great, it works! Thanks so much. ;-)
>
> Well, not really. After applying it to our production site, only
> superadmin users could access those records and collections.
>
> You wrote that «First thing is to create the groups and add people to
> them»,
Your initial description was refering to groups, I think.
They are not roles. A role can be applied to a group,
however.
> but, in fact, we don't have groups, we have roles.
Then the fire role does not work as it refers to groups. If
you use the roles only you'd need to hook up the users to
the role. In our setup, however, it's much easier to handle
if we add users to groups and have roles that apply to
those groups. (Mainly, casue we get a lot of external groups
via LDAP auth, and because we don't want to redo all the
user handling LDAP does already.)
> After browsing all related pages, in our 1.1.2 system and
> in github 1.1 branch, we don't see any group related
> management, except for a lonely «list groups» page that
> seems obsolete, a leftover from older versions of Invenio.
Not really. /yourgroups/ allows you to create groups. Actually, every user can
add groups. Be careful in case you add restrictions based on groups that those
groups are owned by admin. If you use external groups create local groups of
the same name as otherwise people could highjack them.
> So, we did create a new role with the list of «allow groups X», «allow
> groups Y», etc, that you wrote in your mail. We added the
> viewrestrcol with our collections. The result was that all those
> collections were restricted for everybody except for superadmin. We
> tried to simplify our definitions to a single role, but we didn't
> succeed.
If you have no group an no one in the group, this has to be that way, right?
> We also tried to change «allow groups X» for «allow roles X». Again,
> no luck. Only superadmin can access those restricted collections.
>
> Again, are we dealing with roles or groups? Can we manage groups, in
> Invenio 1.1.2?
You can have groups in invenio 1.1 (we use them extensively)
Here is a snippet of code we use to add groups to Admin
----------------------------------------------------------------------
def RegisterWorkflowGroups(GroupDict):
"""
Register groups for workflow. All these groups belong to "admin" (uid=1).
They need to exist and they need to belong to admin to avoid privilege
escalation. Note that we use fireroles in our workflow based on those
groups.
Note that we use FIXED names:
- EDITORS : all editors at the institute level. They approve files from
user sumissions to the VDBINPRINT collection
- STAFF : editors at the library that approve EDITOR approvals to the
final VDB collection
- STAFFNOMAIL : Users with STAFF rights but no baskets, alerts and change
request notifications
Additionally, we create workflow baskets and alerts for groups of
institutes. The group ID for those things is the same as for STAFF.
This is used at RWTH for their workflow.
@type Groups: dictionary
@param Groups: Dictionary of lists containing groupname as key and
description as value.
"""
logger.info('Registring groups for workflow')
adminuid = 1 # owner of all groups
policy = 'VM' # Join policy requires approval by admin
rootGroups = groupdb.get_groups(adminuid)
GID = {}
# Extact GIDs for groups matching our names
for row in rootGroups:
for groupname in GroupDict:
if row[1] == groupname:
GID[groupname] = row[0]
for name in GID:
if name in GID:
logger.info("Group %s already belonged to admin." % name)
else:
grp = groupdb.get_group_id(name)
if grp != ():
logger.error("Some user tried to Hijack our Workflow Groups %s"
% name)
groupdb.delete_group_and_members(grp)
for groupname in GroupDict:
if (not groupname in GID) or (GID[groupname] == 0):
logger.info("Inserting group %s:" % groupname)
GID[groupname] = groupdb.insert_new_group(adminuid, groupname,
GroupDict[groupname], policy)
# Make sure admin is always admin of these groups
for groupname in GID:
groupdb.delete_member(GID[groupname], adminuid)
groupdb.insert_new_member(adminuid, GID[groupname], 'A')
return GID
def AddUser2Group(gid, uid, mail, inst, role):
"""
Add users to the proper group GID. Additionally, add the user to local
mimic-groups called "inst [loginmethod]", which prevents other users to
create such a group locally and thus get privileges on restricted
collections. In case the mimic groups don't exist, create them as well.
@param gid: groupid
@param uid: userid
@param role: name for display
@param inst: institues id
"""
# Do not process ADMIN here as otherwise she will loose the group and
# just become a member!
if uid > 1:
logger.info("Adding user to %s group:" % role)
logger.info(" %s: %s (%s)" % (inst, mail, uid))
groupdb.delete_member(gid, uid)
groupdb.insert_new_member(uid, gid,
CFG_WEBSESSION_USERGROUP_STATUS["MEMBER"])
logger.info(" Adding to local groups...")
for method in CFG_EXTERNAL_AUTHENTICATION.keys():
if method == 'Local':
# We do nothing for Local logins, we just want to add
# our editors/staff to all external mimic groups to ensure she
# gets proper rights in case she belongs to more than one
# institue.
pass
else:
localgrp = inst + ' ' + '[' + method + ']'
try:
localGID = groupdb.get_group_id(localgrp)[0][0]
except:
logger.info(" Local group ", localgrp, \
" did not exist. Adding...")
localGID = groupdb.insert_new_group(1, localgrp,
inst, 'VM')
logger.info(" %s = %s" % (localgrp, localGID))
groupdb.delete_member(localGID, uid)
groupdb.insert_new_member(uid, localGID,
CFG_WEBSESSION_USERGROUP_STATUS["MEMBER"])
return
----------------------------------------------------------------------
Note: role here does not refer to invenios role management
but the role people have in our workflow like Users,
Editors, Staff. In the end, those guys are connected to
roles like hgf_user, hgf_editor, hgf_staff. Sorry for this
naming clash.
For collection cration we use something similar that then
also registers roles that have the view_restr_col
permissions on the collection in question. Unfortunatly, the
code that does this is a bit heavy and recursive :S as it
hooks up with our institute authorities to keep track of
proper subordination and rights. Bascially, the whole tree
of restricted collections you can see here
https://bib-pubdb1.desy.de/collection/InstColl?ln=en
is restricted based on group membership.
I'll try to extract the essentials to give you an idea
----------------------------------------------------------------------
rolename = 'I-' + colIntName
roledesc = 'Institute user for ' + colIntName + '(' + colShortName +')'
if instID is None:
instID = ''
firerule = ''
for method in CFG_EXTERNAL_AUTHENTICATION.keys():
if method == 'Local':
# We do nothing for Local this key is not usefull
pass
elif method == 'Robot':
# We do nothing for Robots.
pass
elif method == 'ZRobot':
# We do nothing for ZRobots.
pass
else:
# Setup roles
grouppostfix = '[' + method + ']' # Needed for fireroles
grpname = instID + ' ' + grouppostfix
firerule += "allow groups '" + grpname + "'" + '\n'
firerule += "allow groups 'STAFF'\n"
firerule += "allow groups 'STAFFNOMAIL'\n"
res = acc_delete_role(None, rolename)
info(" %s roles deleted.", str(res))
if colQuery:
# This collection does not have children, since we have a query
# associated
info(""" Adding role:
%s
%s
%s""", rolename,roledesc,firerule)
res = acc_add_role(rolename, roledesc,
firerole_def_ser=serialize(compile_role_definition(firerule)),
firerole_def_src=firerule)
if res == 0:
info(" %s already exists.", rolename)
else:
info(" %s created", rolename)
acc_add_role_action_arguments_names(rolename,
'viewrestrcoll', collection=colIntName)
----------------------------------------------------------------------
And later on for the group generation:
----------------------------------------------------------------------
for method in CFG_EXTERNAL_AUTHENTICATION.keys():
if not robot, zrobot, local:
groupowneruid_groups = groupdb.get_groups_by_user_status(1, 'A')
# group name is [$i][1]
isowner = False
if groupdb.group_name_exist(grpname):
# check if the group is owned by groupowneruid, if not, drop
# it else keep it and do nothing
for g in groupowneruid_groups:
if g[1] == grpname:
isowner = True
if isowner:
debug("[OK ] Group ", grpname,
" exists and is owned by uid", groupowneruid)
else:
error("[ERR] Group ", grpname,
" exists, BUT HAS WRONG OWNERSHIP! Deleting...")
grpid = groupdb.get_group_id(grpname)[0][0]
groupdb.delete_group_and_members(grpid)
info( " Adding the group for uid ", groupowneruid)
groupdb.insert_new_group(groupowneruid, grpname,
colShortName, grouppolicy)
else:
# A new group is born.
info( "Adding group ", grpname)
groupdb.insert_new_group(groupowneruid, grpname,
colShortName,
grouppolicy)
----------------------------------------------------------------------
HTH :)
--
Kind regards,
Alexander Wagner
Deutsches Elektronen-Synchrotron DESY
Library and Documentation
Building 01d Room OG1.444
Notkestr. 85
22607 Hamburg
phone: +49-40-8998-1758
fax: +49-40-8994-1758
e-mail: [email protected]