Mercurial Hosting > freedit
annotate src/lib/User.luan @ 61:389e5d8e5f8a default tip
minor
| author | Franklin Schmidt <fschmidt@gmail.com> |
|---|---|
| date | Tue, 06 Dec 2022 13:37:25 -0700 |
| parents | 02d8876dc41d |
| children |
| rev | line source |
|---|---|
| 3 | 1 local Luan = require "luan:Luan.luan" |
| 2 local error = Luan.error | |
| 3 local set_metatable = Luan.set_metatable or error() | |
| 56 | 4 local type = Luan.type or error() |
| 5 local to_string = Luan.to_string or error() | |
| 3 | 6 local range = Luan.range or error() |
| 43 | 7 local set_local_only = Luan.set_local_only or error() |
| 8 local get_local_only = Luan.get_local_only or error() | |
| 3 | 9 local String = require "luan:String.luan" |
| 10 local sub_string = String.sub or error() | |
| 56 | 11 local to_number = String.to_number or error() |
| 12 local regex = String.regex or error() | |
| 3 | 13 local Table = require "luan:Table.luan" |
| 14 local concat = Table.concat or error() | |
| 15 local Math = require "luan:Math.luan" | |
| 16 local random = Math.random or error() | |
| 17 local Time = require "luan:Time.luan" | |
| 18 local time_now = Time.now or error() | |
| 19 local Html = require "luan:Html.luan" | |
| 20 local html_encode = Html.encode or error() | |
| 56 | 21 local Number = require "luan:Number.luan" |
| 22 local long = Number.long or error() | |
| 3 | 23 local Lucene = require "luan:lucene/Lucene.luan" |
| 24 local lucene_quote = Lucene.quote or error() | |
| 25 local Http = require "luan:http/Http.luan" | |
| 26 local Db = require "site:/lib/Db.luan" | |
|
55
c57b84f461ae
login and registration work
Franklin Schmidt <fschmidt@gmail.com>
parents:
54
diff
changeset
|
27 local run_in_transaction = Db.run_in_transaction or error() |
| 3 | 28 |
| 29 | |
| 30 local User = {} | |
| 31 | |
| 56 | 32 local users_by_id = {} |
| 43 | 33 |
| 3 | 34 local function from_doc(doc) |
| 35 doc.type == "user" or error "wrong type" | |
| 43 | 36 local user = User.new { |
| 3 | 37 id = doc.id |
| 38 email = doc.user_email | |
| 39 password = doc.password | |
| 40 name = doc.user_name | |
| 41 created = doc.created | |
| 59 | 42 hidden_password = doc.hidden_password |
| 43 new_email = doc.new_email | |
| 3 | 44 } |
| 56 | 45 set_local_only(users_by_id,user.id,user) |
| 43 | 46 return user |
| 3 | 47 end |
| 48 | |
| 49 local function to_doc(user) | |
| 50 local email = user.email | |
| 51 return { | |
| 52 type = "user" | |
| 53 id = user.id | |
| 54 user_email = email | |
| 55 password = user.password | |
| 56 user_name = user.name | |
| 57 created = user.created or time_now() | |
| 59 | 58 hidden_password = user.hidden_password |
| 59 new_email = user.new_email | |
| 3 | 60 } |
| 61 end | |
| 62 | |
| 63 local metatable = {} | |
| 64 function metatable.__index(user,key) | |
| 65 if key == "name_html" then | |
| 66 user.name_html = html_encode(user.name) | |
| 67 return user.name_html | |
| 68 end | |
| 69 return nil | |
| 70 end | |
| 71 | |
| 72 function User.new(user) | |
| 73 | |
| 74 function user.save() | |
| 75 local doc = to_doc(user) | |
| 76 Db.save(doc) | |
| 77 user.id = doc.id | |
| 78 end | |
| 79 | |
| 54 | 80 function user.reload() |
| 81 return User.get_by_id(user.id) or error(user.id) | |
| 82 end | |
| 83 | |
| 84 function user.login() | |
| 56 | 85 local id = to_string(user.id) |
| 86 Http.response.set_persistent_cookie("user",id) | |
| 54 | 87 Http.response.set_persistent_cookie("password",user.password) |
| 56 | 88 Http.request.cookies.user = id |
| 54 | 89 Http.request.cookies.password = user.password or error() |
| 90 end | |
| 91 | |
| 3 | 92 set_metatable(user,metatable) |
| 93 return user | |
| 94 end | |
| 95 | |
| 56 | 96 local function get_by_id(id) |
| 97 if type(id) == "string" then | |
| 98 id = to_number(id) | |
| 99 if id == nil then return nil end | |
| 100 end | |
| 101 id = long(id) | |
| 102 if not Db.is_in_transaction() then | |
| 103 local user = get_local_only(users_by_id,id) | |
| 104 if user ~= nil then return user end | |
| 105 end | |
| 54 | 106 local doc = Db.get_document("id:"..id) |
| 61 | 107 return doc and doc.type=="user" and from_doc(doc) or nil |
| 54 | 108 end |
| 56 | 109 User.get_by_id = get_by_id |
| 54 | 110 |
| 3 | 111 function User.get_by_email(email) |
| 112 local doc = Db.get_document("user_email:"..lucene_quote(email)) | |
| 113 return doc and from_doc(doc) | |
| 114 end | |
| 115 | |
| 56 | 116 function User.get_by_name(name) |
| 3 | 117 local doc = Db.get_document("user_name:"..lucene_quote(name)) |
| 118 return doc and from_doc(doc) | |
| 119 end | |
| 120 | |
| 121 function User.current() | |
| 56 | 122 local id = Http.request.cookies.user |
| 3 | 123 local password = Http.request.cookies.password |
| 56 | 124 if id == nil or password == nil then |
| 3 | 125 return nil |
| 126 end | |
| 56 | 127 local user = get_by_id(id) |
| 3 | 128 if user == nil or user.password ~= password then |
| 129 return nil | |
| 130 end | |
| 131 return user | |
| 132 end | |
| 133 | |
| 8 | 134 function User.current_required() |
| 135 local user = User.current() | |
| 136 user or Http.response.send_redirect "/login.html" | |
| 137 return user | |
| 138 end | |
| 139 | |
| 3 | 140 local password_chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" |
| 141 do | |
| 142 local t = {} | |
| 143 for i in range(1,#password_chars) do | |
| 144 t[#t+1] = sub_string(password_chars,i,i) | |
| 145 end | |
| 146 password_chars = t | |
| 147 end | |
| 148 | |
| 149 local function new_password() | |
| 150 local n = #password_chars | |
| 151 local t = {} | |
| 152 for _ in range(1,10) do | |
| 153 t[#t+1] = password_chars[random(n)] | |
| 154 end | |
| 155 return concat(t) | |
| 156 end | |
| 57 | 157 User.new_password = new_password |
| 3 | 158 |
|
55
c57b84f461ae
login and registration work
Franklin Schmidt <fschmidt@gmail.com>
parents:
54
diff
changeset
|
159 function User.get_or_create_by_email(email,change_password) |
| 3 | 160 local user = User.get_by_email(email) |
| 161 if user == nil then | |
| 56 | 162 run_in_transaction( function() |
| 163 user = User.new{ email=email, password=new_password() } | |
| 164 user.save() | |
| 165 end ) | |
|
55
c57b84f461ae
login and registration work
Franklin Schmidt <fschmidt@gmail.com>
parents:
54
diff
changeset
|
166 elseif change_password then |
|
c57b84f461ae
login and registration work
Franklin Schmidt <fschmidt@gmail.com>
parents:
54
diff
changeset
|
167 run_in_transaction( function() |
|
c57b84f461ae
login and registration work
Franklin Schmidt <fschmidt@gmail.com>
parents:
54
diff
changeset
|
168 user = user.reload() |
|
c57b84f461ae
login and registration work
Franklin Schmidt <fschmidt@gmail.com>
parents:
54
diff
changeset
|
169 user.password = new_password() |
|
c57b84f461ae
login and registration work
Franklin Schmidt <fschmidt@gmail.com>
parents:
54
diff
changeset
|
170 user.save() |
|
c57b84f461ae
login and registration work
Franklin Schmidt <fschmidt@gmail.com>
parents:
54
diff
changeset
|
171 end ) |
| 3 | 172 end |
| 173 return user | |
| 174 end | |
| 175 | |
| 56 | 176 User.name_regex = regex "^[a-zA-Z0-9_-]+$" |
| 177 | |
| 3 | 178 return User |
