Forum OpenACS Improvement Proposals (TIPs): Re: TIP #81: User Merge account support
Posted by
Enrique Catalan
on 06/06/05 07:21 PM
Andrew: the new SC operation is required because we need to manage the merge operation in authentication. By now, we have two implementations; One for local and the other one for auth-ldap.
This is the part of the merge process where we have to be careful. This time i'm posting some tcl code to get it clearly:
Adding the new operation :
ad_proc -private auth::local::authentication::register_impl {} { Register the 'local' implementation of the 'auth_authentication' service contract. @return impl_id of the newly created implementation. } { set spec { contract_name "auth_authentication" owner "acs-authentication" name "local" pretty_name "Local" aliases { MergeUser auth::local::authentication::MergeUser Authenticate auth::local::authentication::Authenticate GetParameters auth::local::authentication::GetParameters } } return [acs_sc::impl::new_from_spec -spec $spec] }
One implementation is:
ad_proc -private auth::local::authentication::MergeUser { from_user_id to_user_id {authority_id ""} } { Merge operation of the auth_authentication Here we will merge the basic user info and merge the email and all related with the username } { ns_log Notice "Starting local merge user" db_transaction { ns_log Notice "Merging user portrait" if { ( ![db_0or1row to_user_portrait { *SQL*} ] ) && ( [db_0or1row from_user_portrait { *SQL* } ] ) } { db_dml upd_portrait { *SQL* } ns_log Notice "Merging user portrait" } # get the permissions of the from_user_id # and grant them to the to_user_id db_foreach getfromobjs { *SQL* } { # revoke the permissions from from_user_id permission::revoke -object_id $from_oid -party_id $from_user_id -privilege $from_priv if { ![db_string getdata { *SQL* } ] } { # grant the permissions to to_user_id permission::grant -object_id $from_oid -party_id $to_user_id -privilege $from_priv } } lappend res "acs_permissions merged" ns_log notice " Merging acs_objects ..." db_dml acs_objs_upd { *SQL* } set msg "acs_objects merged" ns_log notice $msg lappend res $msg ns_log notice " Merging user,names and email..." ns_log Notice " Deleting user $from_user_id. It will be merged with user_id $to_user_id" set new_username "merged_$from_user_id" append new_username "_$to_user_id" # Shall we keep the domain for email? # Actually, the username 'merged_xxx_yyy' # won't be an email, so we will keep it without # domain set new_email "$new_username" set rel_id [db_string getrelid { *SQL* }] membership_rel::change_state -rel_id $rel_id -state "merged" ns_log Notice " state changed, rel_id $rel_id, from_user_id ; $from_user_id" acs_user::update -user_id $from_user_id -username "$new_username" -screen_name "$new_username" party::update -party_id $from_user_id -email "$new_email" set msg " username and member state done" ns_log notice $msg lappend res $msg } lappend res "local MergeUser is complete" ns_log notice $res return $res }
The script for upgrade is in .../acs-authentication/tcl/apm-callback-procs.tcl, the code is in auth::after_upgrade callback and it is:
. .. ... 5.1.4 5.1.5 { db_transaction { # Following the above steps to upgrade a SC # I will add support to MergeUser operation (quio) ns_log notice "Starting Upgrade" acs_sc::contract::operation::new \ -contract_name "auth_authentication" \ -operation "MergeUser" \ -input { from_user_id:integer to_user_id:integer authority_id:integer } \ -output {} \ -description "Merges two accounts given the user_id of each one" acs_sc::impl::alias::new \ -contract_name "auth_authentication" \ -impl_name "LDAP" \ -operation "MergeUser" \ -alias "auth::ldap::authentication::MergeUser" \ acs_sc::impl::alias::new \ -contract_name "auth_authentication" \ -impl_name "local" \ -operation "MergeUser" \ -alias "auth::local::authentication::MergeUser" \ ns_log notice "Finishing upgrade" } }