Example #1
0
class PropertyEditForm(LDAPEditForm):
    """An edit form for LDAP properties.
    """
    form_fields = FormFields(ILDAPPropertyConfiguration)
    label = _(u"Edit Property")
    description = _(u"Edit a LDAP property.")
    form_name = _(u"Configure property")
    fieldset = "schema"
Example #2
0
class ServerEditForm(LDAPEditForm):
    """An edit form for LDAP servers.
    """
    form_fields = FormFields(ILDAPServerConfiguration)
    label = _(u"Edit Server")
    description = _(u"Edit a LDAP or ActiveDirectory server.")
    form_name = _(u"Configure server")
    fieldset = "servers"
Example #3
0
class ILDAPPropertyConfiguration(Interface):
    description = TextLine(title=_(u"label_property_description",
                                   default=u"Property description"),
                           required=False)

    ldap_name = ASCIILine(
        title=_(u"label_ldap_property", default=u"LDAP property name"),
        description=_(u"help_ldap_property",
                      default=u"The name of the property as used in the "
                      "LDAP directory."),
        required=True)

    plone_name = ASCIILine(
        title=_(u"label_plone_property", default=u"Plone property name"),
        description=_(
            u"help_plone_property",
            default=u"The name of the property as used in the Plone site. "
            u"If no name is specified, the property will not be "
            u"visible in Plone but may still be used as the login "
            u"name, user id, or rDN."),
        required=False)

    multi_valued = Bool(
        title=_(u"label_multi_valued", default=u"Multi-valued property"),
        description=_(
            u"help_multi_valued",
            default=u"Select if this property can have multiple values."),
        required=True)

    binary = Bool(
        title=_(u"label_binary", default=u"Binary property"),
        description=_(
            u"help_binary",
            default=u"Select if this property can have binary values."),
        required=True)
Example #4
0
class PropertyAddForm(LDAPAddForm):
    """An add form for LDAP properties.
    """
    form_fields = FormFields(ILDAPPropertyConfiguration)
    label = _(u"Add Property")
    description = _(u"Add a LDAP property to the schema.")
    form_name = _(u"Configure property")
    fieldset = "schema"

    def create(self, data):
        property = LDAPProperty()
        applyChanges(property, self.form_fields, data)
        return property
Example #5
0
class ILDAPServerConfiguration(Interface):
    """Configuration of an LDAP server.
    """
    enabled = Bool(
            title=_(u"label_ldap_enabled",
                default=u"Active"),
            description=_(u"help_ldap_enabled",
                default=u"Use this LDAP server"),
            default=False,
            required=True)

    server = ASCIILine(
            title=_(u"label_ldap_server",
                default=u"Server"),
            description=_(u"help_ldap_server",
                default="The address or hostname of the LDAP server."),
            default="localhost",
            required=True)

    connection_type = Choice(
            title=_(u"label_ldap_connection_type",
                default=u"Connection type"),
            description=_(u"help_ldap_connection_type",
                default=u""),
            vocabulary="plone.app.ldap.engine.LDAPConnectionTypes",
            default=0,
            required=True)

    connection_timeout = Int(
            title=_(u"label_connection_timeout",
                default=u"Connection timeout"),
            description=_(u"help_connection_timeout",
                default=u"The timeout in seconds to wait for a connection to "
                "the LDAP server to be established."),
            default=5,
            min=-1,
            max=300,
            required=True)

    operation_timeout = Int(
            title=_(u"label_operation_timeout",
                default=u"Operation timeout"),
            description=_(u"help_operation_timeout",
                default=u"The timeout in seconds to wait for an operation such "
                "as a search or update to complete. If no timeout should be "
                "used use -1 as value."),
            default=-1,
            min=-1,
            max=300,
            required=True)
Example #6
0
class ServerAddForm(LDAPAddForm):
    """An add form for LDAP servers.
    """
    form_fields = FormFields(ILDAPServerConfiguration)
    label = _(u"Add Server")
    description = _(u"Add an new LDAP or ActiveDirectory server.")
    form_name = _(u"Configure server")
    fieldset = "servers"

    def create(self, data):
        server = LDAPServer()
        applyChanges(server, self.form_fields, data)
        notify(ObjectCreatedEvent(server))
        return server
Example #7
0
    def handle_edit_actions(self, action, data):
        # Filter out non-required fields that have no value so their
        # existing value is not overwritten. This protects us from
        # overwriting the bind password.
        data = dict([(key, value) for (key, value) in data.iteritems() if value is not None])
        if applyChanges(self.context, self.form_fields, data, self.adapters):
            try:
                notify(ObjectModifiedEvent(self.storage))
            except LDAPError, e:
                widget = self.widgets.get("bind_dn")

                widget.error = WidgetInputError("bind_dn", widget.label, LDAPBindFailure("value"))
                self.errors += (widget.error,)
                self.status = _("There were errors")
Example #8
0
class ILDAPConfiguration(ILDAPBinding):
    """LDAP configuration utility"""

    servers = Container(title=u"LDAP servers",
            description=u"List of LDAP servers that can be used.",
            required=True)

    schema = Container(title=u"LDAP schema",
            description=u"The LDAP schema contains information on used LDAP properties",
            required=True)

    activated_plugins = List(title=_(u"Activated plugins"),
            value_type=ASCIILine(
                title=u"interface",))
Example #9
0
    def handle_edit_actions(self, action, data):
        # Filter out non-required fields that have no value so their
        # existing value is not overwritten. This protects us from
        # overwriting the bind password.
        data = dict([(key, value) for (key, value) in data.iteritems()
                     if value is not None])
        if applyChanges(self.context, self.form_fields, data, self.adapters):
            try:
                notify(ObjectModifiedEvent(self.storage))
            except LDAPError:
                widget = self.widgets.get("bind_dn")

                widget.error = WidgetInputError("bind_dn", widget.label,
                                                LDAPBindFailure("value"))
                self.errors += (widget.error, )
                self.status = _("There were errors")
        return self.request.response.redirect(self.nextURL())
Example #10
0
        # Filter out non-required fields that have no value so their
        # existing value is not overwritten. This protects us from
        # overwriting the bind password.
        data = dict([(key, value) for (key, value) in data.iteritems() if value is not None])
        if applyChanges(self.context, self.form_fields, data, self.adapters):
            try:
                notify(ObjectModifiedEvent(self.storage))
            except LDAPError, e:
                widget = self.widgets.get("bind_dn")

                widget.error = WidgetInputError("bind_dn", widget.label, LDAPBindFailure("value"))
                self.errors += (widget.error,)
                self.status = _("There were errors")
        return self.request.response.redirect(self.nextURL())

    @action(_(u"label_enable", default=u"Enable"), name=u"EnableServer")
    def handle_enable_server(self, action, data):
        for id in self.request.form.get("serverId", []):
            if id in self.storage.servers:
                server = self.storage.servers[id]
                if server.enabled == False:
                    server.enabled = True
                    notify(ObjectModifiedEvent(server))
        return self.request.response.redirect(self.nextURL())

    @action(_(u"label_disable", default=u"Disable"), name=u"DisableServer")
    def handle_disable_server(self, action, data):
        for id in self.request.form.get("serverId", []):
            if id in self.storage.servers:
                server = self.storage.servers[id]
                if server.enabled == True:
Example #11
0
class ILDAPBinding(Interface):
    ldap_type = Choice(
        title=_(u"label_ldap_type", default=u"LDAP server type"),
        description=_(
            u"help_ldap_server_type",
            default=u"Plone supports both Active Directory and standard "
            u"LDAP servers. For Active Directory the read-only "
            u"LDAP interface which is enabled for all Active "
            u"Directory servers can be used."),
        vocabulary="plone.app.ldap.engine.LDAPServerTypes",
        default=u"LDAP",
        required=True)

    rdn_attribute = Choice(
        title=_(u"label_ldap_dn_attribute", default=u"rDN attribute"),
        description=_(u"help_ldap_dn_attribute",
                      default=u"This is attribute is used to build the "
                      u"distinguished name (DN) for users that are being "
                      u"created in your LDAP directory. This is commonly "
                      u"either the users full name ('cn' property) or the "
                      u"userid ('uid' property)."),
        default="uid",
        vocabulary="plone.app.ldap.engine.LDAPSingleValueAttributes",
        required=True)

    userid_attribute = Choice(
        title=_(u"label_ldap_userid_attribute", default=u"User id attribute"),
        description=_(
            u"help_ldap_userid_attribute",
            default=u"This attribute is used as the userid inside Plone "
            u"for LDAP users. It has to be unique for all users."),
        default="uid",
        vocabulary="plone.app.ldap.engine.LDAPSingleValueAttributes",
        required=True)

    login_attribute = Choice(
        title=_(u"label_ldap_login_attribute",
                default=u"Login name attribute"),
        description=_(
            u"help_ldap_login_attribute",
            default=u"The attribute is used as the login name for LDAP "
            u"users logging into your site. In most cases this "
            u"should be the same as the user id attribute."),
        default="uid",
        vocabulary="plone.app.ldap.engine.LDAPSingleValueAttributes",
        required=True)

    user_object_classes = ASCIILine(
        title=_(u"label_ldap_user_object_classes",
                default=u"LDAP object classes"),
        description=_(
            u"help_ldap_user_object_classes",
            default=u"Each object in the LDAP database has a structural "
            u"object class and optionally several supplemental "
            u"object classes. These classes define the required "
            u"and optional properties that can be present on an "
            u"object. Classes can be entered in a comma seperated "
            u"list."),
        default="pilotPerson",
        required=True)

    bind_dn = ASCIILine(
        title=_(u"label_ldap_bind_dn", default=u"Bind DN"),
        description=_(
            u"help_ldap_bind_dn",
            default=u"The DN of a manager account in the LDAP directory. "
            u"This must be allowed to access all user and group "
            u"information as well as be able to update and create "
            u"users and groups. Please note that Plone only "
            u"supports simple binds. SASL is not supported."),
        required=False)

    bind_password = Password(
        title=_(u"label_ldap_bind_password", default=u"Bind password"),
        description=_(
            u"help_ldap_bind_password",
            default=u"Password to use when binding to the LDAP server."),
        required=False)

    user_base = ASCIILine(
        title=_(u"label_ldap_user_base", default=u"Base DN for users"),
        description=_(
            u"help_ldap_user_base",
            default=u"This is the location in your LDAP directory where "
            u"all users are stored."),
        required=True)

    user_scope = Choice(
        title=_(u"label_ldap_user_scope", default=u"Search scope for users"),
        description=_(
            u"help_ldap_user_scope",
            default=u"The search scope determines where the LDAP server "
            u"will search for users. With \"one level\" it will "
            u"only look for users directly in the user base "
            u"location; \"subtree\" will allow the server to also "
            u"look in subfolders of the user base location."),
        default=SCOPE_SUBTREE,
        vocabulary="plone.app.ldap.engine.LDAPScopes",
        required=True)

    group_base = ASCIILine(
        title=_(u"label_ldap_group_base", default=u"Base DN for groups"),
        description=_(
            u"help_ldap_group_base",
            default=u"This is the location in your LDAP directory where "
            u"all groups are stored. There are several options for "
            u"object class and members possible: the groupOfNames, "
            u"accessGroup or group object classes can be used with "
            u"members given in the member property, or the "
            u"groupOfUniqueNames object class can be used with "
            u"uniqueMember property. In Active Directory systems "
            u"only the group object class is supported."),
        required=True)

    group_scope = Choice(
        title=_(u"label_ldap_group_scope", default=u"Search scope for groups"),
        description=_(
            u"help_ldap_group_scope",
            default=u"The search scope determines where the LDAP server "
            u"will search for groups. With \"one level\" it will "
            u"only look for groups directly in the group base "
            u"location; \"subtree\" will allow the server to also "
            u"look in subfolders of the group base location."),
        default=SCOPE_SUBTREE,
        vocabulary="plone.app.ldap.engine.LDAPScopes",
        required=True)

    password_encryption = Choice(
        title=_(u"label_ldap_user_password_encryption",
                default=u"User password encryption"),
        description=_(
            u"help_ldap_user_password_encryption",
            default=u"Method of encryption used for user passwords."),
        default="crypt",
        vocabulary="plone.app.ldap.engine.LDAPPasswordEncryption",
    )

    default_user_roles = ASCIILine(
        title=_(u"label_ldap_default_user_roles",
                default=u"Default user roles"),
        description=_(u"help_ldap_default_user_roles",
                      default=u"Default roles for new users."),
        default="Member",
        required=True,
    )

    read_only = Bool(
        title=_(u"label_ldap_read_only", default=u"Read Only"),
        description=_(
            u"help_ldap_read_only",
            default=u"Control whether Plone should attempt to modify "
            u"objects and properties on the server."),
        default=False,
    )
Example #12
0
        # overwriting the bind password.
        data = dict([(key,value) for (key,value) in data.iteritems() 
                        if value is not None])
        if applyChanges(self.context, self.form_fields, data, self.adapters):
            try:
                notify(ObjectModifiedEvent(self.storage))
            except LDAPError, e:
                widget=self.widgets.get("bind_dn")

                widget.error=WidgetInputError("bind_dn", widget.label,
                        LDAPBindFailure("value"))
                self.errors += (widget.error,)
                self.status= _("There were errors")
        return self.request.response.redirect(self.nextURL())

    @action(_(u'label_enable', default=u'Enable'), name=u'EnableServer')
    def handle_enable_server(self, action, data):
        for id in self.request.form.get("serverId", []):
            if id in self.storage.servers:
                server = self.storage.servers[id]
                if server.enabled == False:
                    server.enabled = True
                    notify(ObjectModifiedEvent(server))
        return self.request.response.redirect(self.nextURL())
    
    @action(_(u'label_disable', default=u'Disable'), name=u'DisableServer')
    def handle_disable_server(self, action, data):
        for id in self.request.form.get("serverId", []):
            if id in self.storage.servers:
                server = self.storage.servers[id]
                if server.enabled == True:
Example #13
0
class LDAPControlPanel(EditForm):
    template = ViewPageTemplateFile("controlpanel.pt")

    form_fields = FormFields(ILDAPBinding)
    label = u"LDAP Control Panel"
    description = u"In this control panel you can configure an LDAP connection. You can either use a standard LDAP server or a Microsoft Active Directory Server."
    form_name = u"LDAP Control Panel"

    @action(_("Apply"), condition=haveInputWidgets)
    def handle_edit_actions(self, action, data):
        # Filter out non-required fields that have no value so their
        # existing value is not overwritten. This protects us from
        # overwriting the bind password.
        data = dict([(key, value) for (key, value) in data.iteritems()
                     if value is not None])
        if applyChanges(self.context, self.form_fields, data, self.adapters):
            try:
                notify(ObjectModifiedEvent(self.storage))
            except LDAPError:
                widget = self.widgets.get("bind_dn")

                widget.error = WidgetInputError("bind_dn", widget.label,
                                                LDAPBindFailure("value"))
                self.errors += (widget.error, )
                self.status = _("There were errors")
        return self.request.response.redirect(self.nextURL())

    @action(_(u'label_enable', default=u'Enable'), name=u'EnableServer')
    def handle_enable_server(self, action, data):
        for id in self.request.form.get("serverId", []):
            if id in self.storage.servers:
                server = self.storage.servers[id]
                if server.enabled is False:
                    server.enabled = True
                    notify(ObjectModifiedEvent(server))
        return self.request.response.redirect(self.nextURL())

    @action(_(u'label_disable', default=u'Disable'), name=u'DisableServer')
    def handle_disable_server(self, action, data):
        for id in self.request.form.get("serverId", []):
            if id in self.storage.servers:
                server = self.storage.servers[id]
                if server.enabled is True:
                    server.enabled = False
                    notify(ObjectModifiedEvent(server))
        return self.request.response.redirect(self.nextURL())

    @action(_(u'label_delete', default=u'Delete'), name=u'DeleteServer')
    def handle_delete_server(self, action, data):
        for id in self.request.form.get("serverId", []):
            if id in self.storage.servers:
                notify(ObjectRemovedEvent(self.storage.servers[id]))
                del self.storage.servers[id]
        return self.request.response.redirect(self.nextURL())

    @action(_(u'label_delete_property', default=u'Delete'),
            name=u'DeleteProperty')
    def handle_delete_property(self, action, data):
        for id in self.request.form.get("propertyId", []):
            if id in self.storage.schema:
                notify(ObjectRemovedEvent(self.storage.schema[id]))
                del self.storage.schema[id]
        return self.request.response.redirect(self.nextURL())

    @action(_(u'label_purge', default=u'Purge'), name=u'Purge')
    def handle_cache_purge(self, action, data):
        luf = getLDAPPlugin()._getLDAPUserFolder()
        luf.manage_reinit()
        self.status = 'User caches cleared'
        return self.request.response.redirect(self.nextURL())

    @action(_(u'label_update_cache_timeouts',
              default=u'Update Cache Timeouts'),
            name=u'UpdateCacheTimeouts')
    def handle_update_cache_timeouts(self, action, data):
        luf = getLDAPPlugin()._getLDAPUserFolder()
        for cache_type, cache_value_name in [
            ('authenticated', 'auth_cache_seconds'),
            ('anonymous', 'anon_cache_seconds'),
            ('negative', 'negative_cache_seconds'),
        ]:
            cache_value = self.request.form['form.' + cache_value_name]
            try:
                cache_value = int(cache_value)
            except ValueError:
                continue
            if cache_value != getattr(self, cache_value_name, None):
                luf.setCacheTimeout(cache_type=cache_type, timeout=cache_value)
                self.status = 'Cache timeout changed'
        return self.request.response.redirect(self.nextURL())

    # cache properties delegate to the LDAPUserFolder instance
    def get_auth_cache_seconds(self):
        try:
            luf = getLDAPPlugin()._getLDAPUserFolder()
        except KeyError:
            return 600
        return luf.getCacheTimeout('authenticated')

    def set_auth_cache_seconds(self, value):
        luf = getLDAPPlugin()._getLDAPUserFolder()
        luf.setCacheTimeout(cache_type='authenticated', timeout=value)

    auth_cache_seconds = property(get_auth_cache_seconds,
                                  set_auth_cache_seconds)

    def get_anon_cache_seconds(self):
        try:
            luf = getLDAPPlugin()._getLDAPUserFolder()
        except KeyError:
            return 600
        return luf.getCacheTimeout('anonymous')

    def set_anon_cache_seconds(self, value):
        luf = getLDAPPlugin()._getLDAPUserFolder()
        luf.setCacheTimeout(cache_type='anonymous', timeout=value)

    anon_cache_seconds = property(get_anon_cache_seconds,
                                  set_anon_cache_seconds)

    def get_negative_cache_seconds(self):
        try:
            luf = getLDAPPlugin()._getLDAPUserFolder()
        except KeyError:
            return 600
        return luf.getCacheTimeout('negative')

    def set_negative_cache_seconds(self, value):
        luf = getLDAPPlugin()._getLDAPUserFolder()
        luf.setCacheTimeout(cache_type='negative', timeout=value)

    negative_cache_seconds = property(get_negative_cache_seconds,
                                      set_negative_cache_seconds)

    def anon_cache(self):
        try:
            luf = getLDAPPlugin()._getLDAPUserFolder()
        except KeyError:
            return []
        users = luf.getUsers(authenticated=0)
        for user in users:
            user.cache_type = 'anonymous'
        return users

    def auth_cache(self):
        try:
            luf = getLDAPPlugin()._getLDAPUserFolder()
        except KeyError:
            return []
        users = luf.getUsers(authenticated=1)
        for user in users:
            user.cache_type = 'authenticated'
        return users

    def nextURL(self):
        url = str(
            getMultiAdapter((self.context, self.request),
                            name=u"absolute_url"))
        return url + "/@@ldap-controlpanel#" + self.request.form.get(
            'fieldset_id', '')

    @property
    @memoize
    def storage(self):
        return getUtility(ILDAPConfiguration)

    def servers(self):
        def contype(c):
            if c == 0:
                return "LDAP"
            elif c == 1:
                return "LDAP over SSL"
            else:
                return "LDAP over IPC"

        return [
            dict(id=s.__name__,
                 enabled=s.enabled,
                 server=s.server,
                 connection_type=contype(s.connection_type),
                 connection_timeout=s.connection_timeout,
                 operation_timeout=s.operation_timeout)
            for s in self.storage.servers.values()
        ]

    def schema(self):
        storage = self.storage

        def protected(attr):
            return attr.__name__ in (storage.rdn_attribute,
                                     storage.userid_attribute,
                                     storage.login_attribute)

        return [
            dict(id=p.__name__,
                 description=p.description,
                 ldap_name=p.ldap_name,
                 plone_name=p.plone_name,
                 multi_valued=p.multi_valued,
                 binary=p.binary,
                 protected=protected(p)) for p in storage.schema.values()
        ]
Example #14
0
class LDAPBindFailure(ValidationError):
    __doc__ = _(u"LDAP server refused your credentials")