1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222
|
set client_min_messages = 'warning';
BEGIN;
CREATE OR REPLACE FUNCTION form_check(in_session_id int, in_form_id int)
RETURNS BOOL AS
$$
SELECT count(*) = 1
FROM open_forms f
JOIN "session" s USING (session_id)
JOIN users u ON (s.users_id = u.id)
WHERE f.session_id = $1 and f.id = $2 and u.username = SESSION_USER;
$$ language sql SECURITY DEFINER;
COMMENT ON FUNCTION form_check(in_session_id int, in_form_id int) IS
$$ This checks to see if an open form (record in open_forms) exists with
the form_id and session_id provided. Returns true if exists, false if not.$$;
CREATE OR REPLACE FUNCTION form_close(in_session_id int, in_form_id int)
RETURNS BOOL AS
$$
DECLARE form_test bool;
BEGIN
form_test := form_check(in_session_id, in_form_id);
IF form_test IS TRUE THEN
DELETE FROM open_forms
WHERE session_id = in_session_id AND id = in_form_id;
RETURN TRUE;
ELSE
RETURN FALSE;
END IF;
END;
$$ language plpgsql SECURITY DEFINER;
COMMENT ON FUNCTION form_close(in_session_id int, in_form_id int) IS
$$ Closes out the form by deleting it from the open_forms table.
Returns true if found, false if not.
$$;
CREATE OR REPLACE FUNCTION check_expiration() RETURNS bool AS
$$
DECLARE test_result BOOL;
expires_in interval;
notify_again interval;
BEGIN
expires_in := user__check_my_expiration();
SELECT expires_in < notify_password INTO test_result
FROM users WHERE username = SESSION_USER;
IF test_result THEN
IF expires_in < '1 week' THEN
notify_again := '1 hour';
ELSE
notify_again := '1 day';
END IF;
UPDATE users
SET notify_password = expires_in - notify_again
WHERE username = SESSION_USER;
END IF;
RETURN test_result;
END;
$$ LANGUAGE PLPGSQL SECURITY DEFINER; -- run by public, but no input from user.
COMMENT ON FUNCTION check_expiration() IS
$$ This checks whether the user needs to be notified of a pending expiration of
his/her password. Returns true if needed, false if not.
The function also records the next time when the notification will again need to
be displayed. $$;
CREATE OR REPLACE FUNCTION form_open(in_session_id int)
RETURNS INT AS
$$
DECLARE usertest bool;
form_id int;
BEGIN
SELECT count(*) = 1 INTO usertest FROM session
WHERE session_id = in_session_id
AND users_id IN (select id from users
WHERE username = SESSION_USER);
IF usertest is not true THEN
RAISE EXCEPTION 'Invalid session';
END IF;
INSERT INTO open_forms (session_id,last_used)
VALUES (in_session_id,now())
RETURNING id INTO form_id;
RETURN form_id;
END;
$$ LANGUAGE PLPGSQL SECURITY DEFINER;
COMMENT ON FUNCTION form_open(in_session_id int) IS
$$ This opens a form, and returns the id of the form opened.$$;
CREATE OR REPLACE FUNCTION session_check(in_session_id int, in_token text)
RETURNS session AS
$$
DECLARE out_row session%ROWTYPE;
BEGIN
PERFORM * FROM defaults
WHERE setting_key='never_logout' and value = '1';
IF NOT FOUND THEN
DELETE FROM session
WHERE last_used < now() - coalesce((SELECT value FROM defaults
WHERE setting_key = 'session_timeout')::interval,
'90 minutes'::interval);
END IF;
UPDATE session
SET last_used = now()
WHERE session_id = in_session_id
AND token = in_token
AND users_id = (select id from users
where username = SESSION_USER)
RETURNING * INTO out_row;
-- if there is no matching row, return NULL values
-- note: there is also a failing match when the token doesn't
-- match; which might mean a replay attack!
RETURN out_row;
END;
$$ LANGUAGE PLPGSQL;
COMMENT ON FUNCTION session_check(int, text) IS
$$ Returns a session row. If no session exists, it returns null$$;
CREATE OR REPLACE FUNCTION session_create()
RETURNS session AS
$$
DECLARE
out_row session%ROWTYPE;
users_id int;
BEGIN
SELECT id INTO users_id
FROM users WHERE username = SESSION_USER;
IF NOT FOUND THEN
RETURN out_row;
END IF;
INSERT INTO session (users_id, token, last_used)
VALUES (users_id, md5(random()::text), now())
RETURNING * INTO out_row;
RETURN out_row;
END;
$$ LANGUAGE PLPGSQL;
COMMENT ON FUNCTION session_create() IS
$$ Creates a session for the current session user and returns it.
When no user is found by name of the session user,
returns a row with NULL values.$$;
CREATE OR REPLACE FUNCTION session_delete(in_session_id int)
RETURNS BOOL AS
$$
BEGIN
DELETE FROM session
WHERE session_id = in_session_id
AND users_id = (select id from users
where username = SESSION_USER);
RETURN FOUND;
END;
$$ LANGUAGE PLPGSQL;
COMMENT ON FUNCTION session_delete(int) IS
$$ Removes the session with the id given in the argument.
Returns TRUE on success.
Note: only users owning a session may delete that session. $$;
CREATE OR REPLACE FUNCTION unlock_all() RETURNS BOOL AS
$$
BEGIN
UPDATE transactions SET locked_by = NULL
where locked_by IN
(select session_id from session WHERE users_id =
(SELECT id FROM users WHERE username = SESSION_USER));
RETURN FOUND;
END;
$$ LANGUAGE PLPGSQL;
COMMENT ON FUNCTION unlock_all() IS
$$Releases all pessimistic locks against transactions. These locks are again
only advisory, and the application may choose to handle them or not.
Returns true if any transactions were unlocked, false otherwise.$$;
CREATE OR REPLACE FUNCTION unlock(in_id int) RETURNS BOOL AS $$
BEGIN
UPDATE transactions SET locked_by = NULL WHERE id = in_id
AND locked_by IN (SELECT session_id FROM session WHERE users_id =
(SELECT id FROM users WHERE username = SESSION_USER));
RETURN FOUND;
END;
$$ LANGUAGE PLPGSQL;
COMMENT ON FUNCTION unlock(in_id int) IS
$$Releases a pessimistic locks against a transaction, if that transaciton, as
identified by in_id exists, and if it is locked by the current session.
These locks are again only advisory, and the application may choose to handle
them or not.
Returns true if the transaction was unlocked by this routine, false
otherwise.$$;
update defaults set value = 'yes' where setting_key = 'module_load_ok';
COMMIT;
|