Verify authentication.

            Returns True/False dependant on whether the authentication
            succeeded or not.

def authenticate(self):
        """ Verify authentication.

            Returns True/False dependant on whether the authentication
            succeeded or not.
        """

        # if authentication has been performed, return last result
        if self._authenticated is not None:
            return self._authenticated

        try:
            self._ldap_conn.simple_bind_s(self._ldap_binddn_fmt.format(ldap.dn.escape_dn_chars(self.username)), self.password)
        except ldap.SERVER_DOWN as exc:
            raise AuthError('Could not connect to LDAP server')
        except (ldap.INVALID_CREDENTIALS, ldap.INVALID_DN_SYNTAX,
                ldap.UNWILLING_TO_PERFORM) as exc:
            # Auth failed
            self._logger.debug('erroneous password for user %s' % self.username)
            self._authenticated = False
            return self._authenticated


        # auth succeeded
        self.authenticated_as = self.username
        self.trusted = False
        self.readonly = False

        try:
            # Create separate connection for search?
            if self._ldap_search_conn is not None:
                self._ldap_search_conn.simple_bind(self._ldap_search_binddn, self._ldap_search_password)
                search_conn = self._ldap_search_conn
            else:
                search_conn = self._ldap_conn

            res = search_conn.search_s(self._ldap_basedn, ldap.SCOPE_SUBTREE, self._ldap_search.format(ldap.dn.escape_dn_chars(self.username)), ['cn','memberOf'])
            if res[0][1]['cn'][0] is not None:
                self.full_name = res[0][1]['cn'][0].decode('utf-8')
            # check for ro_group membership if ro_group is configured
            if self._ldap_ro_group:
                if self._ldap_ro_group in res[0][1].get('memberOf', []):
                    self.readonly = True
            # check for rw_group membership if rw_group is configured
            if self._ldap_rw_group:
                if self._ldap_rw_group in res[0][1].get('memberOf', []):
                    self.readonly = False
                else:
                    # if ro_group is configured, and the user is a member of
                    # neither the ro_group nor the rw_group, fail authentication.
                    if self._ldap_ro_group:
                        if self._ldap_ro_group not in res[0][1].get('memberOf', []):
                            self._authenticated = False
                            return self._authenticated
                    else:
                        self.readonly = True

        except ldap.LDAPError as exc:
            raise AuthError(exc)
        except KeyError:
            raise AuthError('LDAP attribute missing')
        except IndexError:
            self.full_name = ''
            # authentication fails if either ro_group or rw_group are configured
            # and the user is not found.
            if self._ldap_rw_group or self._ldap_ro_group:
                self._authenticated = False
                return self._authenticated

        self._authenticated = True

        self._logger.debug('successfully authenticated as %s, username %s, full_name %s, readonly %s' % (self.authenticated_as, self.username, self.full_name, str(self.readonly)))
        return self._authenticated