Forum OpenACS Development: Group definitions and use
All of the users can run a query on a specific device or look at the
history of the queries on the specific device.
The way I have designed my pages is the following:
Going to the main page will check to see if you're authorized
Depending on group you're in you can see links. Then when a
supervisor, manager or admin go to add users the drop down will be
populated with more options if the user has the authority to add
those types of users. The problem I have is the following:
In my package-create.sql I define new groups and their permissions but apparently I am not doing this correctly because when I go to group/group type administration my groups are not listed there. However, they are in the Oracle database. I have a good grasp of how the permissions work, it's the coding part that's getting the best of me...If anyone has any suggestions, links or examples I will gladly follow up on them..
Thanks, Nick
Graeme
We had a brownout and the server the files are on isn't configured to launch SSHd on boot...
I did manage to figure out a couple of things, but I think there should be a few extra additions to my create.sql to make the relationships since my groups are being created
Your best bet is to look carefully at the existing ACS login and admin pages that create users and groups, and do it the same way.
But for comparison, here's some Oracle PL/SQL code that I used in testing an ACS 4.2 site. If I remember correctly, this code creates users and groups exactly the same way as the ACS 4.2 UI pages do, and it also expunges them from the system cleanly and completely. (I don't know if any of this low level user/group stuff has been changed for OpenACS 4, but I suspect not.)
Creates a test user and group:
declare v_group_id integer; v_person_id integer; v_rel_id integer; begin -- Create company A: v_group_id := p_account.new( v_account_code => 'A' ,v_context_id => p_const.package_id_is ); v_person_id := acs.add_user ( email => 'x@a.com', first_names => 'X', last_name => 'X', password => 'X', salt => 'X' ); -- add X into A v_rel_id := membership_rel.new( object_id_one => v_group_id ,object_id_two => v_person_id ); end; / show errors
Deletes the test user and group:
(Now, why this calls acs_group.delete instead of p_account.delete, I don't know. Probably that's a bug.)
declare test_users pl_list.integer_list; test_groups pl_list.integer_list; test_parties pl_list.integer_list; begin select party_id bulk collect into test_users from parties where email in ('x@a.com', 'y@b.com') ; select party_id bulk collect into test_groups from parties where party_id in ( select account_id from p_accounts where account_code in ('A', 'B') ); select party_id bulk collect into test_parties from parties where email in ('x@a.com', 'y@b.com') or party_id in ( select account_id from p_accounts where account_code in ('A', 'B') ); for i in test_groups.first .. test_groups.last loop acs_group.delete(test_groups(i)); -- Note that deleting the group also deletes the membership_rels for -- the group, so we don't have to do it explicitly - imagine that! end loop; for i in test_users.first .. test_users.last loop for j in ( select rel_id from acs_rels where rel_type = 'membership_rel' and object_id_two = test_users(i) ) loop membership_rel.delete(j.rel_id); end loop; delete from acs_permissions p where p.object_id = test_users(i) or p.grantee_id = test_users(i) ; acs_user.delete(test_users(i)); -- Note that acs.remove_user simply delets the row from the users table, -- which is not what we want! end loop; end; / show errors
Some other stuff:
Of course, I'd extended the ACS groups table with a "p_accounts" table, so here's the part that actually calls the ACS group create function:
create or replace package body p_account is function new ( v_account_code in p_accounts.account_code%TYPE -- AKA group_name: ,v_account_pretty_name in groups.group_name%TYPE default null ,v_allow_auto_join_p in p_accounts.allow_auto_join_p%TYPE default 't' ,v_account_id in p_accounts.account_id%TYPE default null ,v_creation_date in acs_objects.creation_date%TYPE default sysdate ,v_creation_user in acs_objects.creation_user%TYPE default null ,v_creation_ip in acs_objects.creation_ip%TYPE default null ,v_context_id in acs_objects.context_id%TYPE default null ) return p_accounts.account_id%TYPE is v_id integer; w_account_pretty_name groups.group_name%TYPE; begin if v_account_pretty_name is null then w_account_pretty_name := v_account_code; else w_account_pretty_name := v_account_pretty_name; end if; v_id := acs_group.new( group_id => v_id ,object_type => 'p_account' ,creation_date => v_creation_date ,creation_user => v_creation_user ,creation_ip => v_creation_ip ,context_id => v_context_id ,group_name => w_account_pretty_name ); insert into p_accounts ( account_id, account_code, address_id ,allow_auto_join_p ) values ( v_id, v_account_code, null ,v_allow_auto_join_p ); return v_id; end new; procedure delete ( v_account_id in p_accounts.account_id%TYPE ) is begin -- Our application logic says that any address mapped directly to the -- account belongs ONLY to that account, so if we're deleting the account -- delete the address too: delete from p_addresses where address_id = ( select address_id from p_accounts where account_id = v_account_id ); delete from p_accounts where account_id = v_account_id; delete from acs_permissions p where p.object_id = v_account_id or p.grantee_id = v_account_id ; acs_group.delete(v_account_id); end delete; end p_account; / show errors
One of the questions I have about your delete stuff is:
Does it actually remove the user from the system? And does it keep the data created by that user intact?
One of my current problems is that when I try to "delete" a user in OpenACS it simply marks them as "inactive" and hides them but they can be "un-deleted". So if a different person gets the same e-mail address I can't add them to the system.
My code for creating user types:
--create priviledged users here --first create the manager declare v_group_id integer; default_context acs_objects.object_id%TYPE; begin default_context := acs.magic_object_id('default_context'); select count(group_id) into v_group_id from groups where group_name='Manager'; if v_group_id = 0 then v_group_id :=acs_group.new (group_name => 'Manager'); else select group_id into v_group_id from groups where group_name='Manager'; end if; acs_privilege.create_privilege ( 'manager' ); acs_privilege.add_child( 'manager' ); acs_permission.grant_permission( default_context, v_group_id, 'manager'); end; / show errorsAnd a supervisor which is identical to above but with 'Supervisor' instead of 'Manager'
does NOT preserve their content. We used very similar code for load
testing, and we sure wouldn't have wanted to preserve all that
"content"! In fact, it was important to delete it all cleanly so that
I could change the number of users and groups or whatever and try it
all again.
Re. the ACS "delete" function - that's what "delete a user" does by
design. It is perhaps poorly named. Note that a user may in fact
delete himself, and then undelete himself, with no adverse effects.
There is "nuke a user", but as you've noticed, there is no "really
delete a user but preserve content".
I've never messed around with the user and group type features of ACS
4, so I can't really comment there.