I have a function that I'm trying to get to create a user, insert the user into a table and IF provided add the user to a role. I can create the user and add them to the table I've created with the first function easy enough but I can't conditionally add them to a group. I want the option to NOT add the user to a role or to include the role and grant that role to the user. Here is my function to create the user that works
CREATE OR REPLACE FUNCTION create_user(
new_user character varying,
temp_password character varying,
grant_role text default NULL)
RETURNS text AS
$BODY$
BEGIN
IF NOT EXISTS (SELECT usename FROM pg_catalog.pg_user
Where usename not in ('postgres','repl','pgpool')
and usename = new_user) THEN
EXECUTE format('CREATE USER ' || new_user || ' with password ''' || temp_password || ''';');
EXECUTE format('insert into open_sesame (user_name, last_change_date, next_change_date) VALUES( ''' || new_user || ''',
date(now()),
date(now() + interval ''1 days''));');
RETURN 'CREATED ROLE';
ELSE
RETURN format('ROLE ''%I'' ALREADY EXISTS', new_user);
END IF;
END;
$BODY$
LANGUAGE plpgsql VOLATILE SECURITY DEFINER
COST 100;
ALTER FUNCTION create_user(character varying, character varying)
OWNER TO postgres;
I want to do something like this pseudo code
BEGIN
IF NOT EXISTS (SELECT usename FROM pg_catalog.pg_user
Where usename not in ('postgres','repl','pgpool')
and usename = new_user)
&& IF NOT EXISTS (SELECT rolname FROM pg_roles WHERE rolname = grant_role and rolname <> 'postgres')
&& grant_role IS NOT NULL THEN
EXECUTE format('CREATE USER ' || new_user || ' with password ''' || temp_password || ''';');
EXECUTE format('GRANT ' || grant_role || ' to ' || new_user ||';');
EXECUTE format('insert into open_sesame (user_name, last_change_date, next_change_date) VALUES( ''' || new_user || ''', date(now()), date(now() + interval ''1 days''));');
RETURN 'CREATED USER WITH ROLE';
ELSE
IF NOT EXISTS (SELECT usename FROM pg_catalog.pg_user
Where usename not in ('postgres','repl','pgpool')
and usename = new_user)
EXECUTE format('CREATE USER ' || new_user || ' with password ''' || temp_password || ''';');
EXECUTE format('insert into open_sesame (user_name, last_change_date, next_change_date) VALUES( ''' || new_user || ''', date(now()),date(now() + interval ''1 days''));');
RETURN 'CREATED USER ONLY';
ELSE
RETURN 'NO USER CREATED';
END IF;
END IF;
END;
Any help is much appreciated.
You are missing conditions for your nested ELSEIF. Fill it where I've added the comment line and it should work as expected with nested
IF ... THEN ... [ELSEIF ...] [ELSE ...] END IF;
Code:
BEGIN
IF NOT EXISTS (
SELECT usename
FROM pg_catalog.pg_user
WHERE usename not in ('postgres','repl','pgpool')
AND usename = new_user
)
THEN
IF NOT EXISTS (
SELECT rolname
FROM pg_roles
WHERE rolname = grant_role
AND rolname <> 'postgres'
) AND grant_role IS NOT NULL
THEN
EXECUTE format('CREATE USER ' || new_user || ' with password ''' || temp_password || ''';');
EXECUTE format('GRANT ' || grant_role || ' to ' || new_user ||';');
EXECUTE format('insert into open_sesame (user_name, last_change_date, next_change_date) VALUES( ''' || new_user || ''', date(now()), date(now() + interval ''1 days''));');
RETURN 'CREATED USER WITH ROLE';
ELSEIF -- you forgot to specify the condition
EXECUTE format('CREATE USER ' || new_user || ' with password ''' || temp_password || ''';');
EXECUTE format('insert into open_sesame (user_name, last_change_date, next_change_date) VALUES( ''' || new_user || ''', date(now()),date(now() + interval ''1 days''));');
RETURN 'CREATED USER ONLY';
ELSE
RETURN 'NO USER CREATED';
END IF;
ELSE
RETURN format('ROLE ''%I'' ALREADY EXISTS', new_user);
END IF;
END;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With