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()
Exemple #2
0
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()
Exemple #3
0
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()
Exemple #5
0
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()
Exemple #6
0
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()
Exemple #7
0
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()
Exemple #8
0
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()
Exemple #9
0
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()
Exemple #10
0
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]
Exemple #11
0
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()