You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ponymail.apache.org by se...@apache.org on 2016/12/15 21:50:06 UTC
incubator-ponymail git commit: lib/aaa.lua overwrites local
customisations on updates
Repository: incubator-ponymail
Updated Branches:
refs/heads/master 0426f671a -> b2947f610
lib/aaa.lua overwrites local customisations on updates
This fixes #292
Project: http://git-wip-us.apache.org/repos/asf/incubator-ponymail/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-ponymail/commit/b2947f61
Tree: http://git-wip-us.apache.org/repos/asf/incubator-ponymail/tree/b2947f61
Diff: http://git-wip-us.apache.org/repos/asf/incubator-ponymail/diff/b2947f61
Branch: refs/heads/master
Commit: b2947f610b5e46b5533646b807be62fc65186414
Parents: 0426f67
Author: Sebb <se...@apache.org>
Authored: Thu Dec 15 21:49:32 2016 +0000
Committer: Sebb <se...@apache.org>
Committed: Thu Dec 15 21:49:32 2016 +0000
----------------------------------------------------------------------
.gitignore | 4 ++
CHANGELOG.md | 1 +
RELEASE-NOTES.md | 23 +++++++
aaa_examples/aaa_with_ldap.lua | 84 ++++++++++++++++++++++++
site/api/lib/aaa.lua | 126 ++++++++++++++++--------------------
5 files changed, 167 insertions(+), 71 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-ponymail/blob/b2947f61/.gitignore
----------------------------------------------------------------------
diff --git a/.gitignore b/.gitignore
index 7a53ef8..1beebb2 100644
--- a/.gitignore
+++ b/.gitignore
@@ -14,6 +14,10 @@ site/api/lib/config.lua
site/js/config.js
tools/ponymail.cfg
+# site-local AAA module
+site/api/lib/aaa_site.lua
+
+
# Note:
# Add local overrides to one of the following files:
# $HOME/.config/git/ignore - applies to all local git repos
http://git-wip-us.apache.org/repos/asf/incubator-ponymail/blob/b2947f61/CHANGELOG.md
----------------------------------------------------------------------
diff --git a/CHANGELOG.md b/CHANGELOG.md
index b0a435b..00c458e 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -65,6 +65,7 @@
- inconsistent rights checking (#267)
- thread.lua fails to fetch rights when fetching private child of public parent (#296)
- typo in all example aaa modules: xemail != exmail (#299)
+-
## CHANGES in 0.9b:
http://git-wip-us.apache.org/repos/asf/incubator-ponymail/blob/b2947f61/RELEASE-NOTES.md
----------------------------------------------------------------------
diff --git a/RELEASE-NOTES.md b/RELEASE-NOTES.md
new file mode 100644
index 0000000..4b46ccd
--- /dev/null
+++ b/RELEASE-NOTES.md
@@ -0,0 +1,23 @@
+# Apache Pony Mail (Incubating)
+
+Release Notes
+
+## Version 0.10 ##
+
+### Change to AAA ###
+
+Pony Mail now has two AAA modules:
+- lib/aaa.lua
+- lib/aaa_site.lua
+
+The aaa.lua file is now a generic module which implements the AAA API.
+It does not grant any rights; that must be done by the aaa_site.lua module.
+
+Before updating an existing installation, copy aaa.lua to aaa_site.lua otherwise it will be overwritten.
+The new generic aaa.lua module will automatically use aaa_site.lua if present.
+
+If this is a new installation, the lib/aaa_site.lua module needs to be created.
+There are several examples in the aaa_examples directory or you can create your own.
+
+This was done to simplify subsequent releases.
+
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-ponymail/blob/b2947f61/aaa_examples/aaa_with_ldap.lua
----------------------------------------------------------------------
diff --git a/aaa_examples/aaa_with_ldap.lua b/aaa_examples/aaa_with_ldap.lua
new file mode 100644
index 0000000..8672683
--- /dev/null
+++ b/aaa_examples/aaa_with_ldap.lua
@@ -0,0 +1,84 @@
+--[[
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+]]
+
+-- This is aaa_site.lua - site-specific AAA filter for ASF.
+
+-- Get a list of PMCs the user is a part of
+local function getPMCs(r, uid)
+ local groups = {}
+ local ldapdata = io.popen( ([[ldapsearch -x -LLL "(|(memberUid=%s)(member=uid=%s,ou=people,dc=apache,dc=org))" cn]]):format(uid,uid) )
+ local data = ldapdata:read("*a")
+ for match in data:gmatch("dn: cn=([-a-zA-Z0-9]+),ou=pmc,ou=committees,ou=groups,dc=apache,dc=org") do
+ table.insert(groups, match)
+ end
+ return groups
+end
+
+
+-- Is $uid a member of the ASF?
+local function isMember(r, uid)
+
+ -- First, check the 30 minute cache
+ local NOWISH = math.floor(os.time() / 1800)
+ local MEMBER_KEY = "isMember_" .. NOWISH .. "_" .. uid
+ local t = r:ivm_get(MEMBER_KEY)
+
+ -- If cached, then just return the value
+ if t then
+ return tonumber(t) == 1
+
+ -- Otherwise, look in LDAP
+ else
+ local ldapdata = io.popen([[ldapsearch -x -LLL -b cn=member,ou=groups,dc=apache,dc=org]])
+ local data = ldapdata:read("*a")
+ for match in data:gmatch("memberUid: ([-a-z0-9_.]+)") do
+ -- Found it?
+ if match == uid then
+ -- Set cache
+ r:ivm_set(MEMBER_KEY, "1")
+ return true
+ end
+ end
+ end
+
+ -- Set cache
+ r:ivm_set(MEMBER_KEY, "0")
+ return false
+end
+
+-- Get a list of domains the user has private email access to (or wildcard if org member)
+local function getRights(r, usr)
+ local uid = usr.credentials.uid
+ local rights = {}
+ -- Check if uid has member (admin) rights
+ if usr.internal.admin or isMember(r, uid) then
+ table.insert(rights, "*")
+ -- otherwise, get PMC list and construct array
+ else
+ local list = getPMCs(r, uid)
+ for k, v in pairs(list) do
+ table.insert(rights, v .. ".apache.org")
+ end
+ end
+ return rights
+end
+
+-- module defs
+return {
+ rights = getRights,
+ validateParams = true
+}
http://git-wip-us.apache.org/repos/asf/incubator-ponymail/blob/b2947f61/site/api/lib/aaa.lua
----------------------------------------------------------------------
diff --git a/site/api/lib/aaa.lua b/site/api/lib/aaa.lua
index d116909..cdc3481 100644
--- a/site/api/lib/aaa.lua
+++ b/site/api/lib/aaa.lua
@@ -13,75 +13,41 @@
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-]]--
+]]
--- This is aaa.lua - AAA filter for ASF.
-
-local config = require 'lib/config'
-
--- Get a list of PMCs the user is a part of
-local function getPMCs(r, uid)
- local groups = {}
- local ldapdata = io.popen( ([[ldapsearch -x -LLL "(|(memberUid=%s)(member=uid=%s,ou=people,dc=apache,dc=org))" cn]]):format(uid,uid) )
- local data = ldapdata:read("*a")
- for match in data:gmatch("dn: cn=([-a-zA-Z0-9]+),ou=pmc,ou=committees,ou=groups,dc=apache,dc=org") do
- table.insert(groups, match)
- end
- return groups
-end
+--[[
+ This is aaa.lua - generic AAA module.
+ It includes a basic version of the API.
+ However the default does not grant any rights.
+ Each site must provide their own customised AAA module.
+ The site-specific module must be called 'aaa_site.lua'
+ and be located in the lib/ directory.
+ ]]
--- Is $uid a member of the org?
-local function isMember(r, uid)
-
- -- First, check the 30 minute cache
- local NOWISH = math.floor(os.time() / 1800)
- local MEMBER_KEY = "isMember_" .. NOWISH .. "_" .. uid
- local t = r:ivm_get(MEMBER_KEY)
-
- -- If cached, then just return the value
- if t then
- return tonumber(t) == 1
-
- -- Otherwise, look in LDAP
- else
- local ldapdata = io.popen([[ldapsearch -x -LLL -b cn=member,ou=groups,dc=apache,dc=org]])
- local data = ldapdata:read("*a")
- for match in data:gmatch("memberUid: ([-a-z0-9_.]+)") do
- -- Found it?
- if match == uid then
- -- Set cache
- r:ivm_set(MEMBER_KEY, "1")
- return true
- end
- end
- end
-
- -- Set cache
- r:ivm_set(MEMBER_KEY, "0")
- return false
-end
+local config = require 'lib/config'
--- Get a list of domains the user has private email access to (or wildcard if org member)
-local function getRights(r, usr)
- if not usr.credentials then
- return {}
- end
+local aaa_site = nil
+pcall(function() aaa_site = require 'lib/aaa_site' end)
+--[[
+ The module is expected to return the following:
+ {
+ rights = function(r, account) to get the rights
+ validateParams = true/false (optional)
+ }
+]]
- local xuid = usr.credentials.uid or usr.credentials.email or "|||"
- local uid = xuid:match("([-a-zA-Z0-9._]+)") -- whitelist
- local rights = {}
- -- bad char in uid?
- if not uid or xuid ~= uid then
- return rights
+--Basic parameter validation
+local function validateParams(r, account)
+ if not account.credentials then
+ return false -- no credentials, cannot grant rights
end
-
-- Check that we used oauth, bail if not
- local oauth_domain = usr.internal and usr.internal.oauth_used or nil
+ local oauth_domain = account.internal and account.internal.oauth_used or nil
if not oauth_domain then
- return {}
+ return false -- no valid auth
end
-
+
-- check if oauth was through an oauth portal that can give privacy rights
local authority = false
for k, v in pairs(config.admin_oauth or {}) do
@@ -90,22 +56,40 @@ local function getRights(r, usr)
break
end
end
+
-- if not a 'good' oauth, then let's forget all about it
if not authority then
- return rights
+ return false
end
-
- -- Check if uid has member (admin) rights
- if usr.internal.admin or isMember(r, uid) then
- table.insert(rights, "*")
- -- otherwise, get PMC list and construct array
- else
- local list = getPMCs(r, uid)
- for k, v in pairs(list) do
- table.insert(rights, v .. ".apache.org")
+
+ -- if the uid exists, then validate it
+ local uid = account.credentials.uid
+ if uid and (not uid:match("^[-a-zA-Z0-9._]+$") or uid:sub(1,1) == '-') then
+ return false
+ end
+ -- TODO is there any further common validation possible?
+ -- not sure it makes sense to validate an email address here;
+ -- if required it should be done by the site module
+ return true
+end
+
+--[[
+ Get the set of rights to be used for checking access to private documents.
+
+ The default implementation returns an empty set of rights.
+]]
+local function getRights(r, account)
+ if aaa_site then -- we have a site override module
+ -- should we pre-validate the params?
+ if aaa_site.validateParams then
+ if not validateParams(r, account) then
+ return {}
+ end
end
+ return aaa_site.rights(r, account)
+ else
+ return {}
end
- return rights
end
-- module defs