This patch removes the existing UI functionality, as a prep for adding the Javascript based ui.

This commit is contained in:
Adam Young 2010-07-26 11:57:29 -04:00 committed by Rob Crittenden
parent fd1ff372dc
commit 26b0e8fc98
17 changed files with 4 additions and 675 deletions

0
dev/null Normal file
View File

View File

@ -19,13 +19,10 @@ install-exec-local:
chmod 700 $(DESTDIR)$(localstatedir)/lib/ipa/sysrestore
mkdir -p $(DESTDIR)$(localstatedir)/cache/ipa/sessions
chmod 700 $(DESTDIR)$(localstatedir)/cache/ipa/sessions
mkdir -p $(DESTDIR)$(localstatedir)/cache/ipa/assets
chmod 700 $(DESTDIR)$(localstatedir)/cache/ipa/assets
uninstall-local:
-rmdir $(DESTDIR)$(localstatedir)/lib/ipa/sysrestore
-rmdir $(DESTDIR)$(localstatedir)/lib/ipa
-rmdir $(DESTDIR)$(localstatedir)/cache/ipa/assets
-rmdir $(DESTDIR)$(localstatedir)/cache/ipa/sessions
-rmdir $(DESTDIR)$(localstatedir)/cache/ipa

View File

@ -129,10 +129,6 @@ PYTHON_POTFILES = \
../../ipaserver/plugins/xmlserver.py \
../../ipaserver/plugins/dogtag.py \
../../contrib/RHEL4/ipachangeconf.py \
../../ipawebui/engine.py \
../../ipawebui/__init__.py \
../../ipawebui/widgets.py \
../../ipawebui/controllers.py \
../../ipa-client/ipaclient/ntpconf.py \
../../ipa-client/ipaclient/__init__.py \
../../ipa-client/ipaclient/ipachangeconf.py \

View File

@ -10,8 +10,6 @@ except StandardError, e:
api.log.error('Failed to start IPA: %s' % e)
else:
api.log.info('*** PROCESS START ***')
import ipawebui
ui = ipawebui.create_wsgi_app(api)
# This is the WSGI callable:
application = api.Backend.session

View File

@ -56,14 +56,12 @@ from ipapython import sysrestore
from ipapython.ipautil import *
from ipalib import api, errors, util
import ipawebui
pw_name = None
uninstalling = False
# Used to determine the the highest possible uid/gid
MAXINT_32BIT = 2147483648
ASSETS_DIR = '/var/cache/ipa/assets'
def parse_options():
namespace = random.randint(1000000, (MAXINT_32BIT - 1000000))
@ -412,13 +410,6 @@ def uninstall(dm_password=None):
return 0
def render_assets():
"""
Render CSS and JavaScript assets.
"""
ui = ipawebui.create_wsgi_app(api)
ui.render_assets()
def set_subject_in_config(host_name, dm_password, suffix, subject_base):
ldapuri = 'ldap://%s' % host_name
try:
@ -511,7 +502,6 @@ def main():
print " * Create and configure an instance of Directory Server"
print " * Create and configure a Kerberos Key Distribution Center (KDC)"
print " * Configure Apache (httpd)"
print " * Render web UI JavaScript and CSS assets"
if options.setup_dns:
print " * Configure DNS (bind)"
if not options.conf_ntp:
@ -656,7 +646,6 @@ def main():
fd.write("enable_ra=True\n")
if not options.selfsign:
fd.write("ra_plugin=dogtag\n")
fd.write('webui_assets_dir=' + ASSETS_DIR + '\n')
fd.close()
api.bootstrap(**cfg)
@ -739,9 +728,6 @@ def main():
# generated
ds.add_cert_to_service()
# Render webui assets:
ipautil.run(["/sbin/restorecon", ASSETS_DIR])
render_assets()
# Create a HTTP instance

View File

@ -85,8 +85,6 @@ Requires: mod_nss
%endif
Requires: python-ldap
Requires: python-krbV
Requires: python-assets
Requires: python-wehjit >= 0.2.2
Requires: acl
Requires: python-pyasn1 >= 0.0.9a
Requires: libcap
@ -379,7 +377,6 @@ fi
%{_sbindir}/ipa-upgradeconfig
%attr(755,root,root) %{_initrddir}/ipa_kpasswd
%{python_sitelib}/ipaserver/*
%{python_sitelib}/ipawebui/*
%dir %{_usr}/share/ipa
%{_usr}/share/ipa/wsgi.py*
%{_usr}/share/ipa/*.ldif
@ -415,7 +412,6 @@ fi
%attr(700,root,root) %dir %{_localstatedir}/lib/ipa/sysrestore
%dir %{_localstatedir}/cache/ipa
%attr(700,apache,apache) %dir %{_localstatedir}/cache/ipa/sessions
%attr(700,apache,apache) %dir %{_localstatedir}/cache/ipa/assets
%attr(700,root,root) %dir %{_localstatedir}/cache/ipa/kpasswd
%{_mandir}/man1/ipa-replica-install.1.gz
%{_mandir}/man1/ipa-replica-manage.1.gz
@ -498,6 +494,9 @@ fi
%endif
%changelog
* Thu Jun 24 2010 Adam Young <ayoung@redhat.com> - 1.99-24
- Removed python-asset based webui
* Thu Jun 24 2010 Rob Crittenden <rcritten@redhat.com> - 1.99-23
- Change Requires from fedora-ds-base to 389-ds-base
- Set minimum level of 389-ds-base to 1.2.6 for the replication

View File

@ -110,8 +110,6 @@ DEFAULT_CONFIG = (
('mount_ipa', '/ipa/'),
('mount_xmlserver', 'xml'),
('mount_jsonserver', 'json'),
('mount_webui', 'ui'),
('mount_webui_assets', '/ipa-assets/'),
# WebUI stuff:
('webui_prod', True),

View File

@ -1,73 +0,0 @@
# Authors: Jason Gerard DeRose <jderose@redhat.com>
#
# Copyright (C) 2009 Red Hat
# see file 'COPYING' for use and warranty information
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; version 2 only
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
"""
IPA web UI.
"""
# Special wehjit initialization to prevent it from loading the plugins that
# require pygments, which uses ctypes, which makes the httpd SELinux policy
# crazy:
import wehjit
wehjit.builtins._skip_pygments = True
wehjit.init_builtins()
from ipalib.backend import Executioner
from ipalib.request import destroy_context
from ipaserver.rpcserver import extract_query
from controllers import JSON
from engine import Engine
from widgets import create_widgets
from assetslib import Assets
from wehjit import Application
def join_url(base, url):
if url.startswith('/'):
return url
return base + url
class WebUI(Application):
def __init__(self, api):
self.api = api
baseurl = api.env.mount_ipa
assets = Assets(
url=join_url(baseurl, api.env.mount_webui_assets),
dir=api.env.webui_assets_dir,
prod=api.env.webui_prod,
)
super(WebUI, self).__init__(
url=join_url(baseurl, api.env.mount_webui),
assets=assets,
widgets=create_widgets(),
prod=api.env.webui_prod,
)
self.api.Backend.session.mount(self, api.env.mount_webui)
def create_wsgi_app(api):
app = WebUI(api)
engine = Engine(api, app)
engine.build()
app.finalize()
return app

View File

@ -1,59 +0,0 @@
# Authors: Jason Gerard DeRose <jderose@redhat.com>
#
# Copyright (C) 2008 Red Hat
# see file 'COPYING' for use and warranty information
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; version 2 only
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
"""
Controllers.
"""
from wehjit import util
from ipalib.compat import json
class JSON(object):
def __init__(self, url, api):
self.url = url
self.api = api
def __repr__(self):
return '%s(url=%r)' % (self.__class__.__name__, self.url)
def __call__(self, env, start):
util.extract_query(env)
start('200 OK', [('Content-Type', 'text/plain')])
for key in sorted(env):
yield '%s = %r\n' % (key, env[key])
class Command(object):
def __init__(self, url, cmd, api):
self.url = url
self.cmd = cmd
self.api = api
def __repr__(self):
return '%s(url=%r)' % (self.__class__.__name__, self.url)
def __call__(self, env, start):
kw = util.extract_query(env)
ccname = env['KRB5CCNAME']
self.api.Backend.xmlserver.create_context(ccname)
result = self.api.Backend.xmlserver.execute(self.cmd.name, **kw)
start('200 OK', [('Content-Type', 'text/plain')])
return [
json.dumps(result, sort_keys=True, indent=4)
]

View File

@ -1,200 +0,0 @@
# Authors: Jason Gerard DeRose <jderose@redhat.com>
#
# Copyright (C) 2009 Red Hat
# see file 'COPYING' for use and warranty information
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; version 2 only
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
"""
Engine to map ipalib plugins to wehjit widgets.
"""
from controllers import Command
from ipalib import crud
class ParamMapper(object):
def __init__(self, api, app):
self._api = api
self._app = app
self.__methods = dict()
for name in dir(self):
if name.startswith('_'):
continue
attr = getattr(self, name)
if not callable(attr):
continue
self.__methods[name] = attr
def __call__(self, param, cmd):
key = param.__class__.__name__
if key in self.__methods:
method = self.__methods[key]
else:
method = self.Str
return method(param, cmd)
def Str(self, param, cmd):
return self._app.new('TextRow',
label=param.label,
name=param.name,
required=param.required,
value=param.default,
)
def Password(self, param, cmd):
return self._app.new('PasswordRow',
name=param.name,
required=param.required,
)
def Flag(self, param, cmd):
return self._app.new('SelectRow',
name=param.name,
label=param.label,
)
def filter_params(namespace):
for param in namespace():
if param.exclude and 'webui' in param.exclude:
continue
yield param
class Engine(object):
cruds = frozenset(['add', 'show', 'mod', 'del', 'find'])
def __init__(self, api, app):
self.api = api
self.app = app
self.param_mapper = ParamMapper(api, app)
self.pages = dict()
self.jsonurl = self.api.Backend.jsonserver.url.rstrip('/')
self.info_pages = []
def add_object_menuitems(self, menu, name):
obj = self.api.Object[name]
for cmd in obj.methods():
p = self.pages[cmd.name]
menu.add(
menu.new('MenuItem',
label=p.title,
href=p.url,
)
)
def build(self):
for obj in self.api.Object():
if self.cruds.issubset(obj.methods) and obj.primary_key is not None:
self.pages[obj.name] = self.build_cruds_page(obj)
# Add landing page:
landing = self.app.new('PageApp', id='', title='Welcome to FreeIPA')
for page in self.pages.values() + [landing]:
page.menu.label = 'FreeIPA'
for name in sorted(self.pages):
p = self.pages[name]
page.menu.new_child('MenuItem', label=p.title, href=p.url)
# Add in the info pages:
page = self.app.new('PageApp', id='api', title='api')
page.view.add(
self.app.new('API', api=self.api)
)
self.info_pages.append(page)
for kind in self.api:
self.build_info_page(kind)
for page in self.info_pages:
for p in self.info_pages:
page.menuset.add(
self.app.new('MenuItem',
href=p.url,
label=p.title,
)
)
def build_cruds_page(self, obj):
page = self.app.new('PageGrid', title=obj.label, id=obj.name)
# Setup CRUDS widget:
page.cruds.autoload = True
page.cruds.jsonrpc_url = self.api.Backend.jsonserver.url
page.cruds.key = obj.primary_key.name
page.cruds.method_create = obj.methods['add'].name
page.cruds.method_retrieve = obj.methods['show'].name
page.cruds.method_update = obj.methods['mod'].name
page.cruds.method_delete = obj.methods['del'].name
page.cruds.method_search = obj.methods['find'].name
page.cruds.display_cols = tuple(
dict(
name=p.name,
label=p.label,
css_classes=None,
)
for p in obj.params()
)
# Setup the Grid widget:
page.grid.cols = tuple(
dict(
name=p.name,
label=p.label,
css_classes=None,
)
for p in obj.params() if p.required
)
# Setup the create Dialog:
cmd = obj.methods['add']
page.create.title = cmd.summary.rstrip('.')
for p in filter_params(cmd.params):
page.create.fieldtable.add(self.param_mapper(p, cmd))
# Setup the retrieve Dialog
page.retrieve.title = 'Showing "{value}"'
# Setup the update Dialog:
page.update.title = 'Updating "{value}"'
cmd = obj.methods['mod']
for p in filter_params(cmd.options):
page.update.fieldtable.add(self.param_mapper(p, cmd))
# Setup the delete Dialog
page.delete.title = 'Delete "{value}"?'
return page
def build_info_page(self, kind):
# Add in the Object page:
plugins = tuple(self.api[kind]())
page = self.app.new('PageApp', id=kind, title=kind)
info = self.app.new('IPAPlugins', kind=kind, plugins=plugins)
quick_jump = self.app.new('QuickJump',
options=tuple((p.name, p.name) for p in plugins)
)
page.view.add(info)
page.actions.add(quick_jump)
self.info_pages.append(page)
if kind in self.app.widgets:
info.add(
self.app.new(kind)
)
return page

View File

@ -1,260 +0,0 @@
# Authors: Jason Gerard DeRose <jderose@redhat.com>
#
# Copyright (C) 2009 Red Hat
# see file 'COPYING' for use and warranty information
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; version 2 only
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
"""
Custom IPA widgets.
"""
from textwrap import dedent
from wehjit import Collection, base, freeze, builtins
from wehjit.util import Alternator
from wehjit import Static, Dynamic, StaticProp, DynamicProp
from ipaserver.rpcserver import extract_query
class IPAPlugins(base.Container):
plugins = Static('plugins', default=tuple())
kind = Static('kind')
@DynamicProp
def row(self):
return Alternator(['odd', 'even'])
xml = """
<div
xmlns:py="http://genshi.edgewall.org/"
class="${css_classes}"
id="${id}"
>
<p py:content="'%d %s plugins' % (len(plugins), kind)" />
<div py:for="p in plugins">
<h2 id="${p.name}"><a href="#${p.name}" py:content="p.name" /></h2>
<table class="${row.reset()}">
<tr class="${row.next()}">
<td>module</td>
<td>
<a
title="Link to module documentation"
href="http://freeipa.org/developer-docs/${p.module}-module.html"
py:content="p.module"
/>
</td>
</tr>
<tr class="${row.next()}">
<td>base(s)</td>
<td py:content="', '.join(p.bases)" />
</tr>
<tr py:if="p.doc" class="${row.next()}">
<td>docstring</td>
<td><pre py:content="p.doc" /></td>
</tr>
<tr
py:for="child in children"
py:replace="child.generate(plugin=p, row=row)"
/>
</table>
</div>
</div>
"""
style_global = (
('tr.odd', (
('background-color', '#ddd'),
)),
('tr.even', (
('background-color', '#eee'),
)),
('td', (
('vertical-align', 'top'),
('padding', '0.25em 0.5em'),
)),
)
style = (
('', (
('font-size', '%(font_size_mono)s'),
('font-family', 'monospace'),
)),
('table', (
('width', '100%%'),
)),
('pre', (
('margin', '0'),
)),
('th', (
('color', '#0a0'),
)),
('h2', (
('font-family', 'monospace'),
('font-weight', 'normal'),
('margin-top', '1.5em'),
('margin-bottom', '0'),
)),
('h2 a', (
('text-decoration', 'none'),
('color', 'inherit'),
)),
('h2 a:hover', (
('background-color', '#eee'),
)),
('h2:target', (
('color', '#e02'),
)),
)
class API(base.Widget):
api = Static('api')
@DynamicProp
def row(self):
return Alternator(['odd', 'even'])
xml = """
<div
xmlns:py="http://genshi.edgewall.org/"
class="${css_classes}"
id="${id}"
>
<p py:content="'%d namespaces in API' % len(api)" />
<table>
<tr py:for="key in api" class="${row.next()}">
<td>
<a href="${key}" py:content="'api.' + key" />
</td>
<td py:content="repr(api[key])" />
</tr>
</table>
</div>
"""
class Command(base.Widget):
xml = """
<table
xmlns:py="http://genshi.edgewall.org/"
py:strip="True"
>
<tr py:if="plugin.obj" class="${row.next()}">
<td>Object</td>
<td>
<a href="Object#${plugin.obj.name}" py:content="plugin.obj.fullname" />
</td>
</tr>
<tr py:if="plugin.args" class="${row.next()}">
<th colspan="2" py:content="'args (%d)' % len(plugin.args)" />
</tr>
<tr py:for="arg in plugin.args()" class="${row.next()}">
<td py:content="arg.name"/>
<td py:content="repr(arg)" />
</tr>
<tr py:if="plugin.options" class="${row.next()}">
<th colspan="2" py:content="'options (%d)' % len(plugin.options)" />
</tr>
<tr py:for="option in plugin.options()" class="${row.next()}">
<td py:content="option.name"/>
<td py:content="repr(option)" />
</tr>
<tr py:if="plugin.output" class="${row.next()}">
<th colspan="2" py:content="'output (%d)' % len(plugin.output)" />
</tr>
<tr py:for="param in plugin.output()" class="${row.next()}">
<td py:content="param.name"/>
<td py:content="repr(param)" />
</tr>
</table>
"""
class Object(base.Widget):
xml = """
<table
xmlns:py="http://genshi.edgewall.org/"
py:strip="True"
>
<tr py:if="plugin.methods" class="${row.next()}">
<th colspan="2" py:content="'methods (%d)' % len(plugin.methods)" />
</tr>
<tr py:for="method in plugin.methods()" class="${row.next()}">
<td><a href="${'Command#' + method.name}" py:content="method.name"/></td>
<td py:content="method.summary" />
</tr>
<tr py:if="plugin.params" class="${row.next()}">
<th colspan="2" py:content="'params (%d)' % len(plugin.params)" />
</tr>
<tr py:for="param in plugin.params()" class="${row.next()}">
<td>${"param.name"}:</td>
<td py:content="repr(param)" />
</tr>
</table>
"""
class LandingPage(base.Widget):
pages = Static('pages', default=tuple())
xml = """
<div
xmlns:py="http://genshi.edgewall.org/"
class="${css_classes}"
id="${id}"
>
<a
py:for="p in pages"
py:content="p.title"
href="${relurl(p.url)}"
/>
</div>
"""
def create_widgets():
widgets = Collection('freeIPA')
widgets.register_builtins()
widgets.register(API)
widgets.register(IPAPlugins)
widgets.register(Command)
widgets.register(Object)
widgets.register(LandingPage)
freeze(widgets)
return widgets

View File

@ -36,9 +36,7 @@ import optparse
from paste import httpserver
import paste.gzipper
from paste.urlmap import URLMap
from assetslib.wsgi import AssetsApp
from ipalib import api
import ipawebui
class KRBCheater(object):
@ -82,13 +80,9 @@ if __name__ == '__main__':
)
api.finalize()
ui = ipawebui.create_wsgi_app(api)
ui.render_assets()
urlmap = URLMap()
apps = [
('IPA', KRBCheater(api.Backend.session)),
('Assets', AssetsApp(ui.assets)),
]
for (name, app) in apps:
urlmap[app.url] = app

View File

@ -2,7 +2,7 @@
# Hackish script to generate documentation using epydoc
sources="ipalib ipaserver ipawebui tests"
sources="ipalib ipaserver tests"
out="./freeipa2-dev-doc"
init="./ipalib/__init__.py"

View File

@ -2,7 +2,6 @@
# /var
#
/var/cache/ipa/sessions(/.*)? gen_context(system_u:object_r:httpd_sys_content_t,s0)
/var/cache/ipa/assets(/.*)? gen_context(system_u:object_r:httpd_sys_content_t,s0)
# Make these files writable so the selfsign plugin can operate
/etc/httpd/alias/cert8.db -- gen_context(system_u:object_r:cert_t,s0)

View File

@ -81,7 +81,6 @@ setup(
'ipaserver',
'ipaserver.plugins',
'ipaserver.install',
'ipawebui',
],
scripts=['ipa'],
data_files = [('share/man/man1', ["ipa.1"])],

View File

@ -1,21 +0,0 @@
# Authors: Jason Gerard DeRose <jderose@redhat.com>
#
# Copyright (C) 2008 Red Hat
# see file 'COPYING' for use and warranty information
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; version 2 only
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
"""
Sub-package containing unit tests for `ipawebui` package.
"""

View File

@ -1,24 +0,0 @@
# Authors: Jason Gerard DeRose <jderose@redhat.com>
#
# Copyright (C) 2008 Red Hat
# see file 'COPYING' for use and warranty information
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; version 2 only
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
"""
Test the `ipawebui.controllers` module.
"""
from wsgiref import util
from wsgiref.validate import validator