Add function to change the current user’s password
This function does not ask for the confirmation because this is an user-facing issue, not for the database. Still missing: validation and proper error messages.
This commit is contained in:
parent
56d149e211
commit
d9c93b8797
|
@ -0,0 +1,28 @@
|
|||
-- Deploy numerus:change_password to pg
|
||||
-- requires: schema_numerus
|
||||
-- requires: user
|
||||
|
||||
begin;
|
||||
|
||||
set search_path to numerus, auth, public;
|
||||
|
||||
create or replace function change_password(new_password text) returns void as
|
||||
$$
|
||||
update "user"
|
||||
set password = new_password
|
||||
where email = current_user_email()
|
||||
and cookie = current_user_cookie()
|
||||
and cookie_expires_at > current_timestamp
|
||||
and length(cookie) > 30
|
||||
$$ language sql
|
||||
security definer
|
||||
set search_path to auth, numerus, pg_temp;
|
||||
|
||||
revoke execute on function change_password(text) from public;
|
||||
grant execute on function change_password(text) to invoicer;
|
||||
grant execute on function change_password(text) to admin;
|
||||
|
||||
comment on function change_password(text) is
|
||||
'Changes the password for the current app user';
|
||||
|
||||
commit;
|
|
@ -43,6 +43,9 @@ func ProfileHandler() http.Handler {
|
|||
page.Language = r.FormValue("language")
|
||||
cookie := conn.MustGetText(r.Context(), "", "update user_profile set name = $1, email = $2, lang_tag = $3 returning build_cookie()", page.Name, page.Email, page.Language)
|
||||
setSessionCookie(w, cookie)
|
||||
if page.Password != "" && page.Password == page.PasswordConfirm {
|
||||
conn.MustExec(r.Context(), "select change_password($1)", page.Password)
|
||||
}
|
||||
http.Redirect(w, r, "/profile", http.StatusSeeOther)
|
||||
return
|
||||
} else {
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
-- Revert numerus:change_password from pg
|
||||
|
||||
begin;
|
||||
|
||||
drop function if exists numerus.change_password(text);
|
||||
|
||||
commit;
|
|
@ -23,3 +23,4 @@ logout [schema_auth current_user_email current_user_cookie user] 2023-01-17T19:1
|
|||
set_cookie [schema_public check_cookie] 2023-01-19T11:00:22Z jordi fita mas <jordi@tandem.blog> # Add function to set the role based on the cookie
|
||||
available_languages [schema_numerus language] 2023-01-21T21:11:08Z jordi fita mas <jordi@tandem.blog> # Add the initial available languages
|
||||
user_profile [schema_numerus user current_user_email current_user_cookie] 2023-01-21T23:18:20Z jordi fita mas <jordi@tandem.blog> # Add view for user profile
|
||||
change_password [schema_numerus user] 2023-01-23T20:22:45Z jordi fita mas <jordi@tandem.blog> # Add function to change the current user’s password
|
||||
|
|
|
@ -0,0 +1,57 @@
|
|||
-- Test change_password
|
||||
set client_min_messages to warning;
|
||||
create extension if not exists pgtap;
|
||||
reset client_min_messages;
|
||||
|
||||
begin;
|
||||
|
||||
select plan(14);
|
||||
|
||||
set search_path to numerus, auth, public;
|
||||
|
||||
select has_function('numerus', 'change_password', array ['text']);
|
||||
select function_lang_is('numerus', 'change_password', array ['text'], 'sql');
|
||||
select function_returns('numerus', 'change_password', array ['text'], 'void');
|
||||
select is_definer('numerus', 'change_password', array ['text']);
|
||||
select volatility_is('numerus', 'change_password', array ['text'], 'volatile');
|
||||
select function_privs_are('numerus', 'change_password', array ['text'], 'guest', array []::text[]);
|
||||
select function_privs_are('numerus', 'change_password', array ['text'], 'invoicer', array ['EXECUTE']);
|
||||
select function_privs_are('numerus', 'change_password', array ['text'], 'admin', array ['EXECUTE']);
|
||||
select function_privs_are('numerus', 'change_password', array ['text'], 'authenticator', array []::text[]);
|
||||
|
||||
set client_min_messages to warning;
|
||||
truncate auth."user" cascade;
|
||||
reset client_min_messages;
|
||||
|
||||
insert into auth."user" (user_id, email, name, password, role, cookie, cookie_expires_at)
|
||||
values (1, 'demo@tandem.blog', 'Demo', 'test', 'invoicer', '44facbb30d8a419dfd4bfbc44a4b5539d4970148dfc84bed0e', current_timestamp + interval '1 month')
|
||||
, (9, 'admin@tandem.blog', 'Demo', 'test', 'admin', '12af4c88b528c2ad4222e3740496ecbc58e76e26f087657524', current_timestamp + interval '1 month')
|
||||
;
|
||||
|
||||
select lives_ok( $$ select change_password('another') $$, 'Should run even without current user' );
|
||||
|
||||
select isnt_empty (
|
||||
$$ select * from auth."user" where password = crypt('test', password) $$,
|
||||
'Should not have changed any password'
|
||||
);
|
||||
|
||||
select set_cookie('44facbb30d8a419dfd4bfbc44a4b5539d4970148dfc84bed0e/demo@tandem.blog');
|
||||
|
||||
select lives_ok( $$ select change_password('another') $$, 'Should run with the correct user' );
|
||||
|
||||
reset role;
|
||||
|
||||
select isnt_empty (
|
||||
$$ select * from auth."user" where email = 'demo@tandem.blog' and password = crypt('another', password) $$,
|
||||
'Should have changed the password of the current user'
|
||||
);
|
||||
|
||||
select isnt_empty (
|
||||
$$ select * from auth."user" where email = 'admin@tandem.blog' and password = crypt('test', password) $$,
|
||||
'Should not have changed any other password'
|
||||
);
|
||||
|
||||
select *
|
||||
from finish();
|
||||
|
||||
rollback;
|
|
@ -0,0 +1,7 @@
|
|||
-- Verify numerus:change_password on pg
|
||||
|
||||
begin;
|
||||
|
||||
select has_function_privilege('numerus.change_password(text)', 'execute');
|
||||
|
||||
rollback;
|
Loading…
Reference in New Issue