3
|
1 local Luan = require "luan:Luan.luan"
|
|
2 local error = Luan.error
|
|
3 local set_metatable = Luan.set_metatable or error()
|
|
4 local range = Luan.range or error()
|
43
|
5 local set_local_only = Luan.set_local_only or error()
|
|
6 local get_local_only = Luan.get_local_only or error()
|
3
|
7 local String = require "luan:String.luan"
|
|
8 local sub_string = String.sub or error()
|
|
9 local Table = require "luan:Table.luan"
|
|
10 local concat = Table.concat or error()
|
|
11 local Math = require "luan:Math.luan"
|
|
12 local random = Math.random or error()
|
|
13 local Time = require "luan:Time.luan"
|
|
14 local time_now = Time.now or error()
|
|
15 local Html = require "luan:Html.luan"
|
|
16 local html_encode = Html.encode or error()
|
|
17 local Lucene = require "luan:lucene/Lucene.luan"
|
|
18 local lucene_quote = Lucene.quote or error()
|
|
19 local Http = require "luan:http/Http.luan"
|
|
20 local Db = require "site:/lib/Db.luan"
|
|
21
|
|
22
|
|
23 local User = {}
|
|
24
|
43
|
25 local users_by_name = {}
|
|
26
|
3
|
27 local function from_doc(doc)
|
|
28 doc.type == "user" or error "wrong type"
|
43
|
29 local user = User.new {
|
3
|
30 id = doc.id
|
|
31 email = doc.user_email
|
|
32 password = doc.password
|
|
33 name = doc.user_name
|
|
34 created = doc.created
|
|
35 }
|
43
|
36 set_local_only(users_by_name,user.name,user)
|
|
37 return user
|
3
|
38 end
|
|
39
|
|
40 local function to_doc(user)
|
|
41 local email = user.email
|
|
42 return {
|
|
43 type = "user"
|
|
44 id = user.id
|
|
45 user_email = email
|
|
46 password = user.password
|
|
47 user_name = user.name
|
|
48 created = user.created or time_now()
|
|
49 }
|
|
50 end
|
|
51
|
|
52 local metatable = {}
|
|
53 function metatable.__index(user,key)
|
|
54 if key == "name_html" then
|
|
55 user.name_html = html_encode(user.name)
|
|
56 return user.name_html
|
|
57 end
|
|
58 return nil
|
|
59 end
|
|
60
|
|
61 function User.new(user)
|
|
62
|
|
63 function user.save()
|
|
64 local doc = to_doc(user)
|
|
65 Db.save(doc)
|
|
66 user.id = doc.id
|
|
67 end
|
|
68
|
54
|
69 function user.reload()
|
|
70 return User.get_by_id(user.id) or error(user.id)
|
|
71 end
|
|
72
|
|
73 function user.login()
|
|
74 Http.response.set_persistent_cookie("user",user.name)
|
|
75 Http.response.set_persistent_cookie("password",user.password)
|
|
76 Http.request.cookies.user = user.name or error()
|
|
77 Http.request.cookies.password = user.password or error()
|
|
78 end
|
|
79
|
3
|
80 set_metatable(user,metatable)
|
|
81 return user
|
|
82 end
|
|
83
|
54
|
84 function User.get_by_id(id)
|
|
85 local doc = Db.get_document("id:"..id)
|
|
86 return doc and from_doc(doc)
|
|
87 end
|
|
88
|
3
|
89 function User.get_by_email(email)
|
|
90 local doc = Db.get_document("user_email:"..lucene_quote(email))
|
|
91 return doc and from_doc(doc)
|
|
92 end
|
|
93
|
|
94 local function get_by_name(name)
|
43
|
95 local user = get_local_only(users_by_name,name)
|
|
96 if user ~= nil then return user end
|
3
|
97 local doc = Db.get_document("user_name:"..lucene_quote(name))
|
|
98 return doc and from_doc(doc)
|
|
99 end
|
|
100 User.get_by_name = get_by_name
|
|
101
|
|
102 function User.current()
|
|
103 local name = Http.request.cookies.user
|
|
104 local password = Http.request.cookies.password
|
|
105 if name == nil or password == nil then
|
|
106 return nil
|
|
107 end
|
|
108 local user = get_by_name(name)
|
|
109 if user == nil or user.password ~= password then
|
|
110 return nil
|
|
111 end
|
|
112 return user
|
|
113 end
|
|
114
|
8
|
115 function User.current_required()
|
|
116 local user = User.current()
|
|
117 user or Http.response.send_redirect "/login.html"
|
|
118 return user
|
|
119 end
|
|
120
|
3
|
121 local password_chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
|
|
122 do
|
|
123 local t = {}
|
|
124 for i in range(1,#password_chars) do
|
|
125 t[#t+1] = sub_string(password_chars,i,i)
|
|
126 end
|
|
127 password_chars = t
|
|
128 end
|
|
129
|
|
130 local function new_password()
|
|
131 local n = #password_chars
|
|
132 local t = {}
|
|
133 for _ in range(1,10) do
|
|
134 t[#t+1] = password_chars[random(n)]
|
|
135 end
|
|
136 return concat(t)
|
|
137 end
|
|
138
|
|
139 function User.get_or_create_by_email(email)
|
|
140 local user = User.get_by_email(email)
|
|
141 if user == nil then
|
|
142 user = User.new{ email=email, password=new_password() }
|
|
143 user.save()
|
|
144 end
|
|
145 return user
|
|
146 end
|
|
147
|
|
148 return User
|