diff src/lib/Shared.luan @ 0:dfc36e7ed22c

init
author Vadim Filimonov <fffilimonov@yandex.ru>
date Thu, 12 May 2022 13:51:59 +0400
parents
children 028e74c8889d
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lib/Shared.luan	Thu May 12 13:51:59 2022 +0400
@@ -0,0 +1,165 @@
+local Luan = require "luan:Luan.luan"
+local error = Luan.error
+local ipairs = Luan.ipairs or error()
+local pairs = Luan.pairs or error()
+local type = Luan.type or error()
+local set_metatable = Luan.set_metatable or error()
+local stringify = Luan.stringify or error()
+local parse = Luan.parse or error()
+local range = Luan.range or error()
+local String = require "luan:String.luan"
+local split = String.split or error()
+local trim = String.trim or error()
+local sub_string = String.sub or error()
+local Table = require "luan:Table.luan"
+local concat = Table.concat or error()
+local Math = require "luan:Math.luan"
+local random = Math.random or error()
+local Binary = require "luan:Binary.luan"
+local binary_base64_decode = Binary.base64_decode or error()
+local binary_to_string = Binary.to_string or error()
+local Io = require "luan:Io.luan"
+local uri = Io.uri or error()
+local Http = require "luan:http/Http.luan"
+local Logging = require "luan:logging/Logging.luan"
+local logger = Logging.logger "Shared"
+
+
+local Shared = {}
+
+function Shared.head()
+%>
+		<meta name="viewport" content="width=device-width, initial-scale=1">
+		<style>
+			@import "/site.css";
+		</style>
+<%
+end
+
+local function header(crumbs)
+%>
+		<div header>
+			<a href="/">Mercurial Hosting</a>
+<%	for _, crumb in ipairs(crumbs or {}) do %>
+			/ <%=crumb%>
+<%	end %>
+		</div>
+<%
+end
+Shared.header = header
+
+function Shared.admin_header()
+	header{
+		[[<a href="/admin/">Your Repositories</a>]]
+	}
+end
+
+function Shared.private_header()
+	header{
+		[[<a href="/private/">private</a>]]
+		[[<a href="/private/tools/">tools</a>]]
+	}
+end
+
+Shared.admin_return = [[<p>Return to <a href="/admin/">Your Repositories</a></p>]]
+
+local function base64_decode(s)
+	return binary_to_string(binary_base64_decode(s))
+end
+
+function Shared.get_user()
+	local s = Http.request.headers["Authorization"] or error "not authorized"
+	local tp, auth = split(s," ")
+	tp=="Basic" or error("invalid auth type: "..tp)
+	s = base64_decode(auth)
+	s = split(s,":")
+	return s
+end
+
+local function deep_copy(tbl)
+	local t = {}
+	for k,v in pairs(tbl) do
+		if type(v)=="table" then
+			v = deep_copy(v)
+		end
+		t[k] = v
+	end
+	return t
+end
+
+local set_mt = {}
+function set_mt.__index(table,key)
+	return false
+end
+
+local function list_to_set(list)
+	local set = {}
+	for _, v in ipairs(list) do
+		set[v] = true
+	end
+	set_metatable(set,set_mt)
+	return set
+end
+Shared.list_to_set = list_to_set
+
+function Shared.text_to_list(text)
+	local list = {}
+	for line in Io.schemes.string(text).read_lines() do
+		line = trim(line)
+		if line ~= "" then
+			list[#list+1] = line
+		end
+	end
+	return list
+end
+
+local password_chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
+do
+	local t = {}
+	for i in range(1,#password_chars) do
+		t[#t+1] = sub_string(password_chars,i,i)
+	end
+	password_chars = t
+end	
+
+function Shared.new_password()
+	local n = #password_chars
+	local t = {}
+	for _ in range(1,10) do
+		t[#t+1] = password_chars[random(n)]
+	end
+	return concat(t)
+end
+
+local raw_config = parse( uri("file:config/config.luano").read_text() )
+local config = deep_copy(raw_config)
+for name, repo in pairs(config.repos) do
+	repo.name = name
+	repo.users = list_to_set(repo.users)
+	repo.admins = list_to_set(repo.admins)
+end
+config.private = config.private and list_to_set(config.private)
+Shared.config = config
+
+function Shared.get_raw_config()
+	return deep_copy(raw_config)
+end
+
+local function reload_nginx()
+	local cmd = [[sudo $(which nginx) -s reload]]
+	local s = uri("bash:"..cmd).read_text()
+	logger.info("reload_nginx "..s)
+end
+
+function Shared.save_raw_config(raw_config)
+	local config_file = uri("file:config/config.luano")
+	local config_old = uri("file:config/config.luano.old")
+	config_old.delete()
+	config_file.move_to(config_old)
+	config_file.write_text(stringify(raw_config).."\n")
+	Http.reset_luan()
+	Luan.do_file "update_repositories.luan"
+	reload_nginx()
+end
+
+return Shared