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