summaryrefslogtreecommitdiffstats
path: root/ipa-server/ipa-gui
diff options
context:
space:
mode:
authorrcritten <devnull@localhost>2007-09-10 16:33:01 -0400
committerrcritten <devnull@localhost>2007-09-10 16:33:01 -0400
commit182fbe30945a8de005f00b460968dca7973342fb (patch)
tree644f8efd633cbb41a387fb33e3deab8de20718b5 /ipa-server/ipa-gui
parent37d10e0c51dc289d815c05cd4d051e9d4120399e (diff)
downloadfreeipa-182fbe30945a8de005f00b460968dca7973342fb.tar.gz
freeipa-182fbe30945a8de005f00b460968dca7973342fb.tar.xz
freeipa-182fbe30945a8de005f00b460968dca7973342fb.zip
Enable mod_proxy to sit in front of TurboGears and pass along the
kerberos principal name Add an identity an visit class to TurboGears that can handle the user without requiring a database Update the UI to show the user correctly. Note that this is currently disabled. It is hardcoded to always return the principal test@FREEIPA.ORG in proxyprovider.py It doesn't handle an unauthorized request because that can never happen.
Diffstat (limited to 'ipa-server/ipa-gui')
-rw-r--r--ipa-server/ipa-gui/dev.cfg13
-rw-r--r--ipa-server/ipa-gui/ipa_gui.egg-info/SOURCES.txt7
-rw-r--r--ipa-server/ipa-gui/ipa_gui.egg-info/entry_points.txt6
-rw-r--r--ipa-server/ipa-gui/ipagui/controllers.py23
-rw-r--r--ipa-server/ipa-gui/ipagui/proxyprovider.py118
-rw-r--r--ipa-server/ipa-gui/ipagui/proxyvisit.py25
-rw-r--r--ipa-server/ipa-gui/ipagui/templates/master.kid19
-rw-r--r--ipa-server/ipa-gui/setup.py6
8 files changed, 205 insertions, 12 deletions
diff --git a/ipa-server/ipa-gui/dev.cfg b/ipa-server/ipa-gui/dev.cfg
index 7bb0fd8c4..7cc2441d0 100644
--- a/ipa-server/ipa-gui/dev.cfg
+++ b/ipa-server/ipa-gui/dev.cfg
@@ -13,8 +13,19 @@
# If you have sqlite, here's a simple default to get you started
# in development
-sqlobject.dburi="sqlite://%(current_dir_uri)s/devdata.sqlite"
+# sqlobject.dburi="sqlite://%(current_dir_uri)s/devdata.sqlite"
+# Our our sqlobject-derived proxy provider
+identity.provider='proxyprovider'
+
+# the first thing checked on any request. We want to short-circuit this
+# as early as possible
+identity.source = 'visit'
+
+# Turn on identity and visit (visit is required for identity)
+identity.on=True
+visit.on=True
+visit.manager='proxyvisit'
# if you are using a database or table type without transactions
# (MySQL default, for example), you should turn off transactions
diff --git a/ipa-server/ipa-gui/ipa_gui.egg-info/SOURCES.txt b/ipa-server/ipa-gui/ipa_gui.egg-info/SOURCES.txt
index 49b7ce44d..3bd848243 100644
--- a/ipa-server/ipa-gui/ipa_gui.egg-info/SOURCES.txt
+++ b/ipa-server/ipa-gui/ipa_gui.egg-info/SOURCES.txt
@@ -4,6 +4,7 @@ start-ipagui.py
ipa_gui.egg-info/PKG-INFO
ipa_gui.egg-info/SOURCES.txt
ipa_gui.egg-info/dependency_links.txt
+ipa_gui.egg-info/entry_points.txt
ipa_gui.egg-info/not-zip-safe
ipa_gui.egg-info/paster_plugins.txt
ipa_gui.egg-info/requires.txt
@@ -13,8 +14,14 @@ ipagui/__init__.py
ipagui/controllers.py
ipagui/json.py
ipagui/model.py
+ipagui/proxyprovider.py
+ipagui/proxyvisit.py
ipagui/release.py
ipagui/config/__init__.py
+ipagui/forms/__init__.py
+ipagui/forms/user.py
+ipagui/helpers/__init__.py
+ipagui/helpers/userhelper.py
ipagui/templates/__init__.py
ipagui/tests/__init__.py
ipagui/tests/test_controllers.py
diff --git a/ipa-server/ipa-gui/ipa_gui.egg-info/entry_points.txt b/ipa-server/ipa-gui/ipa_gui.egg-info/entry_points.txt
new file mode 100644
index 000000000..22c35bfdb
--- /dev/null
+++ b/ipa-server/ipa-gui/ipa_gui.egg-info/entry_points.txt
@@ -0,0 +1,6 @@
+
+ [turbogears.identity.provider]
+ proxyprovider = ipagui.proxyprovider:ProxyIdentityProvider
+
+ [turbogears.visit.manager]
+ proxyvisit = ipagui.proxyvisit:ProxyVisitManager
diff --git a/ipa-server/ipa-gui/ipagui/controllers.py b/ipa-server/ipa-gui/ipagui/controllers.py
index acbc48185..a07555257 100644
--- a/ipa-server/ipa-gui/ipagui/controllers.py
+++ b/ipa-server/ipa-gui/ipagui/controllers.py
@@ -8,6 +8,7 @@ from turbogears import controllers, expose, flash
from turbogears import validators, validate
from turbogears import widgets, paginate
from turbogears import error_handler
+from turbogears import identity
# from model import *
# import logging
# log = logging.getLogger("ipagui.controllers")
@@ -27,7 +28,6 @@ user_edit_form = forms.user.UserEditForm()
password_chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
client = ipa.ipaclient.IPAClient(True)
-client.set_principal("test@FREEIPA.ORG")
user_fields = ['*', 'nsAccountLock']
@@ -45,10 +45,12 @@ def utf8_encode(value):
class Root(controllers.RootController):
@expose(template="ipagui.templates.welcome")
+ @identity.require(identity.not_anonymous())
def index(self):
return dict()
@expose()
+ @identity.require(identity.not_anonymous())
def topsearch(self, **kw):
if kw.get('searchtype') == "Users":
return self.userlist(uid=kw.get('searchvalue'))
@@ -62,6 +64,7 @@ class Root(controllers.RootController):
########
@expose("ipagui.templates.usernew")
+ @identity.require(identity.not_anonymous())
def usernew(self, tg_errors=None):
"""Displays the new user form"""
if tg_errors:
@@ -70,9 +73,11 @@ class Root(controllers.RootController):
return dict(form=user_new_form)
@expose()
+ @identity.require(identity.not_anonymous())
def usercreate(self, **kw):
"""Creates a new user"""
restrict_post()
+ client.set_principal(identity.current.user_name)
if kw.get('submit') == 'Cancel':
turbogears.flash("Add user cancelled")
raise turbogears.redirect('/userlist')
@@ -104,11 +109,13 @@ class Root(controllers.RootController):
@expose("ipagui.templates.useredit")
+ @identity.require(identity.not_anonymous())
def useredit(self, uid, tg_errors=None):
"""Displays the edit user form"""
if tg_errors:
turbogears.flash("There was a problem with the form!")
+ client.set_principal(identity.current.user_name)
user = client.get_user_by_uid(uid, user_fields)
user_dict = user.toDict()
# Edit shouldn't fill in the password field.
@@ -121,9 +128,11 @@ class Root(controllers.RootController):
return dict(form=user_edit_form, user=user_dict)
@expose()
+ @identity.require(identity.not_anonymous())
def userupdate(self, **kw):
"""Updates an existing user"""
restrict_post()
+ client.set_principal(identity.current.user_name)
if kw.get('submit') == 'Cancel Edit':
turbogears.flash("Edit user cancelled")
raise turbogears.redirect('/usershow', uid=kw.get('uid'))
@@ -169,8 +178,10 @@ class Root(controllers.RootController):
@expose("ipagui.templates.userlist")
+ @identity.require(identity.not_anonymous())
def userlist(self, **kw):
"""Retrieve a list of all users and display them in one huge list"""
+ client.set_principal(identity.current.user_name)
users = None
counter = 0
uid = kw.get('uid')
@@ -190,8 +201,10 @@ class Root(controllers.RootController):
@expose("ipagui.templates.usershow")
+ @identity.require(identity.not_anonymous())
def usershow(self, uid):
"""Retrieve a single user for display"""
+ client.set_principal(identity.current.user_name)
try:
user = client.get_user_by_uid(uid, user_fields)
return dict(user=user.toDict(), fields=forms.user.UserFields())
@@ -200,10 +213,12 @@ class Root(controllers.RootController):
raise turbogears.redirect("/")
@validate(form=user_new_form)
+ @identity.require(identity.not_anonymous())
def usercreatevalidate(self, tg_errors=None, **kw):
return tg_errors, kw
@validate(form=user_edit_form)
+ @identity.require(identity.not_anonymous())
def userupdatevalidate(self, tg_errors=None, **kw):
return tg_errors, kw
@@ -222,10 +237,12 @@ class Root(controllers.RootController):
return password
@expose()
+ @identity.require(identity.not_anonymous())
def suggest_uid(self, givenname, sn):
if (len(givenname) == 0) or (len(sn) == 0):
return ""
+ client.set_principal(identity.current.user_name)
givenname = givenname.lower()
sn = sn.lower()
@@ -309,7 +326,9 @@ class Root(controllers.RootController):
#########
@expose("ipagui.templates.groupindex")
+ @identity.require(identity.not_anonymous())
def groupindex(self, tg_errors=None):
+ client.set_principal(identity.current.user_name)
return dict()
@@ -318,5 +337,7 @@ class Root(controllers.RootController):
############
@expose("ipagui.templates.resindex")
+ @identity.require(identity.not_anonymous())
def resindex(self, tg_errors=None):
+ client.set_principal(identity.current.user_name)
return dict()
diff --git a/ipa-server/ipa-gui/ipagui/proxyprovider.py b/ipa-server/ipa-gui/ipagui/proxyprovider.py
new file mode 100644
index 000000000..125198806
--- /dev/null
+++ b/ipa-server/ipa-gui/ipagui/proxyprovider.py
@@ -0,0 +1,118 @@
+from turbogears.identity.soprovider import *
+from turbogears.identity.visitor import *
+import logging
+
+log = logging.getLogger("turbogears.identity")
+
+class IPA_User(object):
+ '''
+ Shell of a User definition. We don't really need much here.
+ '''
+
+ def __init__(self, user_name):
+ self.user_name = user_name
+ self.display_name = user_name
+ self.permissions = None
+ self.groups = None
+ return
+
+class ProxyIdentity(object):
+ def __init__(self, visit_key, user=None):
+ if user:
+ self._user= user
+ self.visit_key= visit_key
+
+ def _get_user(self):
+ try:
+ return self._user
+ except AttributeError:
+ # User hasn't already been set
+ return None
+ user= property(_get_user)
+
+ def _get_user_name(self):
+ if not self.user:
+ return None
+ return self.user.user_name
+ user_name= property(_get_user_name)
+
+ def _get_name(self):
+ if not self.user:
+ return None
+ return self.user.name
+ user_name= property(_get_name)
+
+ def _get_anonymous(self):
+ return not self.user
+ anonymous= property(_get_anonymous)
+
+ def _get_permissions(self):
+ try:
+ return self._permissions
+ except AttributeError:
+ # Permissions haven't been computed yet
+ return None
+ permissions= property(_get_permissions)
+
+ def _get_groups(self):
+ try:
+ return self._groups
+ except AttributeError:
+ # Groups haven't been computed yet
+ return None
+ groups= property(_get_groups)
+
+ def logout(self):
+ '''
+ Remove the link between this identity and the visit.
+ '''
+ # Clear the current identity
+ anon= ProxyObjectIdentity(None,None)
+ #XXX if user is None anonymous will be true, no need to set attr.
+ #anon.anonymous= True
+ identity.set_current_identity( anon )
+
+class ProxyIdentityProvider(SqlObjectIdentityProvider):
+ '''
+ IdentityProvider that uses REMOTE_USER from Apache
+ '''
+ def __init__(self):
+ super(ProxyIdentityProvider, self).__init__()
+ get = turbogears.config.get
+ # We can get any config variables here
+ log.info( "Proxy Identity starting" )
+
+ def create_provider_model(self):
+ pass
+
+ def validate_identity(self, user_name, password, visit_key):
+ user = IPA_User(user_name)
+ log.debug( "validate_identity %s" % user_name)
+
+ return ProxyIdentity(visit_key, user)
+
+ def validate_password(self, user, user_name, password):
+ '''Validation has already occurred in the proxy'''
+ return True
+
+ def load_identity(self, visit_key):
+ try:
+# user_name= cherrypy.request.headers['X-FORWARDED-USER']
+ user_name= "test@FREEIPA.ORG"
+ except KeyError:
+ return None
+ set_login_attempted( True )
+ return self.validate_identity( user_name, None, visit_key )
+
+ def anonymous_identity( self ):
+ '''
+ This shouldn't ever happen in IPA but including it to include the
+ entire identity API.
+ '''
+ return ProxyIdentity( None )
+
+ def authenticated_identity(self, user):
+ '''
+ Constructs Identity object for user that has no associated visit_key.
+ '''
+ return ProxyIdentity(None, user)
diff --git a/ipa-server/ipa-gui/ipagui/proxyvisit.py b/ipa-server/ipa-gui/ipagui/proxyvisit.py
new file mode 100644
index 000000000..1fde3902e
--- /dev/null
+++ b/ipa-server/ipa-gui/ipagui/proxyvisit.py
@@ -0,0 +1,25 @@
+from turbogears.visit.api import BaseVisitManager, Visit
+from turbogears import config
+
+import logging
+
+log = logging.getLogger("turbogears.visit.proxyvisit")
+
+class ProxyVisitManager(BaseVisitManager):
+ """Virtually empty class just so can avoid saving this stuff in a
+ database."""
+ def __init__(self, timeout):
+ super(ProxyVisitManager,self).__init__(timeout)
+ return
+
+ def create_model(self):
+ return
+
+ def new_visit_with_key(self, visit_key):
+ return Visit(visit_key, True)
+
+ def visit_for_key(self, visit_key):
+ return Visit(visit_key, False)
+
+ def update_queued_visits(self, queue):
+ return None
diff --git a/ipa-server/ipa-gui/ipagui/templates/master.kid b/ipa-server/ipa-gui/ipagui/templates/master.kid
index 8abe24bac..2d3a35f22 100644
--- a/ipa-server/ipa-gui/ipagui/templates/master.kid
+++ b/ipa-server/ipa-gui/ipagui/templates/master.kid
@@ -14,15 +14,6 @@
</head>
<body py:match="item.tag=='{http://www.w3.org/1999/xhtml}body'" py:attrs="item.items()">
- <div py:if="tg.config('identity.on') and not defined('logging_in')" id="pageLogin">
- <span py:if="tg.identity.anonymous">
- <a href="${tg.url('/login')}">Login</a>
- </span>
- <span py:if="not tg.identity.anonymous">
- Welcome ${tg.identity.user.display_name}.
- <a href="${tg.url('/logout')}">Logout</a>
- </span>
- </div>
<div id="header">
<div id="logo">
@@ -33,7 +24,15 @@
</div>
<div id="headerinfo">
<div id="login">
- Logged in as: ace
+ <div py:if="tg.config('identity.on') and not defined('logging_in')" id="pageLogin">
+ <span py:if="tg.identity.anonymous">
+ <a href="${tg.url('/login')}">Login</a>
+ </span>
+ <span py:if="not tg.identity.anonymous">
+ Logged in as: ${tg.identity.user.display_name}
+ </span>
+ </div>
+
</div>
<div id="topsearch">
<form action="${tg.url('/topsearch')}" method="post">
diff --git a/ipa-server/ipa-gui/setup.py b/ipa-server/ipa-gui/setup.py
index 371325f6a..123817999 100644
--- a/ipa-server/ipa-gui/setup.py
+++ b/ipa-server/ipa-gui/setup.py
@@ -58,5 +58,11 @@ setup(
# 'Framework :: TurboGears :: Widgets',
],
test_suite = 'nose.collector',
+ entry_points = """
+ [turbogears.identity.provider]
+ proxyprovider = ipagui.proxyprovider:ProxyIdentityProvider
+ [turbogears.visit.manager]
+ proxyvisit = ipagui.proxyvisit:ProxyVisitManager
+ """,
)