File: Session.sql

package info (click to toggle)
ledgersmb 1.6.33%2Bds-2.1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 33,000 kB
  • sloc: perl: 52,612; sql: 43,562; xml: 36,194; javascript: 2,428; sh: 1,099; makefile: 361; pascal: 25
file content (222 lines) | stat: -rw-r--r-- 6,722 bytes parent folder | download | duplicates (3)
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;