diff options
author | kmccarth@dhcp-172-16-25-136.sfbay.redhat.com <kmccarth@dhcp-172-16-25-136.sfbay.redhat.com> | 2007-08-12 04:53:18 -0700 |
---|---|---|
committer | kmccarth@dhcp-172-16-25-136.sfbay.redhat.com <kmccarth@dhcp-172-16-25-136.sfbay.redhat.com> | 2007-08-12 04:53:18 -0700 |
commit | 728e44833cebeb75f8a0035af7d4dd1b2924b75d (patch) | |
tree | 299d47464b1a617c8d0800f7ed10e2e098b9edf7 /ipa-server/ipa-gui | |
parent | a3e786e22ec9d4b0e7d2ef982ac045a29477433e (diff) | |
download | freeipa-728e44833cebeb75f8a0035af7d4dd1b2924b75d.tar.gz freeipa-728e44833cebeb75f8a0035af7d4dd1b2924b75d.tar.xz freeipa-728e44833cebeb75f8a0035af7d4dd1b2924b75d.zip |
Addiing initial turbogears web gui.
Contains simple user add, list, and view pages.
Diffstat (limited to 'ipa-server/ipa-gui')
37 files changed, 1344 insertions, 0 deletions
diff --git a/ipa-server/ipa-gui/README.txt b/ipa-server/ipa-gui/README.txt new file mode 100644 index 000000000..876b880b1 --- /dev/null +++ b/ipa-server/ipa-gui/README.txt @@ -0,0 +1,4 @@ +ipa-gui + +This is a TurboGears (http://www.turbogears.org) project. It can be +started by running the start-ipagui.py script.
\ No newline at end of file diff --git a/ipa-server/ipa-gui/dev.cfg b/ipa-server/ipa-gui/dev.cfg new file mode 100644 index 000000000..7bb0fd8c4 --- /dev/null +++ b/ipa-server/ipa-gui/dev.cfg @@ -0,0 +1,66 @@ +[global] +# This is where all of your settings go for your development environment +# Settings that are the same for both development and production +# (such as template engine, encodings, etc.) all go in +# ipagui/config/app.cfg + +# DATABASE + +# pick the form for your database +# sqlobject.dburi="postgres://username@hostname/databasename" +# sqlobject.dburi="mysql://username:password@hostname:port/databasename" +# sqlobject.dburi="sqlite:///file_name_and_path" + +# If you have sqlite, here's a simple default to get you started +# in development +sqlobject.dburi="sqlite://%(current_dir_uri)s/devdata.sqlite" + + +# if you are using a database or table type without transactions +# (MySQL default, for example), you should turn off transactions +# by prepending notrans_ on the uri +# sqlobject.dburi="notrans_mysql://username:password@hostname:port/databasename" + +# for Windows users, sqlite URIs look like: +# sqlobject.dburi="sqlite:///drive_letter:/path/to/file" + +# SERVER + +# Some server parameters that you may want to tweak +# server.socket_port=8080 + +# Enable the debug output at the end on pages. +# log_debug_info_filter.on = False + +server.environment="development" +autoreload.package="ipagui" + +# Auto-Reload after code modification +# autoreload.on = True + +# Set to True if you'd like to abort execution if a controller gets an +# unexpected parameter. False by default +tg.strict_parameters = True + +# LOGGING +# Logging configuration generally follows the style of the standard +# Python logging module configuration. Note that when specifying +# log format messages, you need to use *() for formatting variables. +# Deployment independent log configuration is in ipagui/config/log.cfg +[logging] + +[[loggers]] +[[[ipagui]]] +level='DEBUG' +qualname='ipagui' +handlers=['debug_out'] + +[[[allinfo]]] +level='INFO' +handlers=['debug_out'] + +[[[access]]] +level='INFO' +qualname='turbogears.access' +handlers=['access_out'] +propagate=0 diff --git a/ipa-server/ipa-gui/ipa_gui.egg-info/PKG-INFO b/ipa-server/ipa-gui/ipa_gui.egg-info/PKG-INFO new file mode 100644 index 000000000..544ba9f98 --- /dev/null +++ b/ipa-server/ipa-gui/ipa_gui.egg-info/PKG-INFO @@ -0,0 +1,15 @@ +Metadata-Version: 1.0 +Name: ipa-gui +Version: 1.0 +Summary: UNKNOWN +Home-page: UNKNOWN +Author: UNKNOWN +Author-email: UNKNOWN +License: UNKNOWN +Description: UNKNOWN +Platform: UNKNOWN +Classifier: Development Status :: 3 - Alpha +Classifier: Operating System :: OS Independent +Classifier: Programming Language :: Python +Classifier: Topic :: Software Development :: Libraries :: Python Modules +Classifier: Framework :: TurboGears diff --git a/ipa-server/ipa-gui/ipa_gui.egg-info/SOURCES.txt b/ipa-server/ipa-gui/ipa_gui.egg-info/SOURCES.txt new file mode 100644 index 000000000..49b7ce44d --- /dev/null +++ b/ipa-server/ipa-gui/ipa_gui.egg-info/SOURCES.txt @@ -0,0 +1,21 @@ +README.txt +setup.py +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/not-zip-safe +ipa_gui.egg-info/paster_plugins.txt +ipa_gui.egg-info/requires.txt +ipa_gui.egg-info/sqlobject.txt +ipa_gui.egg-info/top_level.txt +ipagui/__init__.py +ipagui/controllers.py +ipagui/json.py +ipagui/model.py +ipagui/release.py +ipagui/config/__init__.py +ipagui/templates/__init__.py +ipagui/tests/__init__.py +ipagui/tests/test_controllers.py +ipagui/tests/test_model.py diff --git a/ipa-server/ipa-gui/ipa_gui.egg-info/dependency_links.txt b/ipa-server/ipa-gui/ipa_gui.egg-info/dependency_links.txt new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/ipa-server/ipa-gui/ipa_gui.egg-info/dependency_links.txt @@ -0,0 +1 @@ + diff --git a/ipa-server/ipa-gui/ipa_gui.egg-info/not-zip-safe b/ipa-server/ipa-gui/ipa_gui.egg-info/not-zip-safe new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/ipa-server/ipa-gui/ipa_gui.egg-info/not-zip-safe @@ -0,0 +1 @@ + diff --git a/ipa-server/ipa-gui/ipa_gui.egg-info/paster_plugins.txt b/ipa-server/ipa-gui/ipa_gui.egg-info/paster_plugins.txt new file mode 100644 index 000000000..14fec70ae --- /dev/null +++ b/ipa-server/ipa-gui/ipa_gui.egg-info/paster_plugins.txt @@ -0,0 +1,2 @@ +TurboGears +PasteScript diff --git a/ipa-server/ipa-gui/ipa_gui.egg-info/requires.txt b/ipa-server/ipa-gui/ipa_gui.egg-info/requires.txt new file mode 100644 index 000000000..aecc30960 --- /dev/null +++ b/ipa-server/ipa-gui/ipa_gui.egg-info/requires.txt @@ -0,0 +1 @@ +TurboGears >= 1.0.2.2
\ No newline at end of file diff --git a/ipa-server/ipa-gui/ipa_gui.egg-info/sqlobject.txt b/ipa-server/ipa-gui/ipa_gui.egg-info/sqlobject.txt new file mode 100644 index 000000000..cc84b8d00 --- /dev/null +++ b/ipa-server/ipa-gui/ipa_gui.egg-info/sqlobject.txt @@ -0,0 +1,2 @@ +db_module=ipagui.model +history_dir=$base/ipagui/sqlobject-history diff --git a/ipa-server/ipa-gui/ipa_gui.egg-info/top_level.txt b/ipa-server/ipa-gui/ipa_gui.egg-info/top_level.txt new file mode 100644 index 000000000..2ba21519d --- /dev/null +++ b/ipa-server/ipa-gui/ipa_gui.egg-info/top_level.txt @@ -0,0 +1 @@ +ipagui diff --git a/ipa-server/ipa-gui/ipagui/config/app.cfg b/ipa-server/ipa-gui/ipagui/config/app.cfg new file mode 100644 index 000000000..38d896f27 --- /dev/null +++ b/ipa-server/ipa-gui/ipagui/config/app.cfg @@ -0,0 +1,51 @@ +[global] +# The settings in this file should not vary depending on the deployment +# environment. dev.cfg and prod.cfg are the locations for +# the different deployment settings. Settings in this file will +# be overridden by settings in those other files. + +# The commented out values below are the defaults + +# VIEW + +# which view (template engine) to use if one is not specified in the +# template name +# tg.defaultview = "kid" + +# The following kid settings determine the settings used by the kid serializer. + +# One of (html|html-strict|xhtml|xhtml-strict|xml|json) +# kid.outputformat="html" + +# kid.encoding="utf-8" + +# The sitetemplate is used for overall styling of a site that +# includes multiple TurboGears applications +# tg.sitetemplate="<packagename.templates.templatename>" + +# Allow every exposed function to be called as json, +# tg.allow_json = False + +# List of Widgets to include on every page. +# for exemple ['turbogears.mochikit'] +# tg.include_widgets = [] + +# Set to True if the scheduler should be started +# tg.scheduler = False + +# Set session or cookie +# session_filter.on = True + + +# compress the data sends to the web browser +# [/] +# gzip_filter.on = True +# gzip_filter.mime_types = ["application/x-javascript", "text/javascript", "text/html", "text/css", "text/plain"] + +[/static] +static_filter.on = True +static_filter.dir = "%(top_level_dir)s/static" + +[/favicon.ico] +static_filter.on = True +static_filter.file = "%(top_level_dir)s/static/images/favicon.ico" diff --git a/ipa-server/ipa-gui/ipagui/config/log.cfg b/ipa-server/ipa-gui/ipagui/config/log.cfg new file mode 100644 index 000000000..ce776f850 --- /dev/null +++ b/ipa-server/ipa-gui/ipagui/config/log.cfg @@ -0,0 +1,29 @@ +# LOGGING +# Logging is often deployment specific, but some handlers and +# formatters can be defined here. + +[logging] +[[formatters]] +[[[message_only]]] +format='*(message)s' + +[[[full_content]]] +format='*(asctime)s *(name)s *(levelname)s *(message)s' + +[[handlers]] +[[[debug_out]]] +class='StreamHandler' +level='DEBUG' +args='(sys.stdout,)' +formatter='full_content' + +[[[access_out]]] +class='StreamHandler' +level='INFO' +args='(sys.stdout,)' +formatter='message_only' + +[[[error_out]]] +class='StreamHandler' +level='ERROR' +args='(sys.stdout,)' diff --git a/ipa-server/ipa-gui/ipagui/controllers.py b/ipa-server/ipa-gui/ipagui/controllers.py new file mode 100644 index 000000000..361a5cbdf --- /dev/null +++ b/ipa-server/ipa-gui/ipagui/controllers.py @@ -0,0 +1,168 @@ +import cherrypy +import turbogears +from turbogears import controllers, expose, flash +from turbogears import validators, validate +from turbogears import widgets, paginate +from turbogears import error_handler +# from model import * +# import logging +# log = logging.getLogger("ipagui.controllers") +# import ipa.rpcclient +import ipa.config +import ipa.ipaclient +import ipa.user +import xmlrpclib +import forms.user + +ipa.config.init_config() +user_form = forms.user.UserFormWidget() + +client = ipa.ipaclient.IPAClient(True) +client.set_principal("test@FREEIPA.ORG") + +def restrict_post(): + if cherrypy.request.method != "POST": + turbogears.flash("This method only accepts posts") + raise turbogears.redirect("/") + +def user_to_hash(user): + return { + 'uid' : user.getValue('uid'), + 'givenName' : user.getValue('givenName'), + 'sn' : user.getValue('sn'), + 'mail' : user.getValue('mail'), + 'telephoneNumber': user.getValue('telephoneNumber'), + 'uidNumber': user.getValue('uidNumber'), + 'gidNumber': user.getValue('gidNumber'), + } + +class Root(controllers.RootController): + + @expose(template="ipagui.templates.welcome") + def index(self): + return dict() + + + ######## + # User # + ######## + + @expose("ipagui.templates.usernew") + def usernew(self, tg_errors=None): + """Displays the new user form""" + if tg_errors: + turbogears.flash("There was a problem with the form!") + + return dict(form=user_form) + + @expose() + def usercreate(self, **kw): + """Creates a new user""" + restrict_post() + if kw.get('submit') == 'Cancel': + turbogears.flash("Add user cancelled") + raise turbogears.redirect('/userlist') + + tg_errors, kw = self.uservalidate(**kw) + if tg_errors: + return dict(form=user_form, tg_template='ipagui.templates.usernew') + + try: + # rv = ipa.rpcclient.add_user(kw) + newuser = ipa.user.User(None) + newuser.setValue('uid', kw['uid']) + newuser.setValue('givenName', kw['givenName']) + newuser.setValue('sn', kw['sn']) + newuser.setValue('mail', kw['mail']) + newuser.setValue('telephoneNumber', kw['telephoneNumber']) + newuser2 = { + 'uid' : kw['uid'], + 'givenName' : kw['givenName'], + 'sn' : kw['sn'], + 'mail' : kw['mail'], + 'telephoneNumber': kw['telephoneNumber'] + } + rv = client.add_user(newuser2) + turbogears.flash("%s added!" % kw['uid']) + raise turbogears.redirect('/usershow', uid=kw['uid']) + except xmlrpclib.Fault, f: + turbogears.flash("User add failed: " + str(f.faultString)) + return dict(form=user_form, tg_template='ipagui.templates.usernew') + + + @expose("ipagui.templates.useredit") + def useredit(self, uid, tg_errors=None): + """Displays the edit user form""" + if tg_errors: + turbogears.flash("There was a problem with the form!") + + # user = ipa.rpcclient.get_user(uid) + user = client.get_user(uid) + return dict(form=user_form, user=user_to_hash(user)) + + @expose() + def userupdate(self, **kw): + """Updates an existing user""" + restrict_post() + if kw.get('submit') == 'Cancel': + turbogears.flash("Edit user cancelled") + raise turbogears.redirect('/usershow', uid=kw.get('uid')) + + tg_errors, kw = self.uservalidate(**kw) + if tg_errors: + return dict(form=user_form, user={}, tg_template='ipagui.templates.useredit') + + try: + # rv = ipa.rpcclient.add_user(kw) + turbogears.flash("%s updated!" % kw['uid']) + raise turbogears.redirect('/usershow', uid=kw['uid']) + except xmlrpclib.Fault, f: + turbogears.flash("User add failed: " + str(f.faultString)) + return dict(form=user_form, user={}, tg_template='ipagui.templates.useredit') + + + @expose("ipagui.templates.userlist") + @paginate('users', limit=3, allow_limit_override=True) + def userlist(self): + """Retrieve a list of all users and display them in one huge list""" + # users = ipa.rpcclient.get_all_users() + users = client.get_all_users() + return dict(users=users) + + + @expose("ipagui.templates.usershow") + def usershow(self, uid): + """Retrieve a single user for display""" + try: + # user = ipa.rpcclient.get_user(uid) + user = client.get_user(uid) + return dict(user=user_to_hash(user)) + except xmlrpclib.Fault, f: + turbogears.flash("User show failed: " + str(f.faultString)) + raise turbogears.redirect("/") + + @validate(form=user_form) + def uservalidate(self, tg_errors=None, **kw): + return tg_errors, kw + + @expose() + def userindex(self): + raise turbogears.redirect("/userlist") + + + ######### + # Group # + ######### + + @expose("ipagui.templates.groupindex") + def groupindex(self, tg_errors=None): + return dict() + + + ############ + # Resource # + ############ + + @expose("ipagui.templates.resindex") + def resindex(self, tg_errors=None): + return dict() diff --git a/ipa-server/ipa-gui/ipagui/forms/user.py b/ipa-server/ipa-gui/ipagui/forms/user.py new file mode 100644 index 000000000..3cb4aed49 --- /dev/null +++ b/ipa-server/ipa-gui/ipagui/forms/user.py @@ -0,0 +1,67 @@ +import turbogears +from turbogears import validators, widgets + +class UserFields(): + uid = widgets.TextField(name="uid", label="Login:") + userPassword = widgets.TextField(name="userPassword", label="Password:") + uidNumber = widgets.TextField(name="uidNumber", label="UID:") + gidNumber = widgets.TextField(name="gidNumber", label="GID:") + givenName = widgets.TextField(name="givenName", label="First name:") + sn = widgets.TextField(name="sn", label="Last name:") + mail = widgets.TextField(name="mail", label="E-mail address:") + telephoneNumber = widgets.TextField(name="telephoneNumber", label="Phone:") + + uid.validator = validators.PlainText(not_empty=True) + userPassword.validator = validators.String(not_empty=True) + givenName.validator = validators.String(not_empty=True) + sn.validator = validators.String(not_empty=True) + mail.validator = validators.Email(not_empty=True) + # validators.PhoneNumber may be a bit too picky, requiring an area code + telephoneNumber.validator = validators.PlainText(not_empty=True) + + +class UserFormWidget(widgets.Form): + params = ['user'] +# fields = [UserFields.uid, UserFields.userPassword, UserFields.givenName, +# UserFields.sn, UserFields.mail] + fields = [UserFields.uid, UserFields.givenName, + UserFields.uidNumber, UserFields.gidNumber, + UserFields.sn, UserFields.mail] + + def __init__(self, *args, **kw): + super(UserFormWidget,self).__init__(*args, **kw) + (self.template_c, self.template) = widgets.meta.load_kid_template("ipagui.templates.userform") + self.user = UserFields + + def update_params(self, params): + super(UserFormWidget,self).update_params(params) + params['has_foo'] = self.has_foo + + def has_foo(self): + return False + +# TODO - add dynamic field retrieval: +# myfields=[] +# schema = ipa.rpcclient.get_add_schema () +# +# # FIXME: What if schema is None or an error is thrown? +# +# for s in schema: +# required=False +# +# if (s['type'] == "text"): +# field = widgets.TextField(name=s['name'],label=s['label']) +# elif (s['type'] == "password"): +# field = widgets.PasswordField(name=s['name'],label=s['label']) +# +# if (s['required'] == "true"): +# required=True +# +# if (s['validator'] == "text"): +# field.validator=validators.PlainText(not_empty=required) +# elif (s['validator'] == "email"): +# field.validator=validators.Email(not_empty=required) +# elif (s['validator'] == "string"): +# field.validator=validators.String(not_empty=required) +# +# myfields.append(field) diff --git a/ipa-server/ipa-gui/ipagui/json.py b/ipa-server/ipa-gui/ipagui/json.py new file mode 100644 index 000000000..66d5cfb65 --- /dev/null +++ b/ipa-server/ipa-gui/ipagui/json.py @@ -0,0 +1,10 @@ +# A JSON-based API(view) for your app. +# Most rules would look like: +# @jsonify.when("isinstance(obj, YourClass)") +# def jsonify_yourclass(obj): +# return [obj.val1, obj.val2] +# @jsonify can convert your objects to following types: +# lists, dicts, numbers and strings + +from turbojson.jsonify import jsonify + diff --git a/ipa-server/ipa-gui/ipagui/model.py b/ipa-server/ipa-gui/ipagui/model.py new file mode 100644 index 000000000..244cfff70 --- /dev/null +++ b/ipa-server/ipa-gui/ipagui/model.py @@ -0,0 +1,9 @@ +from turbogears.database import PackageHub +from sqlobject import * + +hub = PackageHub('ipagui') +__connection__ = hub + +# class YourDataClass(SQLObject): +# pass + diff --git a/ipa-server/ipa-gui/ipagui/release.py b/ipa-server/ipa-gui/ipagui/release.py new file mode 100644 index 000000000..7be40c007 --- /dev/null +++ b/ipa-server/ipa-gui/ipagui/release.py @@ -0,0 +1,14 @@ +# Release information about ipa-gui + +version = "1.0" + +# description = "Your plan to rule the world" +# long_description = "More description about your plan" +# author = "Your Name Here" +# email = "YourEmail@YourDomain" +# copyright = "Vintage 2006 - a good year indeed" + +# if it's open source, you might want to specify these +# url = "http://yourcool.site/" +# download_url = "http://yourcool.site/download" +# license = "MIT" diff --git a/ipa-server/ipa-gui/ipagui/static/css/style.css b/ipa-server/ipa-gui/ipagui/static/css/style.css new file mode 100644 index 000000000..e4a1d9f8c --- /dev/null +++ b/ipa-server/ipa-gui/ipagui/static/css/style.css @@ -0,0 +1,146 @@ +/*
+ * Quick mash-up of CSS for the TG quick start page.
+ */
+
+html, body {
+ color: #000;
+ background:#fff;
+ margin: 0;
+ padding: 0;
+}
+
+body {
+ min-width: 750px;
+}
+
+#page {
+ background:#ccc; /* should be same as #sidebar */
+ margin:0 auto;
+ width:100%;
+}
+
+
+#header {
+ background:#fff;
+}
+
+#header h1 {
+ padding:5px;
+ margin:0;
+}
+
+
+#nav {
+ background:#cc0000;
+ color:#fff;
+ padding:5px;
+}
+
+#nav ul {
+ margin:0;
+ padding:0;
+ list-style:none;
+}
+
+#nav li {
+ display:inline;
+}
+
+#nav a:visited {
+ color:#fff;
+}
+#nav a:link {
+ color:#fff;
+}
+
+
+#main_content {
+ background:#fff;
+ float:right;
+ width:85%;
+ border-left: 1px solid #000;
+ padding-left: 15px;
+ padding-bottom: 15px;
+/* color: black;
+ font-size: 127%;
+ background-color: white;
+ margin: 0 auto 0 auto;
+ padding: 10px;
+ float: left; */
+}
+
+
+#sidebar {
+ background:#ccc; /* should be same as #page */
+ float:left;
+ width:10%;
+ /* border: 1px solid #aaa;
+ background-color: #eee;
+ margin: 0.5em;
+ padding: 1em;
+ float: left;
+ font-size: 88%; */
+}
+
+#sidebar h2 {
+ margin-top: 0;
+}
+
+#sidebar ul {
+ margin-left: 1.5em;
+ padding-left: 0;
+}
+
+
+#footer {
+ background:#fff;
+ clear:both;
+ border-top: 1px solid #000;
+ /* color: #999;
+ background-color: white;
+ padding: 10px;
+ font-size: 80%;
+ text-align: center;
+ margin: 0 auto 1em auto; */
+}
+
+
+.formsection {
+ color: #888888;
+ width: 90%;
+ font-weight: bold;
+ border-bottom: 1px solid;
+ margin: 20px 0px 20px 0px;
+}
+
+.formtable {
+ width: 90%;
+}
+
+.formtable th {
+ width: 15%;
+ text-align: right;
+}
+
+#status_block {
+ margin: 0 auto 0.5em auto;
+ padding: 15px 10px 15px 55px;
+ background: #cec URL('../images/ok.png') left center no-repeat;
+ border: 1px solid #9c9;
+ width: 450px;
+ font-size: 120%;
+ font-weight: bolder;
+}
+
+.notice {
+ margin: 0.5em auto 0.5em auto;
+ padding: 15px 10px 15px 55px;
+ width: 450px;
+ background: #eef URL('../images/info.png') left center no-repeat;
+ border: 1px solid #cce;
+}
+
+.fielderror {
+ color: red;
+ font-weight: bold;
+}
diff --git a/ipa-server/ipa-gui/ipagui/templates/groupindex.kid b/ipa-server/ipa-gui/ipagui/templates/groupindex.kid new file mode 100644 index 000000000..0bb70ac9a --- /dev/null +++ b/ipa-server/ipa-gui/ipagui/templates/groupindex.kid @@ -0,0 +1,18 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml" xmlns:py="http://purl.org/kid/ns#" + py:extends="'grouplayout.kid'"> +<head> +<meta content="text/html; charset=utf-8" http-equiv="Content-Type" py:replace="''"/> +<title>Group Listing</title> +</head> +<body> + Groups go here. + <br /> + <br /> + <br /> + <br /> + <br /> + <br /> + <br /> +</body> +</html> diff --git a/ipa-server/ipa-gui/ipagui/templates/grouplayout.kid b/ipa-server/ipa-gui/ipagui/templates/grouplayout.kid new file mode 100644 index 000000000..53b6ce0a7 --- /dev/null +++ b/ipa-server/ipa-gui/ipagui/templates/grouplayout.kid @@ -0,0 +1,22 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xmlns:py="http://purl.org/kid/ns#"
+ py:extends="'master.kid'">
+<head>
+</head>
+
+<body py:match="item.tag=='{http://www.w3.org/1999/xhtml}body'" py:attrs="item.items()">
+ <div id="main_content">
+ <div id="status_block" class="flash" py:if="value_of('tg_flash', None)" py:content="tg_flash"></div>
+
+ <div py:replace="[item.text]+item[:]"></div>
+ </div>
+
+ <div id="sidebar">
+ <h2>Tools</h2>
+ <a href="${tg.url('/groupindex')}">Add Group</a><br/>
+ <a href="${tg.url('/groupindex')}">Find Group</a><br/>
+ <a href="${tg.url('/groupindex')}">List Groups</a><br/>
+ </div>
+</body>
+
+</html>
diff --git a/ipa-server/ipa-gui/ipagui/templates/login.kid b/ipa-server/ipa-gui/ipagui/templates/login.kid new file mode 100644 index 000000000..a819cfc7a --- /dev/null +++ b/ipa-server/ipa-gui/ipagui/templates/login.kid @@ -0,0 +1,112 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml" + xmlns:py="http://purl.org/kid/ns#"> + +<head> + <meta content="text/html; charset=UTF-8" + http-equiv="content-type" py:replace="''"/> + <title>Login</title> + <style type="text/css"> + #loginBox + { + width: 30%; + margin: auto; + margin-top: 10%; + padding-left: 10%; + padding-right: 10%; + padding-top: 5%; + padding-bottom: 5%; + font-family: verdana; + font-size: 10px; + background-color: #eee; + border: 2px solid #ccc; + } + + #loginBox h1 + { + font-size: 42px; + font-family: "Trebuchet MS"; + margin: 0; + color: #ddd; + } + + #loginBox p + { + position: relative; + top: -1.5em; + padding-left: 4em; + font-size: 12px; + margin: 0; + color: #666; + } + + #loginBox table + { + table-layout: fixed; + border-spacing: 0; + width: 100%; + } + + #loginBox td.label + { + width: 33%; + text-align: right; + } + + #loginBox td.field + { + width: 66%; + } + + #loginBox td.field input + { + width: 100%; + } + + #loginBox td.buttons + { + text-align: right; + } + + </style> +</head> + +<body> + <div id="loginBox"> + <h1>Login</h1> + <p>${message}</p> + <form action="${previous_url}" method="POST"> + <table> + <tr> + <td class="label"> + <label for="user_name">User Name:</label> + </td> + <td class="field"> + <input type="text" id="user_name" name="user_name"/> + </td> + </tr> + <tr> + <td class="label"> + <label for="password">Password:</label> + </td> + <td class="field"> + <input type="password" id="password" name="password"/> + </td> + </tr> + <tr> + <td colspan="2" class="buttons"> + <input type="submit" name="login" value="Login"/> + </td> + </tr> + </table> + + <input py:if="forward_url" type="hidden" name="forward_url" + value="${forward_url}"/> + + <input py:for="name,value in original_parameters.items()" + type="hidden" name="${name}" value="${value}"/> + </form> + </div> +</body> +</html> diff --git a/ipa-server/ipa-gui/ipagui/templates/master.kid b/ipa-server/ipa-gui/ipagui/templates/master.kid new file mode 100644 index 000000000..436f0378f --- /dev/null +++ b/ipa-server/ipa-gui/ipagui/templates/master.kid @@ -0,0 +1,48 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<?python import sitetemplate ?>
+<html xmlns="http://www.w3.org/1999/xhtml" xmlns:py="http://purl.org/kid/ns#" py:extends="sitetemplate">
+
+<head py:match="item.tag=='{http://www.w3.org/1999/xhtml}head'" py:attrs="item.items()">
+ <meta content="text/html; charset=UTF-8" http-equiv="content-type" py:replace="''"/>
+ <title py:replace="''">Your title goes here</title>
+ <meta py:replace="item[:]"/>
+ <style type="text/css" media="screen">
+ @import "${tg.url('/static/css/style.css')}";
+ </style>
+</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="page">
+ <div id="header">
+ <h1>Free IPA</h1>
+ </div>
+
+ <div id="nav">
+ <ul>
+ <li><a href="${tg.url('/userindex')}">Users</a></li>
+ <li><a href="${tg.url('/groupindex')}">Groups</a></li>
+ <li><a href="${tg.url('/resindex')}">Resources</a></li>
+ </ul>
+ </div>
+
+ <div py:replace="[item.text]+item[:]"></div>
+
+
+ <div id="footer">
+ This is the footer
+ </div>
+ </div>
+
+</body>
+
+</html>
diff --git a/ipa-server/ipa-gui/ipagui/templates/resindex.kid b/ipa-server/ipa-gui/ipagui/templates/resindex.kid new file mode 100644 index 000000000..5cd06f7eb --- /dev/null +++ b/ipa-server/ipa-gui/ipagui/templates/resindex.kid @@ -0,0 +1,18 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml" xmlns:py="http://purl.org/kid/ns#" + py:extends="'reslayout.kid'"> +<head> +<meta content="text/html; charset=utf-8" http-equiv="Content-Type" py:replace="''"/> +<title>Resource Listing</title> +</head> +<body> + Resources go here. + <br /> + <br /> + <br /> + <br /> + <br /> + <br /> + <br /> +</body> +</html> diff --git a/ipa-server/ipa-gui/ipagui/templates/reslayout.kid b/ipa-server/ipa-gui/ipagui/templates/reslayout.kid new file mode 100644 index 000000000..3f5aa96e3 --- /dev/null +++ b/ipa-server/ipa-gui/ipagui/templates/reslayout.kid @@ -0,0 +1,22 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xmlns:py="http://purl.org/kid/ns#"
+ py:extends="'master.kid'">
+<head>
+</head>
+
+<body py:match="item.tag=='{http://www.w3.org/1999/xhtml}body'" py:attrs="item.items()">
+ <div id="main_content">
+ <div id="status_block" class="flash" py:if="value_of('tg_flash', None)" py:content="tg_flash"></div>
+
+ <div py:replace="[item.text]+item[:]"></div>
+ </div>
+
+ <div id="sidebar">
+ <h2>Tools</h2>
+ <a href="${tg.url('/resindex')}">Add Resource</a><br/>
+ <a href="${tg.url('/resindex')}">Find Resource</a><br/>
+ <a href="${tg.url('/resindex')}">List Resources</a><br/>
+ </div>
+</body>
+
+</html>
diff --git a/ipa-server/ipa-gui/ipagui/templates/useredit.kid b/ipa-server/ipa-gui/ipagui/templates/useredit.kid new file mode 100644 index 000000000..781ff7ff1 --- /dev/null +++ b/ipa-server/ipa-gui/ipagui/templates/useredit.kid @@ -0,0 +1,13 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml" xmlns:py="http://purl.org/kid/ns#" + py:extends="'userlayout.kid'"> +<head> +<meta content="text/html; charset=utf-8" http-equiv="Content-Type" py:replace="''"/> +<title>Edit a Person</title> +</head> +<body> + <h2>Edit User</h2> + + ${form.display(action="userupdate", value=user)} +</body> +</html> diff --git a/ipa-server/ipa-gui/ipagui/templates/userform.kid b/ipa-server/ipa-gui/ipagui/templates/userform.kid new file mode 100644 index 000000000..dd852865a --- /dev/null +++ b/ipa-server/ipa-gui/ipagui/templates/userform.kid @@ -0,0 +1,125 @@ +<div xmlns:py="http://purl.org/kid/ns#" + class="simpleroster"> + <form action="${action}" name="${name}" method="${method}" class="tableform"> + + <div class="formsection">Account Details</div> + <table class="formtable" cellpadding="2" cellspacing="0" border="0"> + <tr> + <th> + <label class="fieldlabel" for="${user.uid.field_id}" + py:content="user.uid.label" /> + </th> + <td> + <span py:replace="user.uid.display(value_for(user.uid))" /> + <span py:if="tg.errors.get('uid')" class="fielderror" + py:content="tg.errors.get('uid')" /> + </td> + </tr> + +<!-- <tr> + <th> + <label class="fieldlabel" for="${user.userPassword.field_id}" + py:content="user.userPassword.label" /> + </th> + <td> + <span py:replace="user.userPassword.display(value_for(user.userPassword))" /> + <span py:if="tg.errors.get('userPassword')" class="fielderror" + py:content="tg.errors.get('userPassword')" /> + </td> + </tr> --> + + <tr> + <th> + <label class="fieldlabel" for="${user.uidNumber.field_id}" + py:content="user.uidNumber.label" /> + </th> + <td> + <span py:replace="user.uidNumber.display(value_for(user.uidNumber))" /> + <span py:if="tg.errors.get('uidNumber')" class="fielderror" + py:content="tg.errors.get('uidNumber')" /> + </td> + </tr> + + <tr> + <th> + <label class="fieldlabel" for="${user.gidNumber.field_id}" + py:content="user.gidNumber.label" /> + </th> + <td> + <span py:replace="user.gidNumber.display(value_for(user.gidNumber))" /> + <span py:if="tg.errors.get('gidNumber')" class="fielderror" + py:content="tg.errors.get('gidNumber')" /> + </td> + </tr> + </table> + + <div class="formsection">Identity Details</div> + <table class="formtable" cellpadding="2" cellspacing="0" border="0"> + <tr> + <th> + <label class="fieldlabel" for="${user.givenName.field_id}" + py:content="user.givenName.label" /> + </th> + <td> + <span py:replace="user.givenName.display(value_for(user.givenName))" /> + <span py:if="tg.errors.get('givenName')" class="fielderror" + py:content="tg.errors.get('givenName')" /> + + </td> + </tr> + + <tr> + <th> + <label class="fieldlabel" for="${user.sn.field_id}" + py:content="user.sn.label" /> + </th> + <td> + <span py:replace="user.sn.display(value_for(user.sn))" /> + <span py:if="tg.errors.get('sn')" class="fielderror" + py:content="tg.errors.get('sn')" /> + </td> + </tr> + </table> + + <div class="formsection">Contact Details</div> + <table class="formtable" cellpadding="2" cellspacing="0" border="0"> + <tr> + <th> + <label class="fieldlabel" for="${user.mail.field_id}" + py:content="user.mail.label" /> + </th> + <td> + <span py:replace="user.mail.display(value_for(user.mail))" /> + <span py:if="tg.errors.get('mail')" class="fielderror" + py:content="tg.errors.get('mail')" /> + </td> + </tr> + <tr> + <th> + <label class="fieldlabel" for="${user.telephoneNumber.field_id}" + py:content="user.telephoneNumber.label" /> + </th> + <td> + <span py:replace="user.telephoneNumber.display(value_for(user.telephoneNumber))" /> + <span py:if="tg.errors.get('telephoneNumber')" class="fielderror" + py:content="tg.errors.get('telephoneNumber')" /> + </td> + </tr> + </table> + + <table class="formtable" cellpadding="2" cellspacing="0" border="0"> + <tr> + <th> + <br /> + <input type="submit" class="submitbutton" name="submit" value="Submit"/> + </th> + <td> + <br /> + <input type="submit" class="submitbutton" name="submit" value="Cancel" /> + </td> + <td></td> + </tr> + </table> + + </form> +</div> diff --git a/ipa-server/ipa-gui/ipagui/templates/userlayout.kid b/ipa-server/ipa-gui/ipagui/templates/userlayout.kid new file mode 100644 index 000000000..de7164f33 --- /dev/null +++ b/ipa-server/ipa-gui/ipagui/templates/userlayout.kid @@ -0,0 +1,22 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xmlns:py="http://purl.org/kid/ns#"
+ py:extends="'master.kid'">
+<head>
+</head>
+
+<body py:match="item.tag=='{http://www.w3.org/1999/xhtml}body'" py:attrs="item.items()">
+ <div id="main_content">
+ <div id="status_block" class="flash" py:if="value_of('tg_flash', None)" py:content="tg_flash"></div>
+
+ <div py:replace="[item.text]+item[:]"></div>
+ </div>
+
+ <div id="sidebar">
+ <h2>Tools</h2>
+ <a href="${tg.url('/usernew')}">Add Person</a><br/>
+ <a href="${tg.url('/userindex')}">Find People</a><br/>
+ <a href="${tg.url('/userlist')}">List People</a><br/>
+ </div>
+</body>
+
+</html>
diff --git a/ipa-server/ipa-gui/ipagui/templates/userlist.kid b/ipa-server/ipa-gui/ipagui/templates/userlist.kid new file mode 100644 index 000000000..7b5667fb5 --- /dev/null +++ b/ipa-server/ipa-gui/ipagui/templates/userlist.kid @@ -0,0 +1,26 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml" xmlns:py="http://purl.org/kid/ns#" + py:extends="'userlayout.kid'"> +<head> +<meta content="text/html; charset=utf-8" http-equiv="Content-Type" py:replace="''"/> +<title>User Listing</title> +</head> +<body> + <fieldset> + <legend>People List</legend> + <div> + Page: + <span py:for="page in tg.paginate.pages"> + <a py:if="page != tg.paginate.current_page" + href="${tg.paginate.get_href(page)}">${page}</a> + <b py:if="page == tg.paginate.current_page">${page}</b> + </span> + <p/> + <span py:for="user in users"> + <a href="${tg.url('/usershow',uid=user.uid)}">${user.cn}</a> + <br/> + </span> + </div> + </fieldset> +</body> +</html> diff --git a/ipa-server/ipa-gui/ipagui/templates/usernew.kid b/ipa-server/ipa-gui/ipagui/templates/usernew.kid new file mode 100644 index 000000000..84b6029ae --- /dev/null +++ b/ipa-server/ipa-gui/ipagui/templates/usernew.kid @@ -0,0 +1,13 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml" xmlns:py="http://purl.org/kid/ns#" + py:extends="'userlayout.kid'"> +<head> + <meta content="text/html; charset=utf-8" http-equiv="Content-Type" py:replace="''"/> + <title>Add a Person</title> +</head> +<body> + <h2>Add New User</h2> + + ${form.display(action="usercreate")} +</body> +</html> diff --git a/ipa-server/ipa-gui/ipagui/templates/usershow.kid b/ipa-server/ipa-gui/ipagui/templates/usershow.kid new file mode 100644 index 000000000..7fea76dbd --- /dev/null +++ b/ipa-server/ipa-gui/ipagui/templates/usershow.kid @@ -0,0 +1,50 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml" xmlns:py="http://purl.org/kid/ns#" + py:extends="'userlayout.kid'"> +<head> + <meta content="text/html; charset=utf-8" http-equiv="Content-Type" py:replace="''"/> + <title>View a Person</title> +</head> +<body> + <h2>View User</h2> + + <div class="formsection">Account Details</div> + <table class="formtable" cellpadding="2" cellspacing="0" border="0"> + <tr> + <th>User ID:</th> + <td>${user.get("uid")}</td> + </tr> + <tr> + <th>UID:</th> + <td>${user.get("uidNumber")}</td> + </tr> + <tr> + <th>GID:</th> + <td>${user.get("gidNumber")}</td> + </tr> + </table> + + <div class="formsection">Identity Details</div> + <table class="formtable" cellpadding="2" cellspacing="0" border="0"> + <tr> + <th>Full Name:</th> + <td>${user.get("givenName")} ${user.get("sn")}</td> + </tr> + </table> + + <div class="formsection">Contact Details</div> + <table class="formtable" cellpadding="2" cellspacing="0" border="0"> + <tr> + <th>Email:</th> + <td>${user.get("mail")}</td> + </tr> + <tr> + <th>Telephone:</th> + <td>${user.get("telephoneNumber")}</td> + </tr> + </table> + + <a href="${tg.url('/useredit', uid=user.get('uid'))}">edit</a> + +</body> +</html> diff --git a/ipa-server/ipa-gui/ipagui/templates/welcome.kid b/ipa-server/ipa-gui/ipagui/templates/welcome.kid new file mode 100644 index 000000000..02b140f64 --- /dev/null +++ b/ipa-server/ipa-gui/ipagui/templates/welcome.kid @@ -0,0 +1,18 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xmlns:py="http://purl.org/kid/ns#"
+ py:extends="'master.kid'">
+<head>
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" py:replace="''"/>
+<title>Welcome</title>
+</head>
+<body>
+ <div id="sidebar">
+ <h2>Tools</h2>
+ </div>
+ <div id="main_content">
+ <div id="status_block" class="flash" py:if="value_of('tg_flash', None)" py:content="tg_flash"></div>
+ <h1>Welcome to Free IPA</h1>
+ </div>
+
+</body>
+</html>
diff --git a/ipa-server/ipa-gui/ipagui/tests/test_controllers.py b/ipa-server/ipa-gui/ipagui/tests/test_controllers.py new file mode 100644 index 000000000..b9b4f5c5c --- /dev/null +++ b/ipa-server/ipa-gui/ipagui/tests/test_controllers.py @@ -0,0 +1,32 @@ +import unittest +import turbogears +from turbogears import testutil +from ipagui.controllers import Root +import cherrypy + +cherrypy.root = Root() + +class TestPages(unittest.TestCase): + + def setUp(self): + turbogears.startup.startTurboGears() + + def tearDown(self): + """Tests for apps using identity need to stop CP/TG after each test to + stop the VisitManager thread. + See http://trac.turbogears.org/turbogears/ticket/1217 for details. + """ + turbogears.startup.stopTurboGears() + + def test_method(self): + "the index method should return a string called now" + import types + result = testutil.call(cherrypy.root.index) + assert type(result["now"]) == types.StringType + + def test_indextitle(self): + "The indexpage should have the right title" + testutil.createRequest("/") + response = cherrypy.response.body[0].lower() + assert "<title>welcome to turbogears</title>" in response + diff --git a/ipa-server/ipa-gui/ipagui/tests/test_model.py b/ipa-server/ipa-gui/ipagui/tests/test_model.py new file mode 100644 index 000000000..bd0db4c70 --- /dev/null +++ b/ipa-server/ipa-gui/ipagui/tests/test_model.py @@ -0,0 +1,22 @@ +# If your project uses a database, you can set up database tests +# similar to what you see below. Be sure to set the db_uri to +# an appropriate uri for your testing database. sqlite is a good +# choice for testing, because you can use an in-memory database +# which is very fast. + +from turbogears import testutil, database +# from ipagui.model import YourDataClass, User + +# database.set_db_uri("sqlite:///:memory:") + +# class TestUser(testutil.DBTest): +# def get_model(self): +# return User +# def test_creation(self): +# "Object creation should set the name" +# obj = User(user_name = "creosote", +# email_address = "spam@python.not", +# display_name = "Mr Creosote", +# password = "Wafer-thin Mint") +# assert obj.display_name == "Mr Creosote" + diff --git a/ipa-server/ipa-gui/sample-prod.cfg b/ipa-server/ipa-gui/sample-prod.cfg new file mode 100644 index 000000000..ffa684cc1 --- /dev/null +++ b/ipa-server/ipa-gui/sample-prod.cfg @@ -0,0 +1,84 @@ +[global] +# This is where all of your settings go for your production environment. +# You'll copy this file over to your production server and provide it +# as a command-line option to your start script. +# Settings that are the same for both development and production +# (such as template engine, encodings, etc.) all go in +# ipagui/config/app.cfg + +# DATABASE + +# pick the form for your database +# sqlobject.dburi="postgres://username@hostname/databasename" +# sqlobject.dburi="mysql://username:password@hostname:port/databasename" +# sqlobject.dburi="sqlite:///file_name_and_path" + +# If you have sqlite, here's a simple default to get you started +# in development +sqlobject.dburi="sqlite://%(current_dir_uri)s/devdata.sqlite" + + +# if you are using a database or table type without transactions +# (MySQL default, for example), you should turn off transactions +# by prepending notrans_ on the uri +# sqlobject.dburi="notrans_mysql://username:password@hostname:port/databasename" + +# for Windows users, sqlite URIs look like: +# sqlobject.dburi="sqlite:///drive_letter:/path/to/file" + + +# SERVER + +server.environment="production" + +# Sets the number of threads the server uses +# server.thread_pool = 1 + +# if this is part of a larger site, you can set the path +# to the TurboGears instance here +# server.webpath="" + +# Set to True if you are deploying your App behind a proxy +# e.g. Apache using mod_proxy +# base_url_filter.on = False + +# Set to True if your proxy adds the x_forwarded_host header +# base_url_filter.use_x_forwarded_host = True + +# If your proxy does not add the x_forwarded_host header, set +# the following to the *public* host url. +# (Note: This will be overridden by the use_x_forwarded_host option +# if it is set to True and the proxy adds the header correctly. +# base_url_filter.base_url = "http://www.example.com" + +# Set to True if you'd like to abort execution if a controller gets an +# unexpected parameter. False by default +# tg.strict_parameters = False + +# LOGGING +# Logging configuration generally follows the style of the standard +# Python logging module configuration. Note that when specifying +# log format messages, you need to use *() for formatting variables. +# Deployment independent log configuration is in ipagui/config/log.cfg +[logging] + +[[handlers]] + +[[[access_out]]] +# set the filename as the first argument below +args="('server.log',)" +class='FileHandler' +level='INFO' +formatter='message_only' + +[[loggers]] +[[[ipagui]]] +level='ERROR' +qualname='ipagui' +handlers=['error_out'] + +[[[access]]] +level='INFO' +qualname='turbogears.access' +handlers=['access_out'] +propagate=0 diff --git a/ipa-server/ipa-gui/setup.py b/ipa-server/ipa-gui/setup.py new file mode 100644 index 000000000..371325f6a --- /dev/null +++ b/ipa-server/ipa-gui/setup.py @@ -0,0 +1,62 @@ +from setuptools import setup, find_packages +from turbogears.finddata import find_package_data + +import os +execfile(os.path.join("ipagui", "release.py")) + +setup( + name="ipa-gui", + version=version, + + # uncomment the following lines if you fill them out in release.py + #description=description, + #author=author, + #author_email=email, + #url=url, + #download_url=download_url, + #license=license, + + install_requires = [ + "TurboGears >= 1.0.2.2", + ], + scripts = ["start-ipagui.py"], + zip_safe=False, + packages=find_packages(), + package_data = find_package_data(where='ipagui', + package='ipagui'), + keywords = [ + # Use keywords if you'll be adding your package to the + # Python Cheeseshop + + # if this has widgets, uncomment the next line + # 'turbogears.widgets', + + # if this has a tg-admin command, uncomment the next line + # 'turbogears.command', + + # if this has identity providers, uncomment the next line + # 'turbogears.identity.provider', + + # If this is a template plugin, uncomment the next line + # 'python.templating.engines', + + # If this is a full application, uncomment the next line + # 'turbogears.app', + ], + classifiers = [ + 'Development Status :: 3 - Alpha', + 'Operating System :: OS Independent', + 'Programming Language :: Python', + 'Topic :: Software Development :: Libraries :: Python Modules', + 'Framework :: TurboGears', + # if this is an application that you'll distribute through + # the Cheeseshop, uncomment the next line + # 'Framework :: TurboGears :: Applications', + + # if this is a package that includes widgets that you'll distribute + # through the Cheeseshop, uncomment the next line + # 'Framework :: TurboGears :: Widgets', + ], + test_suite = 'nose.collector', + ) + diff --git a/ipa-server/ipa-gui/start-ipagui.py b/ipa-server/ipa-gui/start-ipagui.py new file mode 100644 index 000000000..2165e110b --- /dev/null +++ b/ipa-server/ipa-gui/start-ipagui.py @@ -0,0 +1,25 @@ +#!/usr/bin/python +import pkg_resources +pkg_resources.require("TurboGears") + +from turbogears import update_config, start_server +import cherrypy +cherrypy.lowercase_api = True +from os.path import * +import sys + +# first look on the command line for a desired config file, +# if it's not on the command line, then +# look for setup.py in this directory. If it's not there, this script is +# probably installed +if len(sys.argv) > 1: + update_config(configfile=sys.argv[1], + modulename="ipagui.config") +elif exists(join(dirname(__file__), "setup.py")): + update_config(configfile="dev.cfg",modulename="ipagui.config") +else: + update_config(configfile="prod.cfg",modulename="ipagui.config") + +from ipagui.controllers import Root + +start_server(Root()) diff --git a/ipa-server/ipa-gui/test.cfg b/ipa-server/ipa-gui/test.cfg new file mode 100644 index 000000000..df909c99d --- /dev/null +++ b/ipa-server/ipa-gui/test.cfg @@ -0,0 +1,4 @@ +# You can place test-specific configuration options here (like test db uri, etc) + +sqlobject.dburi = "sqlite:///:memory:" + |