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
|
|
69 set_metatable(user,metatable)
|
|
70 return user
|
|
71 end
|
|
72
|
|
73 function User.get_by_email(email)
|
|
74 local doc = Db.get_document("user_email:"..lucene_quote(email))
|
|
75 return doc and from_doc(doc)
|
|
76 end
|
|
77
|
|
78 local function get_by_name(name)
|
43
|
79 local user = get_local_only(users_by_name,name)
|
|
80 if user ~= nil then return user end
|
3
|
81 local doc = Db.get_document("user_name:"..lucene_quote(name))
|
|
82 return doc and from_doc(doc)
|
|
83 end
|
|
84 User.get_by_name = get_by_name
|
|
85
|
|
86 function User.current()
|
|
87 local name = Http.request.cookies.user
|
|
88 local password = Http.request.cookies.password
|
|
89 if name == nil or password == nil then
|
|
90 return nil
|
|
91 end
|
|
92 local user = get_by_name(name)
|
|
93 if user == nil or user.password ~= password then
|
|
94 return nil
|
|
95 end
|
|
96 return user
|
|
97 end
|
|
98
|
8
|
99 function User.current_required()
|
|
100 local user = User.current()
|
|
101 user or Http.response.send_redirect "/login.html"
|
|
102 return user
|
|
103 end
|
|
104
|
3
|
105 local password_chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
|
|
106 do
|
|
107 local t = {}
|
|
108 for i in range(1,#password_chars) do
|
|
109 t[#t+1] = sub_string(password_chars,i,i)
|
|
110 end
|
|
111 password_chars = t
|
|
112 end
|
|
113
|
|
114 local function new_password()
|
|
115 local n = #password_chars
|
|
116 local t = {}
|
|
117 for _ in range(1,10) do
|
|
118 t[#t+1] = password_chars[random(n)]
|
|
119 end
|
|
120 return concat(t)
|
|
121 end
|
|
122
|
|
123 function User.get_or_create_by_email(email)
|
|
124 local user = User.get_by_email(email)
|
|
125 if user == nil then
|
|
126 user = User.new{ email=email, password=new_password() }
|
|
127 user.save()
|
|
128 end
|
|
129 return user
|
|
130 end
|
|
131
|
|
132 return User
|