view src/lib/Shared.luan @ 4:028e74c8889d

add all_users
author Franklin Schmidt <fschmidt@gmail.com>
date Thu, 12 May 2022 16:54:11 -0600
parents dfc36e7ed22c
children
line wrap: on
line source

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

local user_repos = {}
for _, repo in pairs(config.repos) do
	for user in pairs(repo.users) do
		local repos = user_repos[user]
		if repos == nil then
			repos = {}
			user_repos[user] = repos
		end
		repos[#repos+1] = repo
	end
end
Shared.user_repos = user_repos

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