コード例 #1
0
    def group_invite_user(self, inviter, group, email, timeout=3):
        """ This method sets up an event that will allow a user to join a
        group. 

        @type inviter: self.account_class
        @param inviter: The account that is setting up the invitation

        @type group: self.group_class
        @param group_name: The group that should be joined

        @type email: str
        @param : The email adrress of the user that is invited

        @type timeout: int
        @param timeout: The number of days until the confirmation key expires.

        @rtype: dict
        @return: A dictionary with the following keys:
                'confirmation_key': <str> The code that is used to confirm the invitation
                'match_user': <str> A username, if a user exists with that email-address
                'match_user_email': An e-mailaddress. Not sure why?
        """
        ac = self.account_class(self.db)

        assert hasattr(inviter, 'entity_id')
        assert hasattr(group, 'entity_id')

        timeout = DateTimeDelta(int(timeout))
        if timeout.day < 1:
            raise CerebrumError('Timeout too short (%d)' % timeout.day)
        if (timeout > cereconf.MAX_INVITE_PERIOD):
            raise CerebrumError("Timeout too long (%d)" % timeout.day)

        ret = {'confirmation_key': self.vhutils.setup_event_request(
                                       group.entity_id,
                                       self.co.va_group_invitation,
                                       params={'inviter_id': inviter.entity_id,
                                               'group_id': group.entity_id,
                                               'invitee_mail': email,
                                               'timeout': timeout.day,},
                                       change_by=inviter.entity_id)}

        # check if e-mail matches a valid username
        try:
            ac.find_by_name(email)
            ret['match_user'] = ac.account_name
            if ac.np_type in (self.co.fedaccount_type, self.co.virtaccount_type):
                ret['match_user_email'] = ac.get_email_address()
        except NotFoundError:
            pass

        return ret
コード例 #2
0
ファイル: base.py プロジェクト: Narvik-kommune/cerebrum
    def group_create(self, group_name, description, creator, owner, url=None, forward=None):
        """ This method creates a new VirtHome group.
        NOTE: Some group name formats are reserved for specific applications!
        This method WILL allow creation of reserved group names.

        @type group_name: str
        @param group_name: The name of the new group

        @type description: str
        @param description: The group description

        @type creator: self.account_class
        @param creator: The account object of the creator of this group.

        @type owner: self.account_class
        @param owner: The account object of the owner of this group.

        @type url: str
        @param url: A url resource associated with the group

        @type forward: str
        @param forward: A url resource to an external app that uses this group
        """
        gr = self.group_class(self.db)

        if self.vhutils.group_exists(group_name):
            raise CerebrumError("Group name '%s' already exists" % group_name)

        # TBD: Verify owner.np_type is FEDaccount? Must it be?

        try:
            gr.populate(creator.entity_id, group_name, description)
            gr.write_db()
            gr.set_group_resource(url)
        except (ValueError, AssertionError):
            raise CerebrumError(str(sys.exc_info()[1]))

        forward = self.vhutils.whitelist_url(forward)
        if forward:
            gr.populate_trait(self.co.trait_group_forward, strval=forward)

        for spread in getattr(cereconf, "BOFHD_NEW_GROUP_SPREADS", ()):
            gr.add_spread(self.co.human2constant(spread, self.co.Spread))

        gr.write_db()
        roles = GroupRoles(self.db)
        roles.add_admin_to_group(owner.entity_id, gr.entity_id)
        return gr
コード例 #3
0
 def wrapper(self, *args, **kwargs):
     if not getattr(self, 'operator_id', None):
         if hasattr(self, 'log'):
             self.log.debug('Method (%s) requires operator_id',
                            method.__name__)
         raise CerebrumError('%s requires login' % method.__name__)
     return method(self, *args, **kwargs)
コード例 #4
0
 def get_const(self, const_str, const_type):
     """ Wrap h2c with caching, and raise error if not found. """
     if not hasattr(self, '_co_cache'):
         self._co_cache = dict()
     if (const_str, const_type) in self._co_cache:
         return self._co_cache[(const_str, const_type)]
     const = self.co.human2constant(const_str, const_type)
     if const:
         return self._co_cache.setdefault((const_str, const_type), const)
     raise CerebrumError("No constant '%s' of type '%s'" %
                         (const_str, const_type))
コード例 #5
0
    def __get_const(self, const_type, value):
        u""" A human2constant that accepts Constants as input.

        :raises CerebrumError:
            If the constant doesn't exist.
        """
        if isinstance(value, const_type):
            const = value
        else:
            const = self.co.human2constant(value, const_type=const_type)
        if const is None:
            raise CerebrumError('No {!r} code {!r}'.format(const_type, value))
        return const
コード例 #6
0
    def set_auth_data(self, auth_method, auth_data):
        """Register new auth data of the specified type.

        If the entity had an entry for that auth type, it's silently
        overwritten with auth_data.

        If auth_data is None, the corresponding entry (i.e. the proper
        auth_method's row for self) will be removed. IOW this method can be
        used to delete authentication data.
        """

        binds = {
            "entity_id": self.entity_id,
            "auth_method": int(auth_method),
            "auth_data": auth_data
        }

        if not self.validate_auth_data(auth_method, auth_data):
            raise CerebrumError(
                "Invalid auth_data '%s' for auth_method %s" %
                (auth_data, str(self.const.EntityAuthentication(auth_method))))

        if auth_data is None:
            self.execute(
                """
            DELETE FROM [:table schema=cererbum name=entity_authentication_info]
            WHERE entity_id = :entity_id AND
                  auth_method = :auth_method
            """, binds)
            return

        auth_in_db = self.get_auth_data(auth_method)
        if not auth_in_db:
            self.execute(
                """
            INSERT INTO [:table schema=cererbum name=entity_authentication_info]
            VALUES (:entity_id, :auth_method, :auth_data)
            """, binds)
        elif auth_in_db != auth_data:
            self.execute(
                """
            UPDATE [:table schema=cererbum name=entity_authentication_info]
            SET auth_data = :auth_data
            WHERE entity_id = :entity_id AND
                  auth_method = :auth_method
            """, binds)
コード例 #7
0
    def create_account(self, account_type, account_name, email, expire_date,
            human_first_name, human_last_name, with_confirmation=True):
        """Create an account of the specified type.

        This is a convenience function to avoid duplicating some of the work.

        @type account_type: subclass of BaseVirtHomeAccount
        @param account_type: The account class type to use.

        @type account_name: str
        @param account_name: Account name to give the new account

        @type email: str
        @param email: The email address of the account owner

        @type expire_date: mx.DateTime.DateTime
        @param expire_date: The expire date for the account

        @type human_first_name: str
        @param human_first_name: The first name(s) of the account owner

        @type human_last_name: str
        @param human_last_name: The last name(s) of the account owner

        @type with_confirmation: bool
        @param with_confirmation: Controls whether a confirmation request
                                  should be issued for this account. In some
                                  situations it makes no sense to confirm
                                  anything.
                                  NOTE: The caller must dispatch any
                                  confirmation mail. This controls whether a
                                  confirmation event/code should be created and
                                  returned.
        @rtype: list [ BaseVirtHomeAccount, str ]
        @return: The newly created account, and the confirmation key needed to
                 confirm the given email address. 
                 NOTE: If with_confirmation was False, the confirmation key
                 will be empty.
        """

        assert issubclass(account_type, BaseVirtHomeAccount)

        # Creation can still fail later, but hopefully this captures most
        # situations and produces a sensible account_name.
        if self.account_exists(account_name):
            raise CerebrumError("Account '%s' already exists" % account_name)

        account = account_type(self.db)
        account.populate(email, account_name, human_first_name,
                human_last_name, expire_date)
        account.write_db()
        account.populate_trait(self.co.trait_user_retained, numval=0) # Never exported to ldap
        account.write_db()

        self.assign_default_user_spreads(account)

        magic_key = ""
        if with_confirmation:
            magic_key = self.setup_event_request(account.entity_id, self.co.va_pending_create)

        return account, magic_key
コード例 #8
0
 def test_error(self):
     raise CerebrumError('test')
コード例 #9
0
def write_mail_dns():
    """ Gather data and dump to ldif. """
    logger = Factory.get_logger('cronjob')

    hosts, cnames, lower2host, hosts_only_mx = get_hosts_and_cnames()

    # email domains (lowercase -> domain), in alphabetical order
    domains = OrderedDict((d.lower(), d) for d in sorted(get_email_domains()))

    domain_wo_mx = set()
    for domain in domains:
        # Verify that domains have an MX-record.
        for arg in cereconf.LDAP_MAIL_DNS['dig_args']:
            zone = arg[0]
            if domain.endswith(zone) and not (domain in hosts_only_mx
                                              or domain in hosts):
                logger.error("email domain without MX defined: %s" % domain)
                domain_wo_mx.add(domain.lower())
        # Valid email domains only requires MX
        if domain in hosts_only_mx:
            hosts_only_mx.remove(domain)

    for host in hosts_only_mx:
        logger.warn(
            "MX defined but no A/AAAA record or valid email domain: %s" % host)

    if domain_wo_mx:
        cause = "{0:d} email domains without mx".format(len(domain_wo_mx))
        logger.error("{0}, this must be rectified manually!".format(cause))
        raise CerebrumError(cause)

    def handle_domain_host(entry, host):
        entry["host"] = (lower2host[host], )
        for cname in hosts[host]:
            if cname not in domains:
                entry["cn"].add(lower2host[cname])
                del cnames[cname]
        del hosts[host]

    lw = LDIFutils.LDIFWriter('MAIL_DNS', filename=None)
    dn_suffix = lw.getconf('dn')
    lw.write_container()

    for domain, output in domains.items():
        dn = "cn=%s,%s" % (output, dn_suffix)
        entry = {"cn": set((output, )), "objectClass": ("uioHost", )}
        try:
            if domain in cnames:
                # This fails `if domain not in hosts`
                entry["cn"].add(lower2host[cnames[domain]])
                handle_domain_host(entry, cnames[domain])
            elif domain in hosts:
                handle_domain_host(entry, domain)
        except Exception:
            logger.error(
                "domain=%r, cnames[domain]=%r, "
                "in hosts=%r, in cnames=%r", domain, cnames.get(domain), domain
                in hosts, domain in cnames)
            raise
        lw.write_entry(dn, entry)

    for host in sorted(hosts.keys()):
        l2h = lower2host[host]
        names = set(lower2host[cname] for cname in hosts[host])
        names.add(l2h)
        lw.write_entry("host=%s,%s" % (l2h, dn_suffix), {
            "host": (l2h, ),
            "cn": names,
            "objectClass": ("uioHost", )
        })

    lw.close()