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/jbe@1309
|
23 local secret_purposes = { "oauth", "csrf", "_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/jbe@1309
|
43 function Session.object:additional_secret_for(purpose)
|
bsw/jbe@1309
|
44 local use_hash = false
|
bsw/jbe@1309
|
45 local idx = secret_purposes[purpose]
|
bsw/jbe@1309
|
46 if not idx then
|
bsw/jbe@1309
|
47 idx = assert(secret_purposes._other, "No other secrets supported")
|
bsw/jbe@1309
|
48 use_hash = true
|
bsw/jbe@1309
|
49 end
|
bsw/jbe@1309
|
50 local from_pos = secret_length * (idx-1) + 1
|
bsw/jbe@1309
|
51 local to_pos = from_pos + secret_length - 1
|
bsw/jbe@1309
|
52 local secret = string.sub(self.additional_secret, from_pos, to_pos)
|
bsw/jbe@1309
|
53 if #secret ~= secret_length then
|
bsw/jbe@1309
|
54 self:destroy()
|
bsw/jbe@1309
|
55 error("Session state invalid")
|
bsw/jbe@1309
|
56 end
|
bsw/jbe@1309
|
57 if use_hash then
|
bsw/jbe@1309
|
58 local moonhash = require "moonhash" -- TODO: auto loader for libraries in WebMCP?
|
bsw/jbe@1309
|
59 secret = moonhash.shake256(secret .. "\0" .. purpose, secret_length, secret_alphabet)
|
bsw/jbe@1309
|
60 end
|
bsw/jbe@1309
|
61 return secret
|
bsw/jbe@1309
|
62 end
|
bsw/jbe@1309
|
63
|
bsw/jbe@0
|
64 function Session:by_ident(ident)
|
bsw/jbe@0
|
65 local selector = self:new_selector()
|
bsw/jbe@0
|
66 selector:add_where{ 'ident = ?', ident }
|
bsw@1074
|
67 selector:add_field{ 'authority_uid' }
|
bsw/jbe@0
|
68 selector:optional_object_mode()
|
bsw/jbe@0
|
69 return selector:exec()
|
bsw/jbe@0
|
70 end
|
bsw@813
|
71
|
bsw@813
|
72 function Session.object:has_access(level)
|
bsw@813
|
73 if level == "member" then
|
bsw@813
|
74 if app.session.member_id then
|
bsw@813
|
75 return true
|
bsw@813
|
76 else
|
bsw@813
|
77 return false
|
bsw@813
|
78 end
|
bsw@813
|
79
|
bsw@813
|
80 elseif level == "everything" then
|
bsw@813
|
81 if self:has_access("member") or config.public_access == "everything" then
|
bsw@813
|
82 return true
|
bsw@813
|
83 else
|
bsw@813
|
84 return false
|
bsw@813
|
85 end
|
bsw@813
|
86
|
bsw@813
|
87 elseif level == "all_pseudonymous" then
|
bsw@813
|
88 if self:has_access("everything") or config.public_access == "all_pseudonymous" then
|
bsw@813
|
89 return true
|
bsw@813
|
90 else
|
bsw@813
|
91 return false
|
bsw@813
|
92 end
|
bsw@813
|
93
|
bsw@813
|
94 elseif level == "authors_pseudonymous" then
|
bsw@813
|
95 if self:has_access("all_pseudonymous") or config.public_access == "authors_pseudonymous" then
|
bsw@813
|
96 return true
|
bsw@813
|
97 else
|
bsw@813
|
98 return false
|
bsw@813
|
99 end
|
bsw@813
|
100
|
bsw@813
|
101 elseif level == "anonymous" then
|
bsw@813
|
102 if self:has_access("authors_pseudonymous") or config.public_access == "anonymous" then
|
bsw@813
|
103 return true
|
bsw@813
|
104 else
|
bsw@813
|
105 return false
|
bsw@813
|
106 end
|
bsw@813
|
107
|
bsw@813
|
108 end
|
bsw@813
|
109
|
bsw@813
|
110 error("invalid access level")
|
bsw@813
|
111 end
|