From 55ce9de27314a53bb5583cf482a2c4c64e3d1f76 Mon Sep 17 00:00:00 2001 From: Hans Hagen Date: Tue, 25 Sep 2012 21:44:00 +0200 Subject: beta 2012.09.25 21:44 --- tex/context/base/cont-new.mkii | 2 +- tex/context/base/cont-new.mkiv | 2 +- tex/context/base/context-version.pdf | Bin 4146 -> 4147 bytes tex/context/base/context-version.png | Bin 106782 -> 106662 bytes tex/context/base/context.mkii | 2 +- tex/context/base/context.mkiv | 2 +- tex/context/base/grph-inc.mkiv | 6 +- tex/context/base/l-boolean.lua | 4 +- tex/context/base/status-files.pdf | Bin 24590 -> 24572 bytes tex/context/base/status-lua.pdf | Bin 195090 -> 195090 bytes tex/context/base/util-sql-tickets.lua | 6 +- tex/context/base/util-sql-users.lua | 351 +++++++++++++++++++++ tex/context/base/util-sql.lua | 26 +- tex/context/base/util-tab.lua | 3 + tex/generic/context/luatex/luatex-fonts-merged.lua | 6 +- 15 files changed, 392 insertions(+), 18 deletions(-) create mode 100644 tex/context/base/util-sql-users.lua (limited to 'tex') diff --git a/tex/context/base/cont-new.mkii b/tex/context/base/cont-new.mkii index cf8f6e8fc..d6ff107a3 100644 --- a/tex/context/base/cont-new.mkii +++ b/tex/context/base/cont-new.mkii @@ -11,7 +11,7 @@ %C therefore copyrighted by \PRAGMA. See mreadme.pdf for %C details. -\newcontextversion{2012.09.23 12:40} +\newcontextversion{2012.09.25 21:44} %D This file is loaded at runtime, thereby providing an %D excellent place for hacks, patches, extensions and new diff --git a/tex/context/base/cont-new.mkiv b/tex/context/base/cont-new.mkiv index 1903c8021..e8be14c7f 100644 --- a/tex/context/base/cont-new.mkiv +++ b/tex/context/base/cont-new.mkiv @@ -11,7 +11,7 @@ %C therefore copyrighted by \PRAGMA. See mreadme.pdf for %C details. -\newcontextversion{2012.09.23 12:40} +\newcontextversion{2012.09.25 21:44} %D This file is loaded at runtime, thereby providing an excellent place for %D hacks, patches, extensions and new features. diff --git a/tex/context/base/context-version.pdf b/tex/context/base/context-version.pdf index 5704374eb..62b3117f7 100644 Binary files a/tex/context/base/context-version.pdf and b/tex/context/base/context-version.pdf differ diff --git a/tex/context/base/context-version.png b/tex/context/base/context-version.png index cd12a10ca..91f5d5658 100644 Binary files a/tex/context/base/context-version.png and b/tex/context/base/context-version.png differ diff --git a/tex/context/base/context.mkii b/tex/context/base/context.mkii index ba9e7146b..db6a3d13d 100644 --- a/tex/context/base/context.mkii +++ b/tex/context/base/context.mkii @@ -20,7 +20,7 @@ %D your styles an modules. \edef\contextformat {\jobname} -\edef\contextversion{2012.09.23 12:40} +\edef\contextversion{2012.09.25 21:44} %D For those who want to use this: diff --git a/tex/context/base/context.mkiv b/tex/context/base/context.mkiv index 36401fbd3..c4d1a313b 100644 --- a/tex/context/base/context.mkiv +++ b/tex/context/base/context.mkiv @@ -25,7 +25,7 @@ %D up and the dependencies are more consistent. \edef\contextformat {\jobname} -\edef\contextversion{2012.09.23 12:40} +\edef\contextversion{2012.09.25 21:44} %D For those who want to use this: diff --git a/tex/context/base/grph-inc.mkiv b/tex/context/base/grph-inc.mkiv index 74f10b0b0..f96812d26 100644 --- a/tex/context/base/grph-inc.mkiv +++ b/tex/context/base/grph-inc.mkiv @@ -745,10 +745,8 @@ % \eTABLE % \stoptext -\unexpanded\def\showexternalfigures % maybe run time command is better, but no core-run, unless figs-run ... - {%\writestatus\m!system{for \string\showexternalfigures\space see \truefilename{x-res-20}.tex} - \usemodule[res-20]% - \showexternalfigures} % so for the moment we do it this way +\unexpanded\def\showexternalfigures + {\writestatus\m!system{the \string\showexternalfigures\space command is not (yet) implemented in mkiv}} \unexpanded\def\overlayfigure#1% {\externalfigure[#1][\c!width=\overlaywidth,\c!height=\overlayheight]} diff --git a/tex/context/base/l-boolean.lua b/tex/context/base/l-boolean.lua index 2d502f164..4294cf8f0 100644 --- a/tex/context/base/l-boolean.lua +++ b/tex/context/base/l-boolean.lua @@ -16,7 +16,9 @@ function boolean.tonumber(b) end function toboolean(str,tolerant) - if tolerant then + if str == true or str == false then + return str + elseif tolerant then local tstr = type(str) if tstr == "string" then return str == "true" or str == "yes" or str == "on" or str == "1" or str == "t" diff --git a/tex/context/base/status-files.pdf b/tex/context/base/status-files.pdf index 68184675b..9e72bd5c2 100644 Binary files a/tex/context/base/status-files.pdf and b/tex/context/base/status-files.pdf differ diff --git a/tex/context/base/status-lua.pdf b/tex/context/base/status-lua.pdf index a2d807b15..1e5074cb6 100644 Binary files a/tex/context/base/status-lua.pdf and b/tex/context/base/status-lua.pdf differ diff --git a/tex/context/base/util-sql-tickets.lua b/tex/context/base/util-sql-tickets.lua index ad885e34e..1dfe1e376 100644 --- a/tex/context/base/util-sql-tickets.lua +++ b/tex/context/base/util-sql-tickets.lua @@ -164,12 +164,12 @@ function tickets.create(db,ticket) report("created: %s at %s",token,osfulltime(time)) end - local r = result and result[1] + local id = result and result.id - if r then + if id then return { - id = r.id, + id = id, token = token, subtoken = subtoken, created = time, diff --git a/tex/context/base/util-sql-users.lua b/tex/context/base/util-sql-users.lua new file mode 100644 index 000000000..4389b905c --- /dev/null +++ b/tex/context/base/util-sql-users.lua @@ -0,0 +1,351 @@ +if not modules then modules = { } end modules ['util-sql-users'] = { + version = 1.001, + comment = "companion to lmx-*", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +-- This is experimental code and currently part of the base installation simply +-- because it's easier to dirtribute this way. Eventually it will be documented +-- and the related scripts will show up as well. + +local sql = require("util-sql") +local md5 = require("md5") + +local format, upper, find, gsub = string.format, string.upper, string.find, string.gsub +local sumhexa = md5.sumhexa + +local users = { } +sql.users = users + +local trace_sql = false trackers.register("sql.users.trace", function(v) trace_sql = v end) +local report = logs.reporter("sql","users") + +local function encryptpassword(str) + if not str or str == "" then + return "" + elseif find(str,"^MD5:") then + return str + else + return upper(format("MD5:%s",sumhexa(str))) + end +end + +local function cleanuppassword(str) + return (gsub(str,"^MD5:","")) +end + +local function samepasswords(one,two) + if not find(one,"^MD5:") then + one = encryptpassword(one) + end + if not find(two,"^MD5:") then + two = encryptpassword(two) + end + return one == two +end + +users.encryptpassword = encryptpassword +users.cleanuppassword = cleanuppassword +users.samepasswords = samepasswords + +-- print(users.encryptpassword("test")) -- MD5:098F6BCD4621D373CADE4E832627B4F6 + +local function checkeddb(presets,datatable) + return sql.usedatabase(presets,datatable or presets.datatable or "users") +end + +users.usedb = checkeddb + +local groupnames = { } +local groupnumbers = { } + +local function registergroup(name) + local n = #groupnames + 1 + groupnames [n] = name + groupnames [tostring(n)] = name + groupnames [name] = name + groupnumbers[n] = n + groupnumbers[tostring(n)] = n + groupnumbers[name] = n + return n +end + +registergroup("superuser") +registergroup("administrator") +registergroup("user") +registergroup("guest") + +users.groupnames = groupnames +users.groupnumbers = groupnumbers + +-- -- password 'test': +-- +-- INSERT insert into users (`name`,`password`,`group`,`enabled`) values ('...','MD5:098F6BCD4621D373CADE4E832627B4F6',1,1) ; + +local template =[[ + CREATE TABLE `users` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `name` varchar(80) NOT NULL, + `password` varbinary(50) DEFAULT NULL, + `group` int(11) NOT NULL, + `enabled` int(11) DEFAULT '1', + `email` varchar(80) DEFAULT NULL, + `data` longtext, + PRIMARY KEY (`id`), + UNIQUE KEY `name_unique` (`name`) + ) DEFAULT CHARSET = utf8 ; +]] + +local converter, fields = sql.makeconverter { + { name = "id", type = "number" }, + { name = "name", type = "string" }, + { name = "password", type = "string" }, + { name = "group", type = groupnames }, + { name = "enabled", type = "boolean" }, + { name = "email", type = "string" }, + { name = "data", type = "deserialize" }, +} + +function users.createdb(presets,datatable) + + local db = checkeddb(presets,datatable) + + db.execute { + template = template, + variables = { + basename = db.basename, + }, + } + + report("datatable %q created in %q",db.name,db.base) + + return db + +end + +local template =[[ + SELECT + %fields% + FROM + %basename% + WHERE + `name` = '%name%' + AND + `password` = '%password%' + ; +]] + +function users.valid(db,username,password) + + local data = db.execute { + template = template, + converter = converter, + variables = { + basename = db.basename, + fields = fields, + name = username, + password = encryptpassword(password), + }, + } + + local data = data and data[1] + + if not data then + return false, "unknown" + elseif not data.enabled then + return false, "disabled" + else + data.password = nil + return data, "okay" + end + +end + +local template =[[ + INSERT INTO %basename% ( + `name`, + `password`, + `group`, + `enabled`, + `email`, + `data` + ) VALUES ( + '%name%', + '%password%', + '%group%', + '%enabled%', + '%email%', + '%[data]%' + ) ; +]] + +function users.add(db,specification) + + local name = specification.username or specification.name + + if not name or name == "" then + return + end + + db.execute { + template = template, + variables = { + basename = db.basename, + name = name, + password = encryptpassword(specification.password or ""), + group = groupnumbers[specification.group] or groupnumbers.guest, + enabled = toboolean(specification.enabled,true) and "1" or "0", + email = specification.email, + data = type(specification.data) == "table" and db.serialize(specification.data,"return") or "", + }, + } + +end + +local template =[[ + SELECT + %fields% + FROM + %basename% + WHERE + `name` = '%name%' ; +]] + +function users.getbyname(db,name) + + local data = db.execute { + template = template, + converter = converter, + variables = { + basename = db.basename, + fields = fields, + name = name, + }, + } + + return data and data[1] or nil + +end + +local template =[[ + SELECT + %fields% + FROM + %basename% + WHERE + `id` = '%id%' ; +]] + +local function getbyid(db,id) + + local data = db.execute { + template = template, + converter = converter, + variables = { + basename = db.basename, + fields = fields, + id = id, + }, + } + + return data and data[1] or nil + +end + +users.getbyid = getbyid + +local template =[[ + UPDATE + %basename% + SET + `password` = '%password%', + `group` = '%group%', + `enabled` = '%enabled%', + `email` = '%email%', + `data` = '%[data]%' + WHERE + `id` = '%id%' + ; +]] + +function users.save(db,id,specification) + + if not tonumber(id) then + return + end + + local user = getbyid(db,id) + + if user.id ~= id then + return + end + + local password = specification.password == nil and user.password or specification.password + local group = specification.group == nil and user.group or specification.group + local enabled = specification.enabled == nil and user.enabled or specification.enabled + local email = specification.email == nil and user.email or specification.email + local data = specification.data == nil and user.data or specification.data + +-- table.print(data) + + db.execute { + template = template, + variables = { + basename = db.basename, + id = id, + password = encryptpassword(password), + group = groupnumbers[group], + enabled = toboolean(enabled,true) and "1" or "0", + email = email, + data = type(data) == "table" and db.serialize(data,"return") or "", + }, + } + + return getbyid(db,id) + +end + +local template =[[ + DELETE FROM + %basename% + WHERE + `id` = '%id%' ; +]] + +function users.remove(db,id) + + db.execute { + template = template, + variables = { + basename = db.basename, + id = id, + }, + } + +end + +local template =[[ + SELECT + %fields% + FROM + %basename% + ORDER BY + `name` ; +]] + +function users.collect(db) -- maybe also an id/name only variant + + local records, keys = db.execute { + template = template, + converter = converter, + variables = { + basename = db.basename, + fields = fields, + }, + } + + return records, keys + +end diff --git a/tex/context/base/util-sql.lua b/tex/context/base/util-sql.lua index fea60c96a..4e9a5bcd4 100644 --- a/tex/context/base/util-sql.lua +++ b/tex/context/base/util-sql.lua @@ -348,6 +348,10 @@ local function execute(specification) report_state("error in converting") return end + local one = data[1] + if one then + setmetatable(data,{ __index = one } ) + end return data, keys end @@ -407,6 +411,10 @@ local function execute(specification) report_state("error in converting") return end + local one = data[1] + if one then + setmetatable(data,{ __index = one } ) + end return data, keys end @@ -464,6 +472,10 @@ local query = whitespace local splitter = Ct(query * (separator * query)^0) local function datafetched(specification,query,converter) + if not query or query == "" then + report_state("no valid query") + return { }, { } + end local id = specification.id local session, connection if id then @@ -605,6 +617,10 @@ local function execute(specification) report_state("error in fetching") return end + local one = data[1] + if one then + setmetatable(data,{ __index = one } ) + end return data, keys end @@ -764,7 +780,7 @@ return function(result,deserialize) local data = { } for i=1,nofrows do local v = { result:fetch() } - data[#data+1] = { + data[i] = { %s } end @@ -775,6 +791,7 @@ end function sql.makeconverter(entries,deserialize) local shortcuts = { } local assignments = { } + local fields = { } for i=1,#entries do local entry = entries[i] local nam = entry.name @@ -798,13 +815,12 @@ function sql.makeconverter(entries,deserialize) else assignments[i] = format("[%q] = v[%s],",nam,i) end + fields[#fields+1] = format("`%s`",nam) end local code = string.format(template,table.concat(shortcuts,"\n"),table.concat(assignments,"\n ")) local func = loadstring(code) if type(func) == "function" then - return func(), code - else - return false, code + return func(), concat(fields, ", ") end end @@ -850,3 +866,5 @@ else sql.prepare = sql.execute end + +return sql diff --git a/tex/context/base/util-tab.lua b/tex/context/base/util-tab.lua index f0977743b..7a2da298e 100644 --- a/tex/context/base/util-tab.lua +++ b/tex/context/base/util-tab.lua @@ -213,6 +213,9 @@ function table.fastserialize(t,prefix) end function table.deserialize(str) + if not str or str == "" then + return + end local code = loadstring(str) if not code then return diff --git a/tex/generic/context/luatex/luatex-fonts-merged.lua b/tex/generic/context/luatex/luatex-fonts-merged.lua index 36a74ff01..9862853db 100644 --- a/tex/generic/context/luatex/luatex-fonts-merged.lua +++ b/tex/generic/context/luatex/luatex-fonts-merged.lua @@ -1,6 +1,6 @@ -- merged file : luatex-fonts-merged.lua -- parent file : luatex-fonts.lua --- merge date : 09/23/12 12:40:12 +-- merge date : 09/25/12 21:44:34 do -- begin closure to overcome local limits and interference @@ -2033,7 +2033,9 @@ function boolean.tonumber(b) end function toboolean(str,tolerant) - if tolerant then + if str == true or str == false then + return str + elseif tolerant then local tstr = type(str) if tstr == "string" then return str == "true" or str == "yes" or str == "on" or str == "1" or str == "t" -- cgit v1.2.3