Service principal deletion

This commit is contained in:
Rob Crittenden 2008-01-11 11:44:23 -05:00
parent 58071a759a
commit 42d5ddc559
7 changed files with 138 additions and 2 deletions

View File

@ -386,6 +386,9 @@ class IPAClient:
def add_service_principal(self, princ_name): def add_service_principal(self, princ_name):
return self.transport.add_service_principal(princ_name) return self.transport.add_service_principal(princ_name)
def delete_service_principal(self, principal_dn):
return self.transport.delete_service_principal(principal_dn)
def find_service_principal(self, criteria, sattrs=None, searchlimit=0, timelimit=-1): def find_service_principal(self, criteria, sattrs=None, searchlimit=0, timelimit=-1):
"""Return a list: counter followed by a Entity object for each host that """Return a list: counter followed by a Entity object for each host that
matches the criteria. If the results are truncated, counter will matches the criteria. If the results are truncated, counter will

View File

@ -699,6 +699,18 @@ class RPCClient:
return ipautil.unwrap_binary_data(result) return ipautil.unwrap_binary_data(result)
def delete_service_principal(self, principal_dn):
server = self.setup_server()
try:
result = server.delete_service_principal(principal_dn)
except xmlrpclib.Fault, fault:
raise ipaerror.gen_exception(fault.faultCode, fault.faultString)
except socket.error, (value, msg):
raise xmlrpclib.Fault(value, msg)
return ipautil.unwrap_binary_data(result)
def find_service_principal (self, criteria, sattrs=None, searchlimit=0, timelimit=-1): def find_service_principal (self, criteria, sattrs=None, searchlimit=0, timelimit=-1):
"""Return a list: counter followed by a Entity object for each host that """Return a list: counter followed by a Entity object for each host that
matches the criteria. If the results are truncated, counter will matches the criteria. If the results are truncated, counter will

View File

@ -125,6 +125,51 @@ class PrincipalController(IPAController):
return dict(principals=principals, hostname=hostname, fields=ipagui.forms.principal.PrincipalFields()) return dict(principals=principals, hostname=hostname, fields=ipagui.forms.principal.PrincipalFields())
@expose("ipagui.templates.principalshow")
@identity.require(identity.not_anonymous())
def show(self, **kw):
"""Display a single service principal"""
try:
princ = kw['principal']
princ_dn = kw['principal_dn']
except KeyError, e:
turbogears.flash("Principal show failed. Unable to find key %s" % e)
raise turbogears.redirect("/principal/list")
principal = {}
try:
# The principal info is passed in. Not going to both to re-query this.
(service,host) = princ.split('/')
h = host.split('@')
principal['service'] = service
principal['hostname'] = h[0]
principal['principal_dn'] = princ_dn
return dict(principal=principal)
except:
turbogears.flash("Principal show failed %s" % princ)
raise turbogears.redirect("/")
@expose()
@identity.require(identity.in_group("admins"))
def delete(self, principal):
"""Delete a service principal"""
self.restrict_post()
client = self.get_ipaclient()
print "Deleting %s" % principal
try:
client.delete_service_principal(principal)
turbogears.flash("Service principal deleted")
raise turbogears.redirect('/principal/list')
except (SyntaxError, ipaerror.IPAError), e:
turbogears.flash("Service principal deletion failed: " + str(e) + "<br/>" + e.detail[0]['desc'])
raise turbogears.redirect('/principal/list')
@validate(form=principal_new_form) @validate(form=principal_new_form)
@identity.require(identity.not_anonymous()) @identity.require(identity.not_anonymous())
def principalcreatevalidate(self, tg_errors=None, **kw): def principalcreatevalidate(self, tg_errors=None, **kw):

View File

@ -33,10 +33,12 @@
<tbody> <tbody>
<tr py:for="principal in principals"> <tr py:for="principal in principals">
<td> <td>
${principal.hostname} <a href="${tg.url('/principal/show',principal=principal.krbprincipalname,principal_dn=principal.dn)}"
>${principal.hostname}</a>
</td> </td>
<td> <td>
${principal.service} <a href="${tg.url('/principal/show',principal=principal.krbprincipalname,principal_dn=principal.dn)}"
>${principal.service}</a>
</td> </td>
</tr> </tr>
</tbody> </tbody>

View File

@ -0,0 +1,53 @@
<!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="'policylayout.kid'">
<head>
<meta content="text/html; charset=utf-8" http-equiv="Content-Type" py:replace="''"/>
<title>View Service Principal</title>
</head>
<body>
<script type="text/javascript" charset="utf-8" src="${tg.url('/static/javascript/tablekit.js')}"></script>
<script type="text/javascript" charset="utf-8">
function confirmDelete() {
if (confirm("Are you sure you want to delete this service principal?")) {
$('deleteform').submit();
}
return false;
}
</script>
<form id='deleteform'
method="post" action="${tg.url('/principal/delete')}">
<input type="hidden" name="principal" value="${principal.get('principal_dn')}" />
<input type="submit" class="submitbutton"
value="Delete Principal"
onclick="return confirmDelete();"
/>
<h1>View Service Principal</h1>
<h2 class="formsection">Principal</h2>
<table class="formtable" cellpadding="2" cellspacing="0" border="0">
<tr>
<th>
<label class="fieldlabel">Host</label>:
</th>
<td>${principal.get("hostname")}</td>
</tr>
<tr>
<th>
<label class="fieldlabel">Service</label>:
</th>
<td>${principal.get("service")}</td>
</tr>
</table>
</form>
<hr />
</body>
</html>

View File

@ -1724,6 +1724,26 @@ class IPAServer:
self.releaseConnection(conn) self.releaseConnection(conn)
return res return res
def delete_service_principal (self, principal, opts=None):
"""Delete a service principal.
principal is the full DN of the entry to delete.
This should be called with much care.
"""
if not principal:
raise ipaerror.gen_exception(ipaerror.INPUT_INVALID_PARAMETER)
entry = self.get_entry_by_dn(principal, ['dn', 'objectclass'], opts)
if entry is None:
raise ipaerror.gen_exception(ipaerror.LDAP_NOT_FOUND)
conn = self.getConnection(opts)
try:
res = conn.deleteEntry(entry['dn'])
finally:
self.releaseConnection(conn)
return res
def find_service_principal(self, criteria, sattrs, searchlimit=-1, def find_service_principal(self, criteria, sattrs, searchlimit=-1,
timelimit=-1, opts=None): timelimit=-1, opts=None):
"""Returns a list: counter followed by the results. """Returns a list: counter followed by the results.

View File

@ -365,6 +365,7 @@ def handler(req, profiling=False):
h.register_function(f.get_password_policy) h.register_function(f.get_password_policy)
h.register_function(f.update_password_policy) h.register_function(f.update_password_policy)
h.register_function(f.add_service_principal) h.register_function(f.add_service_principal)
h.register_function(f.delete_service_principal)
h.register_function(f.find_service_principal) h.register_function(f.find_service_principal)
h.register_function(f.get_radius_client_by_ip_addr) h.register_function(f.get_radius_client_by_ip_addr)
h.register_function(f.add_radius_client) h.register_function(f.add_radius_client)