• Publicity: Public Only All

authentication-procs.tcl

Automated tests for procs in tcl/authentication-procs.tcl

Location:
packages/acs-authentication/tcl/test/authentication-procs.tcl

Procedures in this file

Detailed information

_acs-authentication__auth__can_admin_system_without_authority_p (private)

 _acs-authentication__auth__can_admin_system_without_authority_p

Partial Call Graph (max 5 caller/called nodes):
%3 aa_equals aa_equals (public) aa_log aa_log (public) aa_log_result aa_log_result (public) aa_run_with_teardown aa_run_with_teardown (public) acs::test::user::create acs::test::user::create (public) _acs-authentication__auth__can_admin_system_without_authority_p _acs-authentication__auth__can_admin_system_without_authority_p _acs-authentication__auth__can_admin_system_without_authority_p->aa_equals _acs-authentication__auth__can_admin_system_without_authority_p->aa_log _acs-authentication__auth__can_admin_system_without_authority_p->aa_log_result _acs-authentication__auth__can_admin_system_without_authority_p->aa_run_with_teardown _acs-authentication__auth__can_admin_system_without_authority_p->acs::test::user::create

Testcases:
No testcase defined.

_acs-authentication__auth__delete_local_account (private)

 _acs-authentication__auth__delete_local_account

Partial Call Graph (max 5 caller/called nodes):
%3 aa_equals aa_equals (public) aa_false aa_false (public) aa_log aa_log (public) aa_log_result aa_log_result (public) aa_run_with_teardown aa_run_with_teardown (public) _acs-authentication__auth__delete_local_account _acs-authentication__auth__delete_local_account _acs-authentication__auth__delete_local_account->aa_equals _acs-authentication__auth__delete_local_account->aa_false _acs-authentication__auth__delete_local_account->aa_log _acs-authentication__auth__delete_local_account->aa_log_result _acs-authentication__auth__delete_local_account->aa_run_with_teardown

Testcases:
No testcase defined.

_acs-authentication__auth__get_all_registration_elements (private)

 _acs-authentication__auth__get_all_registration_elements

Partial Call Graph (max 5 caller/called nodes):
%3 aa_equals aa_equals (public) aa_log aa_log (public) aa_log_result aa_log_result (public) auth::get_all_registration_elements auth::get_all_registration_elements (public) _acs-authentication__auth__get_all_registration_elements _acs-authentication__auth__get_all_registration_elements _acs-authentication__auth__get_all_registration_elements->aa_equals _acs-authentication__auth__get_all_registration_elements->aa_log _acs-authentication__auth__get_all_registration_elements->aa_log_result _acs-authentication__auth__get_all_registration_elements->auth::get_all_registration_elements

Testcases:
No testcase defined.

_acs-authentication__auth__get_register_authority (private)

 _acs-authentication__auth__get_register_authority

Partial Call Graph (max 5 caller/called nodes):
%3 aa_equals aa_equals (public) aa_log aa_log (public) aa_log_result aa_log_result (public) aa_run_with_teardown aa_run_with_teardown (public) aa_silence_log_entries aa_silence_log_entries (public) _acs-authentication__auth__get_register_authority _acs-authentication__auth__get_register_authority _acs-authentication__auth__get_register_authority->aa_equals _acs-authentication__auth__get_register_authority->aa_log _acs-authentication__auth__get_register_authority->aa_log_result _acs-authentication__auth__get_register_authority->aa_run_with_teardown _acs-authentication__auth__get_register_authority->aa_silence_log_entries

Testcases:
No testcase defined.

_acs-authentication__auth__get_user_id (private)

 _acs-authentication__auth__get_user_id

Partial Call Graph (max 5 caller/called nodes):
%3 aa_equals aa_equals (public) aa_log aa_log (public) aa_log_result aa_log_result (public) aa_run_with_teardown aa_run_with_teardown (public) ad_conn ad_conn (public) _acs-authentication__auth__get_user_id _acs-authentication__auth__get_user_id _acs-authentication__auth__get_user_id->aa_equals _acs-authentication__auth__get_user_id->aa_log _acs-authentication__auth__get_user_id->aa_log_result _acs-authentication__auth__get_user_id->aa_run_with_teardown _acs-authentication__auth__get_user_id->ad_conn

Testcases:
No testcase defined.

_acs-authentication__auth__login_attempts (private)

 _acs-authentication__auth__login_attempts

Partial Call Graph (max 5 caller/called nodes):
%3 aa_equals aa_equals (public) aa_false aa_false (public) aa_log aa_log (public) aa_log_result aa_log_result (public) aa_true aa_true (public) _acs-authentication__auth__login_attempts _acs-authentication__auth__login_attempts _acs-authentication__auth__login_attempts->aa_equals _acs-authentication__auth__login_attempts->aa_false _acs-authentication__auth__login_attempts->aa_log _acs-authentication__auth__login_attempts->aa_log_result _acs-authentication__auth__login_attempts->aa_true

Testcases:
No testcase defined.

_acs-authentication__auth__refresh_login (private)

 _acs-authentication__auth__refresh_login

Partial Call Graph (max 5 caller/called nodes):
%3 aa_equals aa_equals (public) aa_log aa_log (public) aa_log_result aa_log_result (public) acs::test::http acs::test::http (public) acs::test::reply_has_status_code acs::test::reply_has_status_code (public) _acs-authentication__auth__refresh_login _acs-authentication__auth__refresh_login _acs-authentication__auth__refresh_login->aa_equals _acs-authentication__auth__refresh_login->aa_log _acs-authentication__auth__refresh_login->aa_log_result _acs-authentication__auth__refresh_login->acs::test::http _acs-authentication__auth__refresh_login->acs::test::reply_has_status_code

Testcases:
No testcase defined.

_acs-authentication__auth__self_registration (private)

 _acs-authentication__auth__self_registration

Partial Call Graph (max 5 caller/called nodes):
%3 aa_equals aa_equals (public) aa_log aa_log (public) aa_log_result aa_log_result (public) aa_section aa_section (public) acs::test::http acs::test::http (public) _acs-authentication__auth__self_registration _acs-authentication__auth__self_registration _acs-authentication__auth__self_registration->aa_equals _acs-authentication__auth__self_registration->aa_log _acs-authentication__auth__self_registration->aa_log_result _acs-authentication__auth__self_registration->aa_section _acs-authentication__auth__self_registration->acs::test::http

Testcases:
No testcase defined.

_acs-authentication__auth__update_local_account (private)

 _acs-authentication__auth__update_local_account

Partial Call Graph (max 5 caller/called nodes):
%3 aa_equals aa_equals (public) aa_log aa_log (public) aa_log_result aa_log_result (public) aa_run_with_teardown aa_run_with_teardown (public) aa_section aa_section (public) _acs-authentication__auth__update_local_account _acs-authentication__auth__update_local_account _acs-authentication__auth__update_local_account->aa_equals _acs-authentication__auth__update_local_account->aa_log _acs-authentication__auth__update_local_account->aa_log_result _acs-authentication__auth__update_local_account->aa_run_with_teardown _acs-authentication__auth__update_local_account->aa_section

Testcases:
No testcase defined.

_acs-authentication__auth__verify_account_status (private)

 _acs-authentication__auth__verify_account_status

Partial Call Graph (max 5 caller/called nodes):
%3 aa_equals aa_equals (public) aa_log aa_log (public) aa_log_result aa_log_result (public) aa_section aa_section (public) aa_true aa_true (public) _acs-authentication__auth__verify_account_status _acs-authentication__auth__verify_account_status _acs-authentication__auth__verify_account_status->aa_equals _acs-authentication__auth__verify_account_status->aa_log _acs-authentication__auth__verify_account_status->aa_log_result _acs-authentication__auth__verify_account_status->aa_section _acs-authentication__auth__verify_account_status->aa_true

Testcases:
No testcase defined.
[ hide source ] | [ make this the default ]

Content File Source

ad_library {

    Automated tests for procs in tcl/authentication-procs.tcl

}

aa_register_case \
    -cats {api} \
    -procs {
        auth::can_admin_system_without_authority_p
    } \
    auth__can_admin_system_without_authority_p {
        Test auth::can_admin_system_without_authority_p
    } {
        aa_run_with_teardown \
            -rollback \
            -test_code {

                set authorities [db_list get_authorities {
                    select authority_id from auth_authorities
                }]

                # First make sure that proc returns the expected value
                # in any setup...
                foreach authority_id $authorities {
                    set expected [db_0or1row admins_left_p {
                        select 1 from dual where exists
                        (
                          select 1
                          from acs_permissions p,
                             party_approved_member_map m,
                             acs_magic_objects amo,
                             cc_users u
                          where amo.name = 'security_context_root'
                          and p.object_id = amo.object_id
                          and p.grantee_id = m.party_id
                          and u.user_id = m.member_id
                          and u.member_state = 'approved'
                          and u.authority_id <> :authority_id
                          and acs_permission.permission_p(amo.object_id, u.user_id, 'admin') = 't'
                        )
                    }]
                    aa_equals "Proc should return $expected for authority $authority_id" \
                        $expected [auth::can_admin_system_without_authority_p \
                                       -authority_id $authority_id]
                }

                # Now revoke SWA permissions to everybody and create a
                # single SWA in the test authority. The expected
                # result is that the proc should return true for any
                # authority except the test one, as it is the only one
                # with an admin.
                aa_log "Revoking all SWA privileges"
                foreach user_id [db_list get_swas {
                    select u.user_id
                    from acs_permissions p,
                    party_approved_member_map m,
                    acs_magic_objects amo,
                    cc_users u
                    where amo.name = 'security_context_root'
                    and p.object_id = amo.object_id
                    and p.grantee_id = m.party_id
                    and u.user_id = m.member_id
                    and u.member_state = 'approved'
                    and acs_permission.permission_p(amo.object_id, u.user_id, 'admin') = 't'
                }] {
                    permission::revoke \
                        -party_id $user_id \
                        -object_id [acs_magic_object security_context_root] \
                        -privilege "admin"
                }

                foreach authority_id $authorities {
                    aa_equals "Proc should return 0 for authority $authority_id, as no admins are left" \
                        0 [auth::can_admin_system_without_authority_p \
                               -authority_id $authority_id]
                }

                aa_log "Creating a new SWA in the test authority"
                set test_authority_id [auth::authority::get_id -short_name "acs_testing"]
                set result [acs::test::user::create]
                set user_id [dict get $result user_id]
                permission::grant \
                    -party_id $user_id \
                    -object_id [acs_magic_object security_context_root] \
                    -privilege "admin"

                foreach authority_id $authorities {
                    set expected [expr {$authority_id != $test_authority_id}]
                    aa_equals "Proc should return $expected for authority $authority_id" \
                        $expected \
                        [auth::can_admin_system_without_authority_p \
                             -authority_id $authority_id]
                }

            }
    }

aa_register_case \
    -cats {api} \
    -procs {
        auth::delete_local_account
        acs_user::registered_user_p
        auth::get_local_account_status
    } \
    auth__delete_local_account  {
        Test mainly auth::delete_local_account and
        auth::get_local_account_status
    } {
        aa_run_with_teardown \
            -rollback \
            -test_code {
                set authority_id [auth::authority::get_id -short_name "acs_testing"]
                set result [acs::test::user::create]
                set user_id [dict get $result user_id]
                set username [dict get $result username]

                set account_status [auth::get_local_account_status -user_id $user_id]
                aa_equals "User '$username' should have local status 'ok'" ok $account_status

                set registered_p [acs_user::registered_user_p -user_id $user_id]
                aa_true "User '$username' is currently approved" $registered_p

                aa_log "Calling auth::delete_local_account on the user"
                set r [auth::delete_local_account \
                           -authority_id $authority_id \
                           -username $username]

                set registered_p [acs_user::registered_user_p -user_id $user_id]
                aa_false "User '$username' is not approved anymore" $registered_p
                aa_true "User '$username' still exists" [db_0or1row get_user {
                    select 1 from users where user_id = :user_id
                }]
                set account_status [auth::get_local_account_status -user_id $user_id]
                aa_equals "User '$username' should have local status 'closed'" closed $account_status

                set not_a_user [acs_magic_object security_context_root]
                set account_status [auth::get_local_account_status -user_id $not_a_user]
                aa_equals "Object '$not_a_user' is not an account" no_account $account_status

                aa_true "Proc returns 'delete_status'" [dict exists $r delete_status]
                aa_true "Proc returns 'delete_message'" [dict exists $r delete_status]
            }
    }

aa_register_case \
    -cats {api} \
    -procs {
        auth::get_all_registration_elements
    } \
    auth__get_all_registration_elements {
        Test auth::get_all_registration_elements
    } {
        aa_equals "Proc returns the expected result with flag 'include_password_confirm' set" \
            [lsort [auth::get_all_registration_elements -include_password_confirm]] [lsort {
                email username first_names last_name password
                password_confirm screen_name url
                secret_question secret_answer
            }]
        aa_equals "Proc returns the expected result with flag 'include_password_confirm' NOT set" \
            [lsort [auth::get_all_registration_elements]] [lsort {
                email username first_names last_name password
                screen_name url secret_question secret_answer
            }]
    }

aa_register_case \
    -cats {api} \
    -procs {
        auth::get_register_authority
    } \
    auth__get_register_authority {
        Test auth::get_register_authority
    } {
        aa_run_with_teardown \
            -rollback \
            -test_code {
                set register_authority [auth::get_register_authority]

                # Set all authorities as the register authority one by
                # one and see that the proc returns the expected
                # value.
                db_foreach get_authorities {
                    select authority_id,
                           short_name,
                           register_impl_id
                    from auth_authorities
                } {
                    aa_log "Setting '$short_name' as the registration authority"
                    parameter::set_from_package_key \
                        -parameter RegisterAuthority \
                        -package_key "acs-authentication" \
                        -value $short_name
                    if { $register_impl_id eq "" } {
                        aa_log "Authority '$short_name' does not have a register implementation, fallback to local authority"
                        set reg_authority_id [auth::authority::local]
                    } else {
                        aa_log "Authority '$short_name' has a register implementation"
                        set reg_authority_id $authority_id
                    }
                    aa_equals "Register authority '$short_name' should be picked correctly" \
                        $reg_authority_id [auth::get_register_authority]

                }

                # Finally, try a bogus one.
                set not_exists [db_string get_bogus_authority {
                    select '0' || min(short_name) from auth_authorities
                }]
                parameter::set_from_package_key \
                    -parameter RegisterAuthority \
                    -package_key "acs-authentication" \
                    -value $not_exists
                aa_silence_log_entries -severities error {
                    aa_equals "Non existent register authority '$not_exists' falls back to the local authority" \
                        [auth::authority::local] [auth::get_register_authority]
                }

                #
                # Put the authority back as it was to not pollute
                # the cache.
                #
                parameter::set_from_package_key \
                    -parameter RegisterAuthority \
                    -package_key "acs-authentication" \
                    -value $register_authority
            }
    }

aa_register_case \
    -cats {api} \
    -procs {
        auth::get_user_id
    } \
    auth__get_user_id {
        Test auth::get_user_id
    } {
        # We will just mess about with the ad_conn variables used
        # inside the proc to simulate a few possible situations.
        set prev_untrusted_user_id [ad_conn untrusted_user_id]
        set prev_account_status [ad_conn account_status]
        set prev_auth_level [ad_conn auth_level]

        set user_id [ad_conn user_id]

        set bogus_user [db_string get_bogus_user {
            select max(user_id) + 1 from users
        }]

        aa_run_with_teardown \
            -rollback \
            -test_code {
                foreach {
                    untrusted_user_id account_status auth_level
                    wanted_level wanted_account_status
                    expected_result
                } [list \
                       0           whatever none   1234 whatever 0 \
                       $user_id    ok       ok     ok     ok       $user_id \
                       $user_id    ok       ok     secure ok       [expr {[security::https_available_p] ? 0 : $user_id}] \
                       $user_id    ok       secure secure ok       $user_id \
                       $user_id    ok       secure secure whatever $user_id \
                       $bogus_user ok       secure secure ok       $bogus_user \
                       $bogus_user ko       secure secure ok       0 \
                      ] {
                    ad_conn -set untrusted_user_id $untrusted_user_id
                    ad_conn -set account_status $account_status
                    ad_conn -set auth_level $auth_level

                    set v [auth::get_user_id \
                               -level $wanted_level \
                               -account_status $wanted_account_status]
                    aa_equals "For user '$untrusted_user_id', level '$wanted_level', account_status '$wanted_account_status' the result should be '$expected_result'" \
                        $v $expected_result
                }
            } -teardown_code {
                ad_conn -set untrusted_user_id $prev_untrusted_user_id
                ad_conn -set account_status $prev_account_status
                ad_conn -set auth_level $prev_auth_level
            }
    }

aa_register_case \
    -cats {api} \
    -procs {
        auth::login_attempts::get_all
        auth::login_attempts::reset
        auth::login_attempts::reset_all
        auth::login_attempts::record
        auth::login_attempts::threshold_reached_p
        auth::login_attempts::get
    } \
    auth__login_attempts {
        Test login attempts API
    } {
        set orig_max_failed_login_attempts [parameter::get_from_package_key \
                                                -parameter "MaxConsecutiveFailedLoginAttempts" \
                                                -package_key "acs-authentication" \
                                                -default 0]
        try {
            # We set this value forcefully or chances are that
            # some system will never test this API
            set max_failed_login_attempts 10
            parameter::set_from_package_key \
                -parameter "MaxConsecutiveFailedLoginAttempts" \
                -package_key "acs-authentication" \
                -value $max_failed_login_attempts

            set login_attempt_key acs-test-login-key
            set another_login_attempt_key acs-test-login-another-key

            for {set i 1} {$i <= $max_failed_login_attempts} {incr i} {
                ::auth::login_attempts::record \
                    -login_attempt_key $login_attempt_key
                aa_equals "Login attempts for key '$login_attempt_key' should now be '$i'" \
                    $i [::auth::login_attempts::get -key $login_attempt_key]
                aa_false "Threshold for key '$login_attempt_key' should not have been reached" \
                    [::auth::login_attempts::threshold_reached_p \
                         -login_attempt_key $login_attempt_key]
            }

            ::auth::login_attempts::record \
                -login_attempt_key $login_attempt_key
            aa_true "Threshold for key '$login_attempt_key' should now have been reached" \
                [::auth::login_attempts::threshold_reached_p \
                     -login_attempt_key $login_attempt_key]

            aa_log "Forgetting of login attempts for '$another_login_attempt_key'"
            auth::login_attempts::reset \
                -login_attempt_key $another_login_attempt_key

            aa_true "Threshold for key '$login_attempt_key' should still have been reached" \
                [::auth::login_attempts::threshold_reached_p \
                     -login_attempt_key $login_attempt_key]

            aa_log "Forgetting of login attempts for '$login_attempt_key'"
            auth::login_attempts::reset \
                -login_attempt_key $login_attempt_key

            aa_false "Threshold for key '$login_attempt_key' should now be fine" \
                [::auth::login_attempts::threshold_reached_p \
                     -login_attempt_key $login_attempt_key]
            aa_equals "Number of attempts for key '$login_attempt_key' should now be 0" \
                0 [::auth::login_attempts::get \
                       -key $login_attempt_key]

            aa_log "Resetting all attempts"
            auth::login_attempts::reset_all
            aa_true "No attempts anymore..." \
                {[llength [auth::login_attempts::get_all]] == 0}

            aa_log "Record two attempts on different keys"

            ::auth::login_attempts::record \
                -login_attempt_key $login_attempt_key
            aa_equals "Number of attempts for key '$login_attempt_key' should now be 1" \
                1 [::auth::login_attempts::get \
                       -key $login_attempt_key]

            ::auth::login_attempts::record \
                -login_attempt_key $another_login_attempt_key
            aa_equals "Number of attempts for key '$another_login_attempt_key' should now be 1" \
                1 [::auth::login_attempts::get \
                       -key $another_login_attempt_key]

            set all_attempts [auth::login_attempts::get_all]

            set keys_to_expect [list \
                                    $login_attempt_key \
                                    $another_login_attempt_key]
            aa_equals "auth::login_attempts::get_all returns the expected number of entries" \
                [llength $all_attempts] [expr {3 * 2}]
            foreach {key timeout number_of_attempts} $all_attempts {
                aa_true "auth::login_attempts::get_all returns an integer for timeout" \
                    [string is integer -strict $timeout]
                aa_equals "auth::login_attempts::get_all returns the correct number of attempts" \
                    1 $number_of_attempts
                set i [lsearch -exact $keys_to_expect $key]
                aa_true "auth::login_attempts::get_all the correct keys" \
                    {$i >= 0}
                set keys_to_expect [lreplace $keys_to_expect $i $i]
            }

            aa_log "Resetting all attempts"
            auth::login_attempts::reset_all

            aa_true "No attempts anymore..." \
                {[llength [auth::login_attempts::get_all]] == 0}
        } finally {
            parameter::set_from_package_key \
                -parameter "MaxConsecutiveFailedLoginAttempts" \
                -package_key "acs-authentication" \
                -value $orig_max_failed_login_attempts
        }
    }

aa_register_case \
    -cats {api} \
    -procs {
        auth::refresh_login
    } \
    auth__refresh_login {
        Test auth::refresh_login
    } {
        try {
            set endpoint_name test__auth__refresh_login
            ns_register_proc GET $endpoint_name {
                set auth_level [ns_queryget auth_level]
                if {$auth_level ne ""} {
                    ad_conn -set auth_level $auth_level
                }
                ad_unless_script_abort {
                    set user_id [auth::refresh_login]
                } {
                    ns_return 200 text/plain $user_id
                }
            }

            set result [acs::test::user::create]
            set user_id [dict get $result user_id]

            set d [acs::test::http -user_id $user_id \
                       -method GET /$endpoint_name]
            acs::test::reply_has_status_code $d 200
            aa_equals "Response must be the supplied user_id '$user_id'" \
                [dict get $d body] $user_id

            set d [acs::test::http -user_id $user_id \
                       -method GET /$endpoint_name?auth_level=expired]
            acs::test::reply_has_status_code $d 302

        } finally {
            ns_unregister_op GET $endpoint_name
            acs_user::delete -user_id $user_id -permanent
        }
    }

aa_register_case \
    -cats {api} \
    -procs {
        auth::self_registration
    } \
    auth__self_registration {
        Test auth::self_registration
    } {
        set old_allow_self_register_p [parameter::get_from_package_key \
                                           -package_key acs-authentication \
                                           -parameter AllowSelfRegister]
        try {
            set endpoint_name test__auth__self_registration
            ns_register_proc GET $endpoint_name {
                ad_unless_script_abort {
                    set user_id [auth::self_registration]
                } {
                    ns_return 200 text/plain $user_id
                }
            }

            set result [acs::test::user::create]
            set user_id [dict get $result user_id]

            aa_section "Set AllowSelfRegister to false"
            parameter::set_from_package_key \
                -package_key acs-authentication \
                -parameter AllowSelfRegister \
                -value false

            aa_log "Unauthenticated request"
            set d [acs::test::http \
                       -method GET /$endpoint_name]
            acs::test::reply_has_status_code $d 302

            aa_log "Authenticated request"
            set d [acs::test::http -user_id $user_id \
                       -method GET /$endpoint_name]
            acs::test::reply_has_status_code $d 200
            aa_equals "Response must be the supplied user_id '$user_id'" \
                [dict get $d body] $user_id

            aa_section "Set AllowSelfRegister to true"
            parameter::set_from_package_key \
                -package_key acs-authentication \
                -parameter AllowSelfRegister \
                -value true

            aa_log "Unauthenticated request"
            set d [acs::test::http \
                       -method GET /$endpoint_name]
            acs::test::reply_has_status_code $d 200
            aa_equals "Response must be empty" \
                [dict get $d body] ""

            aa_log "Authenticated request"
            set d [acs::test::http -user_id $user_id \
                       -method GET /$endpoint_name]
            acs::test::reply_has_status_code $d 200
            aa_equals "Response must be empty" \
                [dict get $d body] ""

        } finally {
            parameter::set_from_package_key \
                -package_key acs-authentication \
                -parameter AllowSelfRegister \
                -value $old_allow_self_register_p
            ns_unregister_op GET $endpoint_name
            acs_user::delete -user_id $user_id -permanent
        }
    }

aa_register_case \
    -cats {api} \
    -procs {
        auth::update_local_account
    } \
    auth__update_local_account {
        Test auth::update_local_account
    } {
        aa_run_with_teardown \
            -rollback \
            -test_code {
                set result [acs::test::user::create]
                set user_id [dict get $result user_id]

                set u [acs_user::get -user_id $user_id]
                set authority_id [dict get $u authority_id]
                set test_authority_id $authority_id
                set username [dict get $u username]

                set other_authority_id [db_string get_authority {
                    select min(authority_id) from auth_authorities
                    where authority_id <> :test_authority_id
                }]

                foreach update_infos [list \
                                          [list [list \
                                                     email_verified_p f \
                                                     screen_name abcd \
                                                     authority_id $other_authority_id \
                                                     bio "a bio" \
                                                     first_names Jonh \
                                                     last_name Doe \
                                                     username anotheruser \
                                                     email valid@email.com \
                                                     url http://avalidurl.com \
                                                     whatever blabla] true]\
                                          [list [list \
                                                     email_verified_p t \
                                                     screen_name abcde \
                                                     authority_id $test_authority_id \
                                                     bio "another bio" \
                                                     first_names Jonh2 \
                                                     last_name Doe2 \
                                                     username anotheruser2 \
                                                     email invalidemail.com \
                                                     url http://avalidurl.com \
                                                     whatever blabla] false] \
                                          [list [list \
                                                     first_names Jonh3 \
                                                     last_name Doe3] true]] {
                    lassign $update_infos data correct_p

                    set not [expr {$correct_p ? "" : "not "}]
                    aa_section "Updating user '$user_id' with $data, supposed to be ${not}correct"

                    unset -nocomplain update_data
                    array set update_data $data

                    set result [auth::update_local_account \
                                    -authority_id $authority_id \
                                    -username $username \
                                    -array update_data]

                    # Update the info we supply to the proc when the
                    # update should succeed.
                    if {$correct_p} {
                        if {[dict exists $data authority_id]} {
                            set authority_id [dict get $data authority_id]
                        }
                        if {[dict exists $data username]} {
                            set username [dict get $data username]
                        }
                    }

                    set expected_keys [lsort -unique \
                                           [list {*}[dict keys $result] \
                                                update_status update_message element_messages]]
                    aa_equals "Proc returns the expected entries" \
                        [lsort [dict keys $result]] \
                        $expected_keys

                    set expected_status [expr {$correct_p ? "ok" : "data_error"}]
                    aa_equals "Update status is '$expected_status' -> $result" \
                        [dict get $result update_status] \
                        $expected_status

                    if {$correct_p} {
                        set updated_user [acs_user::get -user_id $user_id]
                        foreach {key expected_value} $data {
                            if {[dict exists $updated_user $key]} {
                                aa_equals "Attribute '$key' was updated to '$expected_value'" \
                                    [dict get $updated_user $key$expected_value
                            }
                        }
                    }
                }
            }
    }

aa_register_case \
    -cats {api} \
    -procs {
        auth::verify_account_status
    } \
    auth__verify_account_status {
        Test auth::verify_account_status
    } {
        try {
            set endpoint_name test__auth__verify_account_status
            ns_register_proc GET $endpoint_name {
                ad_conn -set auth_level somenonsense
                auth::verify_account_status
                ns_return 200 text/plain [ad_conn auth_level]
            }

            set user_info [acs::test::user::create -admin]
            set user_id [dict get $user_info user_id]
            acs::test::confirm_email -user_id $user_id
            set d [::acs::test::login $user_info]

            set expected_statuses {ok secure}

            aa_section "Accessing the test endpoint as user '$user_id'"
            set d [acs::test::http \
                       -last_request $d \
                       -method GET /$endpoint_name]
            acs::test::reply_has_status_code $d 200

            set auth_level [dict get $d body]
            aa_true "Returned '$auth_level' is among the expected ones '$expected_statuses'" \
                {$auth_level in $expected_statuses}

            aa_section "Accessing the test endpoint as nobody"
            set d [acs::test::http \
                       -method GET /$endpoint_name]
            acs::test::reply_has_status_code $d 200
            aa_equals "Returned auth_level is 'none'" \
                [dict get $d body] "none"

        } finally {
            ns_unregister_op GET $endpoint_name
            acs_user::delete -user_id $user_id -permanent
        }
    }

# Local variables:
#    mode: tcl
#    tcl-indent-level: 4
#    indent-tabs-mode: nil
# End: