auth::authenticate (public)
auth::authenticate [ -return_url return_url ] \ [ -authority_id authority_id ] [ -username username ] \ [ -email email ] -password password [ -persistent ] [ -no_cookie ] \ [ -first_names first_names ] [ -last_name last_name ] \ [ -host_node_id host_node_id ]
Defined in packages/acs-authentication/tcl/authentication-procs.tcl
Try to authenticate and login the user forever by validating the username/password combination, and return authentication and account status codes.
- Switches:
- -return_url (optional)
- If specified, this can be included in account status messages.
- -authority_id (optional)
- The ID of the authority to ask to verify the user. Defaults to local authority.
- -username (optional)
- Authority specific username of the user.
- -email (optional)
- User's email address. You must supply either username or email.
- -password (required)
- The password as the user entered it.
- -persistent (optional, boolean)
- Set this if you want a permanent login cookie
- -no_cookie (optional, boolean)
- Set this if you don't want to issue a login cookie
- -first_names (optional)
- -last_name (optional)
- -host_node_id (optional)
- Optional parameter used to determine the cookie domain from the host_node_map
- Returns:
- Array list with the following entries:
- auth_status: Whether authentication succeeded. ok, no_account, bad_password, auth_error, failed_to_connect
- auth_message: Human-readable message about what went wrong. Guaranteed to be set if auth_status is not ok. Should be ignored if auth_status is ok. May contain HTML.
- account_status: Account status from authentication server. ok, closed.
- account_url: A URL to redirect the user to. Could e.g. ask the user to update his password.
- account_message: Human-readable message about account status. Guaranteed to be set if auth_status is not ok and account_url is empty. If nonempty, must be relayed to the user regardless of account_status. May contain HTML. This proc is responsible for concatenating any remote and/or local account messages into one single message which can be displayed to the user.
- user_id: Set to local user_id if auth_status is ok.
- Partial Call Graph (max 5 caller/called nodes):
- Testcases:
- auth_authenticate, auth_use_email_for_login_p
Source code: # Login Brute Force Prevention set login_attempt_key "[ad_conn peeraddr]-[ad_conn subsite_id]" if { [::auth::login_attempts::threshold_reached_p -login_attempt_key $login_attempt_key] } { set auth_message [_ acs-authentication.Too_many_failed_login_attempts] return [list auth_status "failed_to_connect" auth_message $auth_message account_status "closed" account_message "[_ acs-subsite.Auth_internal_error]"] } # record login attempt ::auth::login_attempts::record -login_attempt_key $login_attempt_key if { $username eq "" } { if { $email eq "" } { set result(auth_status) "auth_error" if { [auth::UseEmailForLoginP] } { set result(auth_message) [_ acs-subsite.Email_required] } else { set result(auth_message) [_ acs-subsite.Username_required] } return [array get result] } set user_id [party::get_by_email -email $email] if { $user_id eq "" || ![acs_user::registered_user_p -user_id $user_id] } { set result(auth_status) "no_account" set result(auth_message) [_ acs-subsite.Unknown_email] return [array get result] } set user [acs_user::get_user_info -user_id $user_id] set authority_id [dict get $user authority_id] set username [dict get $user username] } else { # Default to local authority if { $authority_id eq "" } { set authority_id [auth::authority::local] } } # # initialize result with authentication and account keys # array set result {auth_status "n/a" auth_message "" account_status "n/a" account_message ""} ad_try { array set result [auth::authentication::authenticate -username $username -authority_id $authority_id -password $password] } on error {errorMsg} { set result(auth_status) failed_to_connect set result(auth_message) $errorMsg ad_log Error "auth::authenticate: error '$errorMsg' invoking authentication driver for authority_id = $authority_id: $::errorInfo" } # Returns: # result(auth_status) # result(auth_message) # result(account_status) # result(account_message) # Verify result/auth_message return codes switch $result(auth_status) { ok { # reset/unset failed login attempts counter after a successful authentication ::auth::login_attempts::reset -login_attempt_key $login_attempt_key # Continue below } no_account - bad_password - auth_error - failed_to_connect { if { $result(auth_message) eq "" } { array set default_auth_message { no_account {Unknown username} bad_password {Bad password} auth_error {Invalid username/password} failed_to_connect {Error communicating with authentication server} } set result(auth_message) $default_auth_message($result(auth_status)) } return [array get result] } default { ns_log Error "auth::authenticate: Illegal auth_status code '$result(auth_status)' returned from authentication driver for authority_id $authority_id ([auth::authority::get_element -authority_id $authority_id -element pretty_name])" set result(auth_status) "failed_to_connect" set result(auth_message) [_ acs-subsite.Auth_internal_error] return [array get result] } } # Verify remote account_info/account_message return codes switch $result(account_status) { ok { # Continue below } closed { if { $result(account_message) eq "" } { set result(account_message) [_ acs-subsite.Account_not_avail_now] } } default { ns_log Error "auth::authenticate: Illegal account_status code '$result(account_status)' returned from authentication driver for authority_id $authority_id ([auth::authority::get_element -authority_id $authority_id -element pretty_name])" set result(account_status) "closed" set result(account_message) [_ acs-subsite.Auth_internal_error] } } # # Save the remote account information for later # set remote_account_status $result(account_status) set remote_account_message $result(account_message) # # Clear out remote account_status and account_message # and initialize it with values that we can relay on later. # array set result {account_url "" account_status "" account_message "" user_id ""} # Map to row in local users table array set result [auth::get_local_account -return_url $return_url -username $username -authority_id $authority_id -email $email -first_names $first_names -last_name $last_name] # Returns: # result(account_status) # result(account_message) # result(account_url) # result(user_id) # Verify local account_info/account_message return codes switch $result(account_status) { ok { # Continue below } closed { if { $result(account_message) eq "" } { set result(account_message) [_ acs-subsite.Account_not_avail_now] } } default { ns_log Error "auth::authenticate: Illegal account_status code '$result(account_status)' returned from auth::get_local_account for authority_id $authority_id ([auth::authority::get_element -authority_id $authority_id -element pretty_name])" set result(account_status) "closed" set result(account_message) [_ acs-subsite.Auth_internal_error] } } # If the remote account was closed, the whole account is closed, regardless of local account status if {$remote_account_status eq "closed"} { set result(account_status) closed } if { $remote_account_message ne "" } { if { $result(account_message) ne "" } { # Concatenate local and remote account messages set local_account_message [auth::authority::get_element -authority_id $authority_id -element pretty_name] set result(account_message) [subst { <p>$local_account_message: $remote_account_message</p> <p>[ad_system_name]: $result(account_message)</p> }] } else { set result(account_message) $remote_account_message } } # # Issue login cookie if login was successful # and everything is ok with the account. # if { $result(auth_status) eq "ok" && !$no_cookie_p && $result(user_id) ne "" && $result(account_status) eq "ok" } { if {$host_node_id ne ""} { set cookie_domain [db_string get_mapped_host { select host from host_node_map where node_id = :host_node_id } -default ""] if {$cookie_domain eq ""} { ns_log warning "auth::authenticate: host_node_id $host_node_id was provided but is apparently not mapped" } } else { set cookie_domain "" } ns_log notice "auth::authenticate receives host_node_id $host_node_id domain <$cookie_domain>" ad_user_login -account_status $result(account_status) -cookie_domain $cookie_domain -forever=$persistent_p $result(user_id) } 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