class MassPasswordChangePage(rend.Page): implements(iskin.ISkinnable) title = _('Ldaptor Mass Password Change Page') addSlash = True docFactory = loaders.xmlfile('mass_change_password.xhtml', templateDir=os.path.split( os.path.abspath(__file__))[0]) def __init__(self, baseObject): super(MassPasswordChangePage, self).__init__() self.baseObject = baseObject def render_url(self, context, data): u = url.URL.fromContext(context) return context.tag(href=u.parentdir().child('search')) def childFactory(self, context, name): entry = inevow.ISession(context).getLoggedInRoot().loggedIn filt = uriUnquote(name) e = ldapsyntax.LDAPEntry(client=entry.client, dn=self.baseObject) d = e.search(filterText=filt, sizeLimit=20) d.addCallback(ReallyMassPasswordChangePage) return d render_i18n = i18n.render()
class LoginPage(rend.Page): """The resource that is returned when you are not logged in""" implements(iskin.ISkinnable) title = _('Login') docFactory = loaders.xmlfile( 'login.xhtml', templateDir=os.path.split(os.path.abspath(__file__))[0]) def __init__(self, history): self.history = history super(LoginPage, self).__init__() def locateChild(self, request, segments): return LoginPage(self.history + list(segments)), [] def render_form(self, context, data): current = url.URL.fromContext(context) action = getActionURL(current, self.history) context.fillSlots('action-url', str(action)) return context.tag render_i18n = i18n.render()
class MovePage(rend.Page): implements(iskin.ISkinnable) title = _('Ldaptor Move Page') addSlash = True docFactory = loaders.xmlfile('move.xhtml', templateDir=os.path.split( os.path.abspath(__file__))[0]) def render_url(self, ctx, data): u = url.URL.fromContext(ctx) return ctx.tag(href=u.parentdir().child('search')) def childFactory(self, context, name): dn = uriUnquote(name) session = inevow.ISession(context) userEntry = session.getLoggedInRoot().loggedIn move = session.getComponent(IMove) if move is None: move = [] session.setComponent(IMove, move) e = ldapsyntax.LDAPEntryWithClient(dn=dn, client=userEntry.client) move.append(e) u = url.URL.fromContext(context).sibling('search') return u render_i18n = i18n.render()
class ReallyMassPasswordChangePage(rend.Page): implements(iskin.ISkinnable) title = _('Ldaptor Mass Password Change Page') addSlash = True docFactory = loaders.xmlfile('mass_change_password-really.xhtml', templateDir=os.path.split( os.path.abspath(__file__))[0]) def __init__(self, entries): super(ReallyMassPasswordChangePage, self).__init__() self.entries = entries def data_header(self, ctx, data): u = url.URL.fromContext(ctx) u = u.parentdir().parentdir().clear() l = [] l.append(tags.a(href=u.sibling("search"))[_("Search")]) l.append(tags.a(href=u.sibling("add"))[_("add new entry")]) return l def configurable_(self, context): request = context.locate(inevow.IRequest) return MassPasswordChangeForm(self.entries) def render_form(self, context, data): return webform.renderForms()[context.tag] def render_passthrough(self, context, data): return context.tag.clear()[data] def render_status(self, context, data): try: obj = context.locate(inevow.IHand) except KeyError: return context.tag.clear() if not isinstance(obj, MassPasswordChangeStatus): return context.tag.clear()[obj] dl = tags.dl(compact="compact") context.tag.clear()[dl] for success, x in obj.deferlist: if success: entry, pwd = x dl[tags.dt[entry.dn], tags.dd[pwd]] else: context.tag[_('Failed: '), x.getErrorMessage()] return context.tag render_i18n = i18n.render()
class AddPage(rend.Page): implements(iskin.ISkinnable) title = _('Ldaptor Add Page') addSlash = True docFactory = loaders.xmlfile('add.xhtml', templateDir=os.path.split( os.path.abspath(__file__))[0]) def __init__(self, attributeTypes, objectClasses): super(AddPage, self).__init__() self.attributeTypes = attributeTypes self.objectClasses = objectClasses def listPlugins(self): for plug in plugin.getPlugIns('ldaptor.apps.webui.smartObject'): yield plug.name def havePlugins(self): for plug in plugin.getPlugIns('ldaptor.apps.webui.smartObject'): return True return False def getPlugin(self, name): for plug in plugin.getPlugIns('ldaptor.apps.webui.smartObject'): if plug.name == name: return plug raise KeyError, name def data_header(self, ctx, data): u = url.URL.fromContext(ctx) u = u.parentdir().clear() l = [] l.append(tags.a(href=u.sibling("search"))[_("Search")]) return l def configurable_objectClass(self, context): return AddOCForm(self.objectClasses) def render_objectClassForm(self, context, data): return webform.renderForms('objectClass') def configurable_smartObject(self, context): return ChooseSmartObject(self.listPlugins()) def render_smartObjectForm(self, context, data): if self.havePlugins(): return webform.renderForms('smartObject') else: return context.tag.clear() def render_passthrough(self, context, data): return context.tag.clear()[data] def locateChild(self, request, segments): ret = super(AddPage, self).locateChild(request, segments) if ret != rend.NotFound: return ret if segments[0] == 'manual': if not segments[1:]: return rend.NotFound path = segments[1] unquoted = uriUnquote(path) objectClasses = unquoted.split('+') assert len(objectClasses) >= 1 structName = objectClasses[0] structuralObjectClass = mapNameToObjectClass( self.objectClasses, structName) assert structuralObjectClass is not None, \ "objectClass %s must have schema"%structName auxiliaryObjectClasses = [] for auxName in objectClasses[1:]: oc = mapNameToObjectClass(self.objectClasses, auxName) assert oc is not None, "objectClass %s must have schema" % oc auxiliaryObjectClasses.append(oc) r = ManualAddPage(structuralObjectClass=structuralObjectClass, auxiliaryObjectClasses=auxiliaryObjectClasses, attributeTypes=self.attributeTypes, objectClasses=self.objectClasses) return r, segments[2:] elif segments[0] == 'smart': if not segments[1:]: return rend.NotFound name = segments[1] if not name: return rend.NotFound plug = self.getPlugin(name) module = plug.load() add = module.add() r = SmartObjectAddPage(add) return r, segments[2:] else: return rend.NotFound render_i18n = i18n.render()
class ReallyAddPage(rend.Page): implements(iskin.ISkinnable) title = _('Ldaptor Add Page') addSlash = True docFactory = loaders.xmlfile('add-really.xhtml', templateDir=os.path.split( os.path.abspath(__file__))[0]) def data_header(self, ctx, data): u = url.URL.fromContext(ctx) u = u.parentdir().parentdir().parentdir().clear() l = [] l.append(tags.a(href=u.sibling("search"))[_("Search")]) l.append(tags.a(href=u.sibling("add"))[_("add new entry")]) return l def render_form(self, context, data): return webform.renderForms() def render_passthrough(self, context, data): return context.tag.clear()[data] def render_status(self, context, data): try: obj = context.locate(inevow.IHand) except KeyError: return context.tag.clear() e = interfaces.ILDAPEntry(obj, None) if e is not None: status = AddStatus(entry=e) else: status = IAddStatus(obj, None) if status is None: return context.tag.clear()[obj] e = status.entry u = url.URL.fromContext(context) u = u.parentdir().parentdir().parentdir().clear() msg = [ _("Added "), tags.a(href=u.parentdir().child(e.dn).child("search"))[e.dn], ] if status.password is not None: msg.extend([_(' with password '), status.password]) return context.tag.clear( )[msg, ' ', # TODO share implementation with entryLinks '[', tags.a(href=u.sibling('edit').child(uriQuote(e.dn)))[_('edit')], '|', tags.a(href=u.sibling('move').child(uriQuote(e.dn)))[_('move')], '|', tags.a(href=u.sibling('delete').child(uriQuote(e.dn)))[_('delete')], '|', tags.a(href=u.sibling('change_password').child(uriQuote(e.dn)) )[_('change password')], ']', ] render_i18n = i18n.render()
class GetDN(rend.Page): implements(iskin.ISkinnable) title = _('Ldaptor Delete Page') addSlash = True docFactory = loaders.xmlfile( 'delete-nodn.xhtml', templateDir=os.path.split(os.path.abspath(__file__))[0]) def render_url(self, context, data): u = url.URL.fromContext(context) return context.tag(href=u.parentdir().child('search')) def childFactory(self, context, name): unquoted=uriUnquote(name) try: dn = distinguishedname.DistinguishedName(stringValue=unquoted) except distinguishedname.InvalidRelativeDistinguishedName, e: # TODO There's no way to throw a FormException at this stage. return None r=ConfirmDelete(dn=dn) return r render_i18n = i18n.render() def getResource(): return GetDN()
class ConfirmDelete(rend.Page): implements(iskin.ISkinnable) title = _('Ldaptor Delete Page') docFactory = loaders.xmlfile('delete.xhtml', templateDir=os.path.split( os.path.abspath(__file__))[0]) def __init__(self, dn): super(ConfirmDelete, self).__init__() self.dn = dn def getBindingNames(self, ctx): return ['delete'] def bind_delete(self, ctx): return annotate.MethodBinding( 'delete', annotate.Method(arguments=[ annotate.Argument('ctx', annotate.Context()), ], label=_('Confirm delete')), action=_('Delete')) def delete(self, ctx): request = inevow.IRequest(ctx) user = request.getSession().getLoggedInRoot().loggedIn e = ldapsyntax.LDAPEntry(client=user.client, dn=self.dn) d = e.delete() def cb(dummy): basedn = iwebui.ICurrentDN(ctx) while (basedn != '' and self.dn.contains(basedn)): basedn = basedn.up() u = url.URL.fromContext(ctx) u = u.parentdir().parentdir() if basedn != '': u = u.child(basedn).child('search') request.setComponent(iformless.IRedirectAfterPost, u) return _("Deleted %s.") % self.dn def eb(fail): return _("Failed: %s.") % fail.getErrorMessage() d.addCallbacks(cb, eb) return d def data_status(self, ctx, data): try: return ctx.locate(inevow.IStatusMessage) except KeyError: return None def render_if(self, context, data): r = context.tag.allPatterns(str(bool(data))) return context.tag.clear()[r] def data_entry(self, context, data): user = context.locate(inevow.ISession).getLoggedInRoot().loggedIn assert user entry = ldapsyntax.LDAPEntry(client=user.client, dn=self.dn) d = entry.fetch() d.addErrback(ErrorWrapper) return d def render_error_or_pass(self, context, data): if isinstance(data, ErrorWrapper): return context.tag.clear() \ [ tags.strong(style="color: red;") \ [ _('An error occurred: '), data.value.getErrorMessage(), ] ] else: return context.tag def data_dn(self, context, data): return self.dn def render_form(self, context, data): return webform.renderForms() def render_passthrough(self, context, data): return context.tag.clear()[data] def data_header(self, ctx, data): u = url.URL.fromContext(ctx).up().clear() l = [] l.append(tags.a(href=u.sibling("search"))[_("Search")]) l.append(tags.a(href=u.sibling("add"))[_("add new entry")]) l.append(tags.a(href=u.sibling("edit").child(str(self.dn)))[_("edit")]) return l def render_keyvalue(self, context, data): return weave.keyvalue(context, data) def render_keyvalue_item(self, context, data): return weave.keyvalue_item(context, data) render_i18n = i18n.render()
class GetDN(rend.Page): implements(iskin.ISkinnable) title = _('Ldaptor Delete Page') addSlash = True docFactory = loaders.xmlfile('delete-nodn.xhtml', templateDir=os.path.split( os.path.abspath(__file__))[0]) def render_url(self, context, data): u = url.URL.fromContext(context) return context.tag(href=u.parentdir().child('search')) def childFactory(self, context, name): unquoted = uriUnquote(name) try: dn = distinguishedname.DistinguishedName(stringValue=unquoted) except distinguishedname.InvalidRelativeDistinguishedName, e: # TODO There's no way to throw a FormException at this stage. return None r = ConfirmDelete(dn=dn) return r render_i18n = i18n.render() def getResource(): return GetDN()
class ConfirmChange(ServicePasswordChangeMixin, rend.Page): implements(iskin.ISkinnable) title = _('Ldaptor Password Change Page') addSlash = True docFactory = loaders.xmlfile('change_password.xhtml', templateDir=os.path.split( os.path.abspath(__file__))[0]) def getBindingNames(self, ctx): return ['setPassword', 'generateRandom'] def bind_setPassword(self, ctx): return annotate.MethodBinding( 'setPassword', annotate.Method(arguments=[ annotate.Argument('ctx', annotate.Context()), annotate.Argument( 'newPassword', annotate.PasswordEntry(required=True, label=_('New password'))), annotate.Argument( 'again', annotate.PasswordEntry(required=True, label=_('Again'))), ], label=_('Set password')), action=_('Set password')) def bind_generateRandom(self, ctx): return annotate.MethodBinding( 'generateRandom', annotate.Method(arguments=[ annotate.Argument('ctx', annotate.Context()), ], label=_('Generate random')), action=_('Generate random')) servicePasswordAction_10_remove = RemoveServicePassword servicePasswordAction_20_set = SetServicePassword servicePasswordAction_30_random = SetRandomServicePassword def _setPassword(self, ctx, password): e = getEntry(ctx, self.dn) d = defer.maybeDeferred(e.setPassword, newPasswd=password) return d def setPassword(self, ctx, newPassword, again): d = defer.maybeDeferred(checkPasswordTypos, newPassword, again) d.addCallback(lambda dummy: self._setPassword(ctx, newPassword)) d.addCallback(lambda dummy: _('Password set.')) def eb(fail): return _("Failed: %s") % fail.getErrorMessage() d.addErrback(eb) return d def generateRandom(self, ctx): d = generate_password.generate(reactor) def _first(passwords): assert len(passwords) == 1 return passwords[0] d.addCallback(_first) def _status(newPassword, ctx): d = self._setPassword(ctx, newPassword) d.addCallback(lambda dummy: _('Password set to %s') % newPassword) return d d.addCallback(_status, ctx) def eb(fail): return _("Failed: %s") % fail.getErrorMessage() d.addErrback(eb) return d def data_status(self, ctx, data): try: return ctx.locate(inevow.IStatusMessage) except KeyError: return '' def data_dn(self, ctx, data): return self.dn def render_form(self, ctx, data): return webform.renderForms() def render_passthrough(self, ctx, data): return ctx.tag.clear()[data] def data_header(self, ctx, data): u = url.URL.fromContext(ctx) u = u.parentdir().parentdir().clear() l = [] l.append(tags.a(href=u.sibling("search"))[_("Search")]) l.append(tags.a(href=u.sibling("add"))[_("add new entry")]) l.append(tags.a(href=u.sibling("edit").child(str(self.dn)))[_("edit")]) l.append( tags.a(href=u.sibling("delete").child(str(self.dn)))[_("delete")]) return l def render_add(self, ctx, data): return webform.renderForms('add') def configurable_add(self, ctx): return AddService(self.dn) render_i18n = i18n.render() def render_data(self, ctx, data): return ctx.tag.clear()[data]
class ServicePasswordChangeMixin(object): def __init__(self, dn): super(ServicePasswordChangeMixin, self).__init__() self.dn = dn def listServicePasswordActions(self): l = [(int(pri), name) for x, pri, name in [ name.split('_', 2) for name in dir(self) if name.startswith('servicePasswordAction_') ]] l.sort() for pri, name in l: yield name def getServicePasswordAction(self, name): for attrName in dir(self): if not attrName.startswith('servicePasswordAction_'): continue x, pri, actionName = attrName.split('_', 2) if actionName == name: return getattr(self, attrName) return None def render_servicePasswords(self, ctx, data): docFactory = loaders.xmlfile('change_service_passwords.xhtml', templateDir=os.path.split( os.path.abspath(__file__))[0]) r = inevow.IQ(docFactory).onePattern('main') return r def render_hideIfNot(self, ctx, data): if data: return ctx.tag else: return tags.invisible() def data_servicePasswords(self, ctx, data): user = ctx.locate(inevow.ISession).getLoggedInRoot().loggedIn config = interfaces.ILDAPConfig(ctx) e = ldapsyntax.LDAPEntry(client=user.client, dn=config.getBaseDN()) d = e.search(filterObject=pureldap.LDAPFilter_and([ pureldap.LDAPFilter_equalityMatch( attributeDesc=pureldap.LDAPAttributeDescription('objectClass'), assertionValue=pureldap.LDAPAssertionValue( 'serviceSecurityObject')), pureldap.LDAPFilter_equalityMatch( attributeDesc=pureldap.LDAPAttributeDescription('owner'), assertionValue=pureldap.LDAPAssertionValue(str(self.dn))), pureldap.LDAPFilter_present('cn'), ]), attributes=['cn']) return d def render_form_service(self, ctx, data): # TODO error messages for one password change form display in # all of them. e = inevow.IData(ctx) for name in self.listServicePasswordActions(): yield webform.renderForms('service_%s_%s' % (name, e.dn))[ctx.tag()] def locateConfigurable(self, ctx, name): try: return super(ServicePasswordChangeMixin, self).locateConfigurable(ctx, name) except AttributeError: if name.startswith('service_'): pass else: raise rest = name[len('service_'):] l = rest.split('_', 1) if len(l) != 2: raise AttributeError, name c = self.getServicePasswordAction(l[0]) if c is None: raise AttributeError, name return iformless.IConfigurable(c(l[1])) render_zebra = weave.zebra() render_i18n = i18n.render()