rev |
line source |
bsw/jbe@0
|
1 Session = mondelefant.new_class()
|
bsw/jbe@0
|
2 Session.table = 'session'
|
bsw/jbe@0
|
3 Session.primary_key = { 'ident' }
|
bsw/jbe@0
|
4
|
bsw/jbe@0
|
5 Session:add_reference{
|
bsw/jbe@0
|
6 mode = 'm1',
|
bsw/jbe@0
|
7 to = "Member",
|
bsw/jbe@0
|
8 this_key = 'member_id',
|
bsw/jbe@0
|
9 that_key = 'id',
|
bsw/jbe@0
|
10 ref = 'member',
|
bsw/jbe@0
|
11 }
|
bsw/jbe@0
|
12
|
bsw/jbe@1309
|
13 Session:add_reference{
|
bsw/jbe@1309
|
14 mode = 'm1',
|
bsw/jbe@1309
|
15 to = "Member",
|
bsw/jbe@1309
|
16 this_key = 'real_member_id',
|
bsw/jbe@1309
|
17 that_key = 'id',
|
bsw/jbe@1309
|
18 ref = 'real_member',
|
bsw/jbe@1309
|
19 }
|
bsw/jbe@1309
|
20
|
bsw/jbe@1309
|
21 local secret_length = 24
|
bsw/jbe@1309
|
22 local secret_alphabet = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'
|
bsw@1494
|
23 local secret_purposes = { "oauth", "_other" }
|
bsw/jbe@1309
|
24 for idx, purpose in ipairs(secret_purposes) do
|
bsw/jbe@1309
|
25 secret_purposes[purpose] = idx
|
bsw/jbe@1309
|
26 end
|
bsw/jbe@1309
|
27
|
bsw/jbe@1309
|
28 local function random_string(length_multiplier)
|
bsw/jbe@0
|
29 return multirand.string(
|
bsw/jbe@1309
|
30 secret_length * (length_multiplier or 1),
|
bsw/jbe@1309
|
31 secret_alphabet
|
bsw/jbe@0
|
32 )
|
bsw/jbe@0
|
33 end
|
bsw/jbe@0
|
34
|
bsw/jbe@0
|
35 function Session:new()
|
bsw/jbe@0
|
36 local session = self.prototype.new(self) -- super call
|
bsw/jbe@0
|
37 session.ident = random_string()
|
bsw/jbe@1309
|
38 session.additional_secret = random_string(#secret_purposes)
|
bsw/jbe@1309
|
39 session:save()
|
bsw/jbe@0
|
40 return session
|
bsw/jbe@0
|
41 end
|
bsw/jbe@0
|
42
|
bsw@1511
|
43 function Session.object:set_cookie()
|
bsw@1511
|
44 request.set_cookie{
|
bsw@1511
|
45 name = config.cookie_name,
|
bsw@1511
|
46 value = self.ident,
|
bsw@1511
|
47 samesite = "none"
|
bsw@1511
|
48 }
|
bsw@1511
|
49 request.set_cookie{
|
bsw@1521
|
50 name = config.cookie_name_samesite,
|
bsw@1511
|
51 value = self.ident
|
bsw@1511
|
52 }
|
bsw@1511
|
53 end
|
bsw@1511
|
54
|
bsw/jbe@1309
|
55 function Session.object:additional_secret_for(purpose)
|
bsw/jbe@1309
|
56 local use_hash = false
|
bsw/jbe@1309
|
57 local idx = secret_purposes[purpose]
|
bsw/jbe@1309
|
58 if not idx then
|
bsw/jbe@1309
|
59 idx = assert(secret_purposes._other, "No other secrets supported")
|
bsw/jbe@1309
|
60 use_hash = true
|
bsw/jbe@1309
|
61 end
|
bsw/jbe@1309
|
62 local from_pos = secret_length * (idx-1) + 1
|
bsw/jbe@1309
|
63 local to_pos = from_pos + secret_length - 1
|
bsw/jbe@1309
|
64 local secret = string.sub(self.additional_secret, from_pos, to_pos)
|
bsw/jbe@1309
|
65 if #secret ~= secret_length then
|
bsw/jbe@1309
|
66 self:destroy()
|
bsw/jbe@1309
|
67 error("Session state invalid")
|
bsw/jbe@1309
|
68 end
|
bsw/jbe@1309
|
69 if use_hash then
|
bsw/jbe@1309
|
70 local moonhash = require "moonhash" -- TODO: auto loader for libraries in WebMCP?
|
bsw/jbe@1309
|
71 secret = moonhash.shake256(secret .. "\0" .. purpose, secret_length, secret_alphabet)
|
bsw/jbe@1309
|
72 end
|
bsw/jbe@1309
|
73 return secret
|
bsw/jbe@1309
|
74 end
|
bsw/jbe@1309
|
75
|
bsw/jbe@0
|
76 function Session:by_ident(ident)
|
bsw/jbe@0
|
77 local selector = self:new_selector()
|
bsw/jbe@0
|
78 selector:add_where{ 'ident = ?', ident }
|
bsw@1074
|
79 selector:add_field{ 'authority_uid' }
|
bsw/jbe@0
|
80 selector:optional_object_mode()
|
bsw/jbe@0
|
81 return selector:exec()
|
bsw/jbe@0
|
82 end
|
bsw@813
|
83
|
bsw@813
|
84 function Session.object:has_access(level)
|
bsw@813
|
85 if level == "member" then
|
bsw@813
|
86 if app.session.member_id then
|
bsw@813
|
87 return true
|
bsw@813
|
88 else
|
bsw@813
|
89 return false
|
bsw@813
|
90 end
|
bsw@813
|
91
|
bsw@813
|
92 elseif level == "everything" then
|
bsw@813
|
93 if self:has_access("member") or config.public_access == "everything" then
|
bsw@813
|
94 return true
|
bsw@813
|
95 else
|
bsw@813
|
96 return false
|
bsw@813
|
97 end
|
bsw@813
|
98
|
bsw@813
|
99 elseif level == "all_pseudonymous" then
|
bsw@813
|
100 if self:has_access("everything") or config.public_access == "all_pseudonymous" then
|
bsw@813
|
101 return true
|
bsw@813
|
102 else
|
bsw@813
|
103 return false
|
bsw@813
|
104 end
|
bsw@813
|
105
|
bsw@813
|
106 elseif level == "authors_pseudonymous" then
|
bsw@813
|
107 if self:has_access("all_pseudonymous") or config.public_access == "authors_pseudonymous" then
|
bsw@813
|
108 return true
|
bsw@813
|
109 else
|
bsw@813
|
110 return false
|
bsw@813
|
111 end
|
bsw@813
|
112
|
bsw@813
|
113 elseif level == "anonymous" then
|
bsw@813
|
114 if self:has_access("authors_pseudonymous") or config.public_access == "anonymous" then
|
bsw@813
|
115 return true
|
bsw@813
|
116 else
|
bsw@813
|
117 return false
|
bsw@813
|
118 end
|
bsw@813
|
119
|
bsw@813
|
120 end
|
bsw@813
|
121
|
bsw@813
|
122 error("invalid access level")
|
bsw@813
|
123 end
|