Author: tmckay
Date: 2012-03-21 15:25:05 +0000 (Wed, 21 Mar 2012)
New Revision: 5259
Added:
branches/roles/cumin/metadata/access/
branches/roles/cumin/metadata/access/usergrid.xml
branches/roles/cumin/python/cumin/authorize.py
Modified:
branches/roles/cumin/bin/cumin-admin
branches/roles/cumin/bin/cumin-web
branches/roles/cumin/instance/etc/cumin.conf
branches/roles/cumin/python/cumin/config.py
branches/roles/cumin/python/cumin/main.py
branches/roles/cumin/python/cumin/widgets.py
branches/roles/wooly/python/wooly/__init__.py
Log:
Initial role enforcement sources.
Modified: branches/roles/cumin/bin/cumin-admin
===================================================================
--- branches/roles/cumin/bin/cumin-admin 2012-03-21 15:19:43 UTC (rev 5258)
+++ branches/roles/cumin/bin/cumin-admin 2012-03-21 15:25:05 UTC (rev 5259)
@@ -542,7 +542,7 @@
def handle_remove_assignment(app, cursor, opts, args):
user, role = get_user_and_role(app, cursor, args)
-
+ #TODO: check if user exists otherwise exc occures
assignment = app.admin.get_assignment(cursor, user, role)
if not assignment:
Modified: branches/roles/cumin/bin/cumin-web
===================================================================
--- branches/roles/cumin/bin/cumin-web 2012-03-21 15:19:43 UTC (rev 5258)
+++ branches/roles/cumin/bin/cumin-web 2012-03-21 15:25:05 UTC (rev 5259)
@@ -138,6 +138,9 @@
set_aviary_configs(cumin, values)
set_wallaby_configs(cumin, values, broker_uris)
+ cumin.auth_create_ondemand = values.auth_create_ondemand
+ cumin.auth_proxy = values.auth_proxy
+
cumin.debug = opts.debug
cumin.user = values.user
cumin.update_interval = values.update_interval
Modified: branches/roles/cumin/instance/etc/cumin.conf
===================================================================
--- branches/roles/cumin/instance/etc/cumin.conf 2012-03-21 15:19:43 UTC (rev 5258)
+++ branches/roles/cumin/instance/etc/cumin.conf 2012-03-21 15:25:05 UTC (rev 5259)
@@ -1,11 +1,17 @@
[common]
-# database: dbname=cumin user=cumin host=localhost
-# brokers: localhost:5672
-# debug: False
+database: dbname=cumin user=cumin host=localhost
+#database: dbname=cumin user=cumin host=172.22.88.13 port=5432 password=cumin
+#brokers: cumin/rasca@172.22.88.13:5672
+debug: True
[web]
# host: localhost
-# host: 0.0.0.0
-user: guest
+host: 0.0.0.0
+#user: guest
+authorize: usergrid.xml
+authz-mech:
+persona: default
+auth-proxy: true
+auth-create-ondemand: true
[data]
Added: branches/roles/cumin/metadata/access/usergrid.xml
===================================================================
--- branches/roles/cumin/metadata/access/usergrid.xml (rev 0)
+++ branches/roles/cumin/metadata/access/usergrid.xml 2012-03-21 15:25:05 UTC (rev 5259)
@@ -0,0 +1,34 @@
+<AccessMap>
+<GroupAccess name="nogroup">
+ <WidgetAccess reg="cumin.account.widgets.LoginForm"/>
+ <WidgetAccess reg="cumin.account.widgets.LoginPage"/>
+ <WidgetAccess reg="cumin.account.widgets.Submit"/>
+</GroupAccess>
+ <GroupAccess name="user">
+ <SubGroupAccess name="nogroup"/>
+ <WidgetAccess reg="cumin.usergrid.*" />
+ <WidgetAccess reg="cumin.account.*" />
+ <WidgetAccess reg="cumin.task.*" />
+ <WidgetAccess reg="cumin.widgets.CuminPageLinks"/>
+ <WidgetAccess reg="cumin.widgets.CuminHeartBeat"/>
+ <WidgetAccess reg="cumin.objectselector.*"/>
+ <WidgetAccess reg="cumin.widgets.About*" />
+ <WidgetAccess reg="cumin.widgets.CuminFormPage" />
+ <WidgetAccess reg="cumin.grid.submission.*" />
+</GroupAccess>
+ <GroupAccess name="admin">
+ <WidgetAccess reg=".*"/>
+ </GroupAccess>
+ <GroupAccess name="genericadmin">
+ <SubGroupAccess name="user"/>
+ <WidgetAccess reg="cumin.main.Main*"/>
+ <WidgetAccess reg="cumin.main.Overview*"/>
+ <WidgetAccess reg="cumin.main.Top*"/>
+ <WidgetAccess reg="cumin.widgets.Top*"/>
+ </GroupAccess>
+ <GroupAccess name="messagingadmin">
+ <SubGroupAccess name="user"/>
+ <WidgetAccess reg="cumin.main.Main*"/>
+ <WidgetAccess reg="cumin.main.MessagingView"/>
+ </GroupAccess>
+</AccessMap>
Added: branches/roles/cumin/python/cumin/authorize.py
===================================================================
--- branches/roles/cumin/python/cumin/authorize.py (rev 0)
+++ branches/roles/cumin/python/cumin/authorize.py 2012-03-21 15:25:05 UTC (rev 5259)
@@ -0,0 +1,93 @@
+#!/usr/bin/env python
+import logging
+import os.path
+import re
+
+try:
+ import xml.etree.ElementTree as etree
+except ImportError:
+ import elementtree.ElementTree as etree
+
+log = logging.getLogger("cumin.authorize")
+
+class CuminAuthorizeMap(object):
+
+ def __init__(self):
+ log.info("Initializing %s", self.__class__.__name__)
+ regs = []
+ self.mapping = {}
+ self.filepath = None
+
+ def __repr__(self):
+ return ("%s %s" % ( self.__class__.__name__, self.filepath ))
+
+ def parse_accessfile(self, filepath):
+ #TODO: handle exceptions during parsing
+ acctree = etree.ElementTree().parse(filepath)
+ merges = {}
+ for gacc in acctree.getiterator('GroupAccess'):
+ gkey = gacc.attrib["name"]
+ self.mapping[gkey] = []
+ log.debug("Adding group element %s" , gkey)
+ for child in gacc.getchildren():
+ if child.tag == "WidgetAccess":
+ wa = child.attrib['reg']
+ self.mapping[gkey].append(re.compile(wa))
+ log.debug("Addig widget access %s for %s", wa, gkey)
+ elif child.tag == "SubGroupAccess":
+ merges[gkey] = child.attrib["name"]
+ else:
+ log.error("Illegal access tag %s in tree", child.tag)
+ #TODO: handle adding properly
+ for k in merges.iterkeys():
+ self.mapping[k].extend(self.mapping[merges[k]])
+
+ def lookup(self,group,widget):
+ try:
+ for w in self.mapping[group]:
+ if w.match(widget):
+ return True
+ except KeyError:
+ return False
+ return False
+
+class CuminAuthorizator(object):
+ def __init__(self, app):
+ self.app = app
+ log.info("Initializing %s", self)
+ self.accmap = CuminAuthorizeMap()
+ modules = app.modules
+ #TODO: this should be configurable
+ access_path = app.home + "/metadata/access"
+ log.debug("Access file path is %s", access_path)
+ if os.path.isdir(access_path):
+ for accfile in os.listdir(access_path):
+ if os.path.isfile(access_path + "/" + accfile):
+ self.accmap.parse_accessfile(access_path + "/" + accfile)
+ else:
+ log.error("Path for access files does not exist!")
+ log.info("NODULES %s", modules)
+
+ def authorize(self,web_session, widget_name):
+ try:
+ group = web_session.client_session.attributes['login_session'].group
+ except KeyError:
+ group = "nogroup"
+ pass
+
+ #TODO: bleee ugly ugly ... -> CuminGenericWidget ? .
+ # skip wooly widgets ....
+ if widget_name.startswith("wooly"):
+ return True
+ if type(group) == type([]):
+ for g in group:
+ if self.accmap.lookup(g,widget_name):
+ log.debug("Allowing %s authorization for %s ",
+ widget_name, group)
+ return True
+ else:
+ return self.accmap.lookup(group,widget_name)
+
+ log.debug("Denying %s authorization for %s ", widget_name, group)
+ return False
+
Modified: branches/roles/cumin/python/cumin/config.py
===================================================================
--- branches/roles/cumin/python/cumin/config.py 2012-03-21 15:19:43 UTC (rev 5258)
+++ branches/roles/cumin/python/cumin/config.py 2012-03-21 15:25:05 UTC (rev 5259)
@@ -51,7 +51,7 @@
param = ConfigParameter(web, "persona", str)
param.default = "grid"
-
+
param = ConfigParameter(web, "fast-view-attributes", str)
param.default =
"JobStatus,Cmd,Args,ExitStatus,JobStartDate,LastRemoteHost,LastJobStatus,Owner"
@@ -64,6 +64,19 @@
param = ConfigParameter(web, "force-html-doctype", bool)
param.default = False
+ param = ConfigParameter(web, "authorize", str)
+ param.default = None
+
+ param = ConfigParameter(web, "authz-provider", str)
+ param.default = "internal"
+
+ param = ConfigParameter(web, "auth-create-ondemand", bool)
+ param.default = False
+
+ param = ConfigParameter(web, "auth-proxy", bool)
+ param.default = False
+
+
def create_data_section(self, name, strict_section):
data = CuminConfigSection(self, name, strict_section)
data.log_file.default = os.path.join(self.home, "log", name +
".log")
Modified: branches/roles/cumin/python/cumin/main.py
===================================================================
--- branches/roles/cumin/python/cumin/main.py 2012-03-21 15:19:43 UTC (rev 5258)
+++ branches/roles/cumin/python/cumin/main.py 2012-03-21 15:25:05 UTC (rev 5259)
@@ -21,6 +21,7 @@
from util import *
from widgets import *
from authenticator import *
+from authorize import *
from sage.catalog import Catalog
from sage.qmf.qmfoperations import QmfOperations
from sage.wallaby.wallabyoperations import WallabyOperations
@@ -39,6 +40,9 @@
self.home = home
self.authmech = authmech
+ self.aut_create_ondemand = False
+ self.aut_proxy = False
+
model_dir = os.path.join(self.home, "model")
self.model = CuminModel(self, model_dir)
@@ -56,6 +60,9 @@
self.modules = list()
self.modules_by_name = dict()
+ self.authorizator = CuminAuthorizator(self)
+ self.authorize_cb = self.authorizator.authorize
+
self.tasks = list()
self.user = None
@@ -78,6 +85,7 @@
self.personas["grid"] = self._init_grid_persona
self.personas["messaging"] = self._init_messaging_persona
self._page_links = list()
+ # we need the modules list to authorize
# self.model.sql_logging_enabled = True
@@ -168,6 +176,7 @@
def init(self, schema_version_check=True):
log.info("Initializing %s", self)
+
# Create RPC interfaces for QMF and aviary.
# These service have overlapping functionality,
# so they are wrapped in a sage.Catalog object
@@ -291,9 +300,8 @@
def __init__(self, app, name):
self.app = app
self.name = name
-
self.tasks = list()
-
+ log.debug("Init cumin module %s", name )
assert not hasattr(app, self.name), self.name
self.app.modules.append(self)
Modified: branches/roles/cumin/python/cumin/widgets.py
===================================================================
--- branches/roles/cumin/python/cumin/widgets.py 2012-03-21 15:19:43 UTC (rev 5258)
+++ branches/roles/cumin/python/cumin/widgets.py 2012-03-21 15:25:05 UTC (rev 5259)
@@ -51,7 +51,9 @@
super(CuminMainView, self).do_process(session, *args)
+
def show_child(self, session, child):
+
super(CuminMainView, self).show_child(session, child)
frame = self.page.get_frame(session)
@@ -81,7 +83,7 @@
return branch.marshal()
else:
return super(CuminMainView, self).render_tab_href(session, tab)
-
+
def render_about_href(self, session):
page = self.app.about_page
lsess = Session(page)
@@ -90,10 +92,10 @@
class CuminPageLinks(ItemSet):
def __init__(self, app, name):
super(CuminPageLinks, self).__init__(app, name)
-
+ self.app = app
self.html_class = CuminPageLinks.__name__
- self.check_admin = self.CheckAdmin(app)
+# self.check_admin = self.CheckAdmin(app)
def do_get_items(self, session):
return self.app.page_links
@@ -101,17 +103,18 @@
def render_item_content(self, session, page):
href = Session(page).marshal()
title = page.render_title(session)
+ #TODO: generalize ??
+ if self.app.authorize_cb(session,page.my_name):
+ return fmt_link(href, title)
- return fmt_link(href, title)
-
def render_item_class(self, session, page):
if page is session.page:
return "selected"
else:
return "_"
- class CheckAdmin(CuminSqlDataSet):
- pass
+# class CheckAdmin(CuminSqlDataSet):
+# pass
class CuminFrame(Frame, ModeSet):
def __init__(self, app, name):
@@ -156,7 +159,6 @@
def render_href(self, session, *args):
branch = session.branch()
-
if hasattr(self, "view"):
self.view.show(branch)
@@ -1179,6 +1181,36 @@
self.app = app
self.user = user
+ self.group = []
+ conn = self.app.database.get_connection()
+ cursor = conn.cursor()
+ user_cls = app.model.com_redhat_cumin.User
+ role_cls = app.model.com_redhat_cumin.Role
+ mapping_cls = app.model.com_redhat_cumin.UserRoleMapping
+
+ query = SqlQuery(role_cls.sql_table)
+
+ SqlInnerJoin(query,
+ mapping_cls.sql_table,
+ mapping_cls.role.sql_column,
+ role_cls._id.sql_column)
+
+ SqlInnerJoin(query,
+ user_cls.sql_table,
+ user_cls._id.sql_column,
+ mapping_cls.user.sql_column)
+ #TODO: one column ?
+ cols = [ role_cls.name.sql_column ]
+
+ filt = SqlComparisonFilter(user_cls._id.sql_column,user._id,'=')
+ query.add_filter(filt)
+ sql = query.emit(cols)
+ log.debug("%s",sql)
+ cursor.execute(sql)
+
+ for gname in cursor.fetchall():
+ self.group.append(gname[0])
+
self.created = datetime.now()
self.notifications = list()
@@ -1307,18 +1339,30 @@
if login.created > when:
return True
- elif self.app.user:
- cls = self.app.model.com_redhat_cumin.User
- users = cls.get_selection(session.cursor, name=self.app.user)
+ elif self.app.auth_proxy or self.app.user:
+ username = self.app.user
+ # proxy user overrides app defined user
+ try:
+ username = session.request_environment['HTTP_REMOTE_USER']
+ except KeyError:
+ log.debug("Proxy auth enabled but no remote user set")
+ pass
+ if username:
+ cls = self.app.model.com_redhat_cumin.User
+ users = cls.get_selection(session.cursor, name=username)
- if not users:
- raise Exception("User '%s' not found" % self.app.user)
+ if not users and not self.app.auth_proxy:
+ raise Exception("User '%s' not found" %
self.app.user)
+ else:
+ log.info("User %s not found in db", username )
+#TODO prehodit do authenticatora
+# ondemand -> authenticator.create_user
+# user -> authenticator.force_login
- login = LoginSession(self.app, users[0])
- session.client_session.attributes["login_session"] = login
+ login = LoginSession(self.app, users[0])
+ session.client_session.attributes["login_session"] = login
- return True
-
+ return True
return False
def redirect_on_exception(self, session):
@@ -1332,7 +1376,7 @@
session.add_notice(Notice("An object being displayed became
unavailable"))
return "/index.html"
-
+
def render_error(self, session):
cls, value, traceback = sys.exc_info()
Modified: branches/roles/wooly/python/wooly/__init__.py
===================================================================
--- branches/roles/wooly/python/wooly/__init__.py 2012-03-21 15:19:43 UTC (rev 5258)
+++ branches/roles/wooly/python/wooly/__init__.py 2012-03-21 15:25:05 UTC (rev 5259)
@@ -125,6 +125,8 @@
self.__defer_tmpl = WidgetTemplate(self, "deferred_html")
self.nocontent_tmpl = WidgetTemplate(self, "nocontent")
+ self.my_name = self.__class__.__module__ + '.' + self.__class__.__name__
+
def init(self):
log.debug("Initializing %s" % self)
@@ -286,6 +288,11 @@
child.save_parameters(session, params)
def process(self, session, *args):
+ #TODO: cleanup
+ log.debug("WOOLY PROCESS: %s", self.my_name)
+ if not self.app.authorize_cb(session, self.my_name):
+ return
+
if self.update_enabled:
self.page.enable_update(session, self)
@@ -305,6 +312,10 @@
child.process(session)
def render(self, session, *args):
+ #TODO: cleanup
+ log.debug("WOOLY RENDER: %s", self.my_name)
+ if not self.app.authorize_cb(session, self.my_name):
+ return ""
if self.app.debug:
profile = self.page.profile.get(session)