auth::create_local_account (public)

 auth::create_local_account [ -user_id user_id ] \
    -authority_id authority_id [ -username username ] -array array

Defined in packages/acs-authentication/tcl/authentication-procs.tcl

Create the local account for a user.

Switches:
-user_id (optional)
-authority_id (required)
-username (optional)
-array (required)
Name of an array containing the registration elements to update. Fields are specified by auth::get_all_registration_elements
Returns:
Array list containing the following entries:
  • creation_status: ok, data_error, reg_error, failed_to_connect. Says whether user creation succeeded.
  • creation_message: Information about the problem, to be relayed to the user. If creation_status is not ok, then either creation_message or element_messages is guaranteed to be nonempty, and both are guaranteed to be in the array list. May contain HTML.
  • element_messages: list of (element_name, message, element_name, message, ...) of errors on the individual registration elements. to be relayed on to the user. If creation_status is not ok, then either creation_message or element_messages is guaranteed to be nonempty, and both are guaranteed to be in the array list. Cannot contain HTML.
  • account_status: ok, closed. Only set if creation_status was ok, this says whether the newly created account is ready for use or not. For example, we may require approval, in which case the account would be created but closed.
  • account_message: A human-readable explanation of why the account was closed. May include HTML, and thus shouldn't be quoted. Guaranteed to be nonempty if account_status is not ok.
All entries are guaranteed to always be set, but may be empty.
See Also:

Partial Call Graph (max 5 caller/called nodes):
%3 test_auth_use_email_for_login_p auth_use_email_for_login_p (test acs-authentication) auth::create_local_account auth::create_local_account test_auth_use_email_for_login_p->auth::create_local_account _ _ (public) auth::create_local_account->_ acs_user::get_by_username acs_user::get_by_username (public) auth::create_local_account->acs_user::get_by_username acs_user::get_user_info acs_user::get_user_info (public) auth::create_local_account->acs_user::get_user_info ad_conn ad_conn (public) auth::create_local_account->ad_conn ad_log ad_log (public) auth::create_local_account->ad_log Class ::xo::Authorize Class ::xo::Authorize (public) Class ::xo::Authorize->auth::create_local_account auth::create_user auth::create_user (public) auth::create_user->auth::create_local_account auth::get_local_account auth::get_local_account (private) auth::get_local_account->auth::create_local_account auth::sync::job::action auth::sync::job::action (public) auth::sync::job::action->auth::create_local_account install::xml::action::create-user install::xml::action::create-user (public) install::xml::action::create-user->auth::create_local_account

Testcases:
auth_use_email_for_login_p
Source code:
    upvar 1 $array user_info

    array set result {
        creation_status reg_error
        creation_message {}
        element_messages {}
        account_status ok
        account_message {}
        user_id {}
    }

    # Default all elements to the empty string
    foreach elm [get_all_registration_elements] {
        if { ![info exists user_info($elm)] } {
            set user_info($elm) {}
        }
    }

    # Validate data
    auth::validate_account_info  -authority_id $authority_id  -username $username  -user_array user_info  -message_array element_messages

    # Handle validation errors
    if { [array size element_messages] > 0 } {
        return [list  creation_status "data_error"  creation_message {}  element_messages [array get element_messages]  ]
    }

    # Admin approval
    set system_name [ad_system_name]
    set subsite_id [expr {[ns_conn isconnected] ? [ad_conn subsite_id] : [subsite::main_site_id]}]
    if { [parameter::get -package_id $subsite_id -parameter RegistrationRequiresApprovalP -default 0] } {
        set member_state "needs approval"
        set result(account_status) "closed"
        set result(account_message) [_ acs-subsite.Registration_Approval_Notice]
    } else {
        set member_state "approved"
    }

    set registration_requires_email_verification_p  [parameter::get  -package_id $subsite_id  -parameter RegistrationRequiresEmailVerificationP  -default 0]

    if { ![info exists user_info(email_verified_p)] || $user_info(email_verified_p) eq "" } {
        if {$registration_requires_email_verification_p} {
            set user_info(email_verified_p) "f"
        } else {
            set user_info(email_verified_p) "t"
        }
    }

    # We can generate a username ourselves when this is missing and
    # the system is configured to do so, but only if the account is
    # managed locally.
    if { $username eq "" && [auth::UseEmailForLoginP] } {
        set local_authority_id [auth::authority::local]
        set local_auth_impl_id [auth::authority::get_element  -authority_id $local_authority_id  -element "auth_impl_id"]

        set auth_impl_id [auth::authority::get_element  -authority_id $authority_id  -element "auth_impl_id"]

        set generate_username_p [expr {$local_auth_impl_id == $auth_impl_id}]
    } else {
        set generate_username_p false
    }

    if { $generate_username_p } {

        # Generate a username that is guaranteed to be unique.
        # Rather much work, but that's the best I could think of

        # Default to email
        set username [string tolower $user_info(email)]

        # Check if it already exists
        set existing_user_id [acs_user::get_by_username -authority_id $authority_id -username $username]

        # If so, add -2 or -3 or ... to make it unique
        if { $existing_user_id ne "" } {
            set match "${username}-%"
            set existing_usernames [db_list select_existing_usernames {
                select username
                from   users
                where  authority_id = :authority_id
                and    username like :match
            }]

            set number 2
            foreach existing_username $existing_usernames {
                if { [regexp "^${username}-(\\d+)\$" $existing_username match existing_number] } {
                    # matches the foo-123 pattern
                    if { $existing_number >= $number } {
                        set number [expr {$existing_number + 1}]
                    }
                }
            }
            set username "$username-$number"
            ns_log Notice "auth::create_local_account: user's email was already used as someone else's username, setting username to $username"
        }
    }

    set error_p 0
    ad_try {
        # We create the user without a password
        # If it's a local account, that'll get set later
        set user_id [auth::create_local_account_helper  $user_info(email)  $user_info(first_names)  $user_info(last_name)  {}  $user_info(secret_question)  $user_info(secret_answer)  $user_info(url)  $user_info(email_verified_p)  $member_state  $user_id  $username  $user_info(authority_id)  $user_info(screen_name)]

        # Update person.bio
        if { [info exists user_info(bio)] } {
            person::update  -person_id $user_id  -bio $user_info(bio)
        }
    } on error {errorMsg} {
        set error_p 1
    }

    if { $error_p || $user_id == 0 } {
        set result(creation_status) "failed_to_connect"
        set result(creation_message) [_ acs-subsite.Error_trying_to_register]
        ad_log Error "auth::create_local_account: Error creating local account."
        return [array get result]
    }

    set result(user_id) $user_id

    if { $username eq "" } {
        set username [acs_user::get_user_info  -user_id $user_id -element username]
    }
    set result(username) $username

    # Creation succeeded
    set result(creation_status) "ok"

    if {$registration_requires_email_verification_p} {
        set email $user_info(email)
        set result(account_status) "closed"
        set result(account_message) "<p>[_ acs-subsite.lt_Registration_informat_1]</p><p>[_ acs-subsite.lt_Please_read_and_follo]</p>"

        ad_try {
            auth::send_email_verification_email -user_id $user_id
        } on error {errorMsg} {
            ad_log Error "auth::create_local_account: Error sending out email verification email to email $email: $errorMsg"
            set auth_info(account_message) [_ acs-subsite.Error_sending_verification_mail]
        }
    }

    return [array get result]
Generic XQL file:
packages/acs-authentication/tcl/authentication-procs.xql

PostgreSQL XQL file:
packages/acs-authentication/tcl/authentication-procs-postgresql.xql

Oracle XQL file:
packages/acs-authentication/tcl/authentication-procs-oracle.xql

[ hide source ] | [ make this the default ]
Show another procedure: