summaryrefslogtreecommitdiffstats
path: root/server.lua
diff options
context:
space:
mode:
authorKaarle Ritvanen <kaarle.ritvanen@datakunkku.fi>2014-03-18 00:52:30 +0200
committerKaarle Ritvanen <kaarle.ritvanen@datakunkku.fi>2014-03-25 09:02:58 +0200
commit751f019580e210ff22fc1ac0eea72cece854534a (patch)
tree074f3226c7702ff8196207de84ab0e4ec88b5024 /server.lua
parent499351fd1c1e7c1462df9a962e927fb4dba6b594 (diff)
downloadaconf-751f019580e210ff22fc1ac0eea72cece854534a.tar.bz2
aconf-751f019580e210ff22fc1ac0eea72cece854534a.tar.xz
move permission checking from server to model
hide all model data and functions inaccessible to the user
Diffstat (limited to 'server.lua')
-rw-r--r--server.lua101
1 files changed, 34 insertions, 67 deletions
diff --git a/server.lua b/server.lua
index 7e6620f..bbb7798 100644
--- a/server.lua
+++ b/server.lua
@@ -67,7 +67,7 @@ return function(env)
end
end
- local session, user, txn_id
+ local session
function reset_session_expiry() session.expires = os.time() + 600 end
local sid = tonumber(env.HTTP_X_ACONF_AUTH_TOKEN)
@@ -75,47 +75,20 @@ return function(env)
session = sessions[sid]
if not session then return 401 end
reset_session_expiry()
- user = session.user
- txn_id = tonumber(env.HTTP_X_ACONF_TRANSACTION_ID)
- end
-
- local parent_txn
- if txn_id then
- parent_txn = session.txns[txn_id]
- if not parent_txn then
- return 400, nil, 'Invalid transaction ID'
- end
- end
-
- local function new_txn(defer_validation)
- return aconf.start_txn{
- allow_commit_defer=true,
- defer_validation=defer_validation,
- parent=parent_txn
- }
- end
-
- local txn = new_txn(true)
-
- local function fetch_user(name)
- user = name and txn:fetch('/auth/users')[name]
- end
- if user then
- fetch_user(user)
- if not user then return 401 end
end
if path == '/login' then
if method == 'POST' then
if not data.username or not data.password then return 401 end
- fetch_user(data.username)
+ local user =
+ aconf.start_txn():fetch('/auth/users')[data.username]
if user and user:check_password(data.password) then
local sid
repeat
sid = math.floor(math.random() * 2^32)
until not sessions[sid]
- session = {user=data.username, last_txn_id=0, txns={}}
+ session = {user=user, last_txn_id=0, txns={}}
reset_session_expiry()
sessions[sid] = session
return 204, {
@@ -126,7 +99,7 @@ return function(env)
return 401
end
- if not user then return 401 end
+ if not session then return 401 end
if method == 'DELETE' then
sessions[sid] = nil
@@ -136,7 +109,7 @@ return function(env)
return 405
end
- if not user then return 401 end
+ if not session then return 401 end
if path == '/save' then
if not save_req then return 404 end
@@ -147,6 +120,27 @@ return function(env)
local success, code, hdr, res = aconf.call(
function()
+ local txn_id = tonumber(env.HTTP_X_ACONF_TRANSACTION_ID)
+ local parent_txn
+
+ if txn_id then
+ parent_txn = session.txns[txn_id]
+ if not parent_txn then
+ return 400, nil, 'Invalid transaction ID'
+ end
+ end
+
+ local function new_txn(defer_validation)
+ return aconf.start_txn{
+ allow_commit_defer=true,
+ defer_validation=defer_validation,
+ parent=parent_txn,
+ user=session.user
+ }
+ end
+
+ local txn = new_txn(true)
+
if stringy.startswith(path, '/meta/') then
if method ~= 'GET' then return 405 end
return 200, nil, txn:meta(path:sub(6, -1))
@@ -167,30 +161,25 @@ return function(env)
if type(obj) == 'function' then return 404 end
if isinstance(obj, mnode.TreeNode) then
- if not mnode.has_permission(obj, user, 'read') then
- return 403
- end
-
local node = {}
for k, v in mnode.pairs(obj) do
local readable = true
if isinstance(v, mnode.TreeNode) then
- readable = mnode.has_permission(v, user, 'read')
v = mnode.path(v)
elseif isinstance(v, mbin.Data) then v = v.path end
- if readable then node[k] = v end
+ node[k] = v
end
res = {data=node, meta=mnode.meta(obj)}
- elseif mnode.has_permission(parent, user, 'read') then
+ else
if isinstance(obj, mbin.Data) then
obj = obj:encode()
end
res = {data=obj, meta=mnode.mmeta(parent, name)}
- else return 403 end
+ end
return 200, nil, res
end
@@ -199,10 +188,6 @@ return function(env)
local obj = txn:fetch(path)
if isinstance(obj, mnode.List) then
- if not mnode.has_permission(obj, user, 'create') then
- return 403
- end
-
local index
if not isinstance(obj, mnode.Set) then
index = data.index
@@ -210,37 +195,17 @@ return function(env)
end
mnode.insert(obj, data, index)
- elseif type(obj) == 'function' then
- if not mnode.has_permission(parent, user, name) then
- return 403
- end
- res = obj(data)
+ elseif type(obj) == 'function' then res = obj(data)
else return 405 end
else
- local obj = parent[name]
- if obj ~= nil and not isinstance(obj, mnode.TreeNode) then
- obj = parent
- end
-
if method == 'DELETE' then
- if obj == nil then return 404 end
- if not mnode.has_permission(obj, user, 'delete') then
- return 403
- end
+ if parent[name] == nil then return 404 end
parent[name] = nil
elseif method == 'PUT' then
if isinstance(parent, mnode.Set) then return 405 end
- local permission = 'modify'
- if obj == nil then
- obj = parent
- permission = 'create'
- end
- if not mnode.has_permission(obj, user, permission) then
- return 403
- end
parent[name] = data
else return 405 end
@@ -272,6 +237,8 @@ return function(env)
if success then return code, hdr, res, true end
+ if code.forbidden then return 403, nil, code.forbidden, true end
+
if code.conflict then return 409, nil, code.conflict, true end
return 422, nil, code, true