Example #1
0
 def test_parse_services(self):
     self.assertEquals(
         ('ikea:%22Stuff%22/Hello+There', 'service_id'),
         identifiers.parse(' Ikea :%22Stuff%22/Hello%20There '))
     self.assertEquals(('ikea:%22Stuff%22/Hello+There', 'service_id'),
                       identifiers.parse('ikea:"Stuff"/Hello+There'))
     self.assertEquals(('spotify:BOB', 'service_id'),
                       identifiers.parse('SPOTIFY:BOB'))
Example #2
0
def connect_email(handler):
    for identifier in handler.identifiers:
        identifier, identifier_type = identifiers.parse(identifier)
        if identifier_type != identifiers.EMAIL:
            continue
        _, team, user = identifiers.parse_service(identifier)
        handler.connect_service('email', team, user)
Example #3
0
def get_handler(identifier):
    """Returns an account handler for the given identifier."""
    if isinstance(identifier, AccountHandler):
        # Assume that account handlers have already been resolved before.
        return identifier
    # Parse and normalize the identifier.
    identifier_type = 'unknown'
    if isinstance(identifier, basestring):
        identifier, identifier_type = identifiers.parse(identifier)
    # Attempt to find a Roger account for the provided identifier.
    account = models.Account.resolve(identifier)
    if account:
        # First check if there is a static handler for the account.
        for identity in account.identifiers:
            cls = _static_handlers.get(identity.id())
            if cls:
                return cls.handler
        # Support custom handlers for specific statuses.
        if account.status in _status_handlers:
            return _status_handlers[account.status](account)
        # No special handling for this account.
        return AccountHandler(account)
    # Finally check if the identifier has a static handler.
    if identifier in _static_handlers:
        # Use a static handler for this identifier.
        return _static_handlers[identifier].handler
    # Give up.
    logging.info('Could not get a handler for "%s" (%s)', identifier, identifier_type)
    raise errors.ResourceNotFound('That account does not exist')
Example #4
0
 def change_identifier(self, old, new, notify_connect=True, primary=False):
     new, identifier_type = identifiers.parse(new)
     if not new:
         logging.warning('%r is invalid', new)
         raise errors.InvalidArgument('That identifier is not valid')
     if old not in self.identifiers:
         raise errors.ForbiddenAction('That identifier belongs to another account')
     if old == new:
         return
     # Get the service, team, resource from the new identifier.
     try:
         service, team, resource = identifiers.parse_service(new)
         new_team = not self.is_on_team(service, team)
     except:
         service, team, resource = (None, None, None)
         new_team = True
     identity, account = models.Identity.change(
             old, new, assert_account_key=self.account.key, primary=primary)
     if not identity:
         raise errors.AlreadyExists('That identifier is already in use')
     # Update in-memory instance to reflect reality.
     if account:
         self.account.populate(**account.to_dict())
     if self.account.is_activated and service == 'email' and new_team:
         # Connect the email "service" (if the user is not already on this domain).
         self.connect_service(service, team, resource, notify=notify_connect)
     # TODO: We should also disconnect service if the old identifier was a service.
     self._notify_account_change()
Example #5
0
 def add_identifier(self, identifier, notify_change=True, notify_connect=True, **kwargs):
     identifier, identifier_type = identifiers.parse(identifier)
     identity, account = models.Identity.add(identifier, self.account.key, **kwargs)
     if not identity:
         if self.has_identifier(identifier):
             # Just assume the identifier is already owned by the current account.
             return
         raise errors.AlreadyExists('That identifier is already in use')
     # Brazil can use two formats for one phone number.
     equivalent = self._get_alternate_identifier(identity.key.id())
     if equivalent:
         i, a = models.Identity.add(equivalent, self.account.key)
         if i and a:
             identity, account = i, a
         else:
             logging.warning('Failed to reserve %r (based on %r) for %d',
                             equivalent, identifier, self.account.key.id())
     # Update in-memory instance to reflect reality.
     self.account.populate(**account.to_dict())
     if identifier_type == identifiers.EMAIL and self.account.is_activated:
         # Connect the email "service".
         _, team, user = identifiers.parse_service(identifier)
         self.connect_service('email', team, user, notify=notify_connect)
     elif identifier_type == identifiers.SERVICE_ID:
         service, team, user = identifiers.parse_service(identifier)
         if service == 'fika':
             # fika.io "service" always gets connected.
             self.connect_service('fika', team, user, notify=notify_connect)
     if notify_change:
         self._notify_account_change()
Example #6
0
 def test_parse_username(self):
     self.assertEquals(('a', 'username'), identifiers.parse('a'))
     self.assertEquals(('ab', 'username'), identifiers.parse('ab'))
     self.assertEquals(('a1', 'username'), identifiers.parse('a1'))
     self.assertEquals(('a1b', 'username'), identifiers.parse('a1b'))
     self.assertEquals(('a1b0', 'username'), identifiers.parse('a1b0'))
     self.assertEquals(('a1b0', 'username'), identifiers.parse('a1B0'))
     self.assertEquals(('a_1b-0', 'username'), identifiers.parse('a_1B-0'))
     self.assertEquals(('a_1b-0', 'username'), identifiers.parse('a_1B-0 '))
     self.assertEquals(
         ('z1234567890z1234567890z1234567890z1234567890z1234567890',
          'username'),
         identifiers.parse(
             'z1234567890z1234567890z1234567890z1234567890z1234567890'))
Example #7
0
 def test_parse_account_id(self):
     self.assertEquals((1, 'account_id'), identifiers.parse(1))
     self.assertEquals((123, 'account_id'), identifiers.parse(123))
     self.assertEquals((1, 'account_id'), identifiers.parse('1'))
     self.assertEquals((111, 'account_id'), identifiers.parse('111'))
     self.assertEquals((111, 'account_id'), identifiers.parse(' 111'))
     self.assertEquals((111, 'account_id'), identifiers.parse(' 111'))
     self.assertEquals((111, 'account_id'), identifiers.parse('111 '))
     self.assertEquals((111, 'account_id'), identifiers.parse(' 111 '))
     self.assertEquals(
         (123456789012345678901234567890123456789012345678901234567890,
          'account_id'),
         identifiers.parse(
             '123456789012345678901234567890123456789012345678901234567890')
     )
Example #8
0
 def set_username(self, new_username):
     new_username, identifier_type = identifiers.parse(new_username)
     if identifier_type != identifiers.USERNAME:
         # A user may not use this endpoint to add a phone number/e-mail.
         raise errors.InvalidArgument('A valid username must be provided')
     # Switch out the old username if it exists, otherwise just add the new one.
     old_username = self.username
     if old_username and self.account.primary_set:
         self.change_identifier(old_username, new_username, primary=True)
     else:
         self.add_identifier(new_username, primary=True)
Example #9
0
def get_challenger(client, identifier, call=False):
    """
    Returns a handler for creating a challenge for the given identifier.
    """
    identifier, identifier_type = identifiers.parse(identifier)
    if identifier in config.DEMO_ACCOUNTS:
        # Demo accounts.
        return DummyChallenger(client, identifier)
    if identifier_type == identifiers.PHONE and call:
        return CallChallenger(client, identifier)
    challenger = _challengers.get(identifier_type)
    if not challenger:
        logging.warning('Failed to get a challenger for %r', identifier)
        raise errors.InvalidArgument('That identifier is not valid')
    return challenger(client, identifier)
Example #10
0
 def remove_identifier(self, identifier):
     if identifier not in self.identifiers:
         raise errors.ForbiddenAction('That identifier belongs to another account')
     if len(self.identifiers) < 2:
         raise errors.ForbiddenAction('Can not remove last identifier')
     account = models.Identity.release(identifier, assert_account_key=self.account.key)
     # Update in-memory instance to reflect reality.
     if account:
         self.account.populate(**account.to_dict())
     # Disconnect service if the identifier is a service identifier.
     identifier, identifier_type = identifiers.parse(identifier)
     if identifier_type in (identifiers.EMAIL, identifiers.SERVICE_ID):
         service, team, resource = identifiers.parse_service(identifier)
         self.disconnect_service(service, team, resource)
     self._notify_account_change()
Example #11
0
 def parse(cls, value):
     if not isinstance(value, basestring):
         raise TypeError('Destination value must be a string')
     destination = cls()
     # Value is a comma separated list of routes.
     for route in value.split(','):
         # Route can contain a label prefix (with a colon to separate it).
         label_and_route = route.split(':', 1)
         if len(label_and_route) == 1:
             label = None
             route = label_and_route[0]
         else:
             label = re.sub(r'[\W_]', '', label_and_route[0].lower())
             route = label_and_route[1]
         # Clean up route and get its type.
         route, route_type = identifiers.parse(route)
         destination.add_route(route_type, route, label)
     return destination
Example #12
0
 def test_parse_email(self):
     self.assertEquals(('email:example.com/niceandsimple', 'email'),
                       identifiers.parse('*****@*****.**'))
     self.assertEquals(('email:example.com/very.common', 'email'),
                       identifiers.parse('*****@*****.**'))
     self.assertEquals(
         ('email:dept.example.com/a.little.lengthy.but.fine', 'email'),
         identifiers.parse('*****@*****.**'))
     self.assertEquals(
         ('email:example.com/disposable.style.email.with%2Bsymbol',
          'email'),
         identifiers.parse(
             '*****@*****.**'))
     self.assertEquals(
         ('email:example.com/other.email-with-dash', 'email'),
         identifiers.parse('*****@*****.**'))
     self.assertEquals(
         ('email:example.com/%22much.moreunusual%22', 'email'),
         identifiers.parse('"much.more unusual"@example.com'))
     self.assertEquals(
         ('email:example.com/%22very.unusual.%40.unusual.com%22', 'email'),
         identifiers.parse('"*****@*****.**"@example.com'))
     self.assertEquals(
         ('email:strange.example.com/%22very.%28%29%2C%3A%3B%3C%3E%5B%5D%22.very.%22very%40%5C%22very%22.unusual%22',
          'email'),
         identifiers.parse(
             '"very.(),:;<>[]\".VERY.\"very@\\ \"very\".unusual"@strange.example.com'
         ))
     self.assertEquals((
         'email:example.org/%21%23%24%25%26%27%2A%2B-%2F%3D%3F%5E_%60%7B%7D%7C%7E',
         'email'), identifiers.parse('!#$%&\'*+-/=?^_`{}|[email protected]'))
     self.assertEquals(
         ('email:example.org/%22%28%29%3C%3E%5B%5D%3A%2C%3B%40%5C%22%21%23%24%25%26%27%2A%2B-%2F%3D%3F%5E_%60%7B%7D%7C%7E.a%22',
          'email'),
         identifiers.parse(
             '"()<>[]:,;@\\\"!#$%&\'*+-/=?^_`{}| ~.a"@example.org'))
     self.assertEquals(('email:example.org/%22%22', 'email'),
                       identifiers.parse('" "@example.org'))
     self.assertEquals(
         ('email:example.com/%C3%BC%C3%B1%C3%AE%C3%A7%C3%B8%C3%B0%C3%A9',
          'email'), identifiers.parse('üñîçøðé@example.com'))
     self.assertEquals((
         'email:%C3%BC%C3%B1%C3%AE%C3%A7%C3%B8%C3%B0%C3%A9.com/%C3%BC%C3%B1%C3%AE%C3%A7%C3%B8%C3%B0%C3%A9',
         'email'), identifiers.parse('üñîçøðé@üñîçøðé.com'))
     self.assertEquals(('email:b.c/a', 'email'), identifiers.parse('[email protected]'))
     self.assertEquals(('email:2.3/1', 'email'), identifiers.parse('[email protected]'))
     self.assertEquals(('email:b.c/a', 'email'),
                       identifiers.parse(' [email protected] '))
     self.assertEquals(('email:b.c/a', 'email'),
                       identifiers.parse(' [email protected] '))
     self.assertEquals(('email:b.com/a%2B1', 'email'),
                       identifiers.parse('*****@*****.**'))
     self.assertEquals(
         ('email:weird-long-host.com.br/this-is-a-really-long-email-with%2Bfilters',
          'email'),
         identifiers.parse(
             '*****@*****.**'
         ))
Example #13
0
 def test_parse_channel(self):
     self.assertEquals(('#yolo', 'channel'), identifiers.parse('#yolo'))
     self.assertEquals(('#123', 'channel'), identifiers.parse('#123'))
     self.assertEquals(('#2pac', 'channel'), identifiers.parse('#2pac'))
     self.assertEquals(('#pac2', 'channel'), identifiers.parse('#pac2'))
     self.assertEquals(('#2', 'channel'), identifiers.parse('#2'))
     self.assertEquals(('#a', 'channel'), identifiers.parse('#a'))
     self.assertEquals(('#+123', 'channel'), identifiers.parse('#+123'))
     self.assertEquals(('#+1239415487', 'channel'),
                       identifiers.parse('#+1239415487'))
     self.assertEquals(('#[email protected]', 'channel'),
                       identifiers.parse('#[email protected]'))
     self.assertEquals(('#✂✒✏', 'channel'), identifiers.parse('#✂✒✏'))
     self.assertEquals(('#@!-k', 'channel'), identifiers.parse('#@!-k'))
     self.assertEquals(('#阿里巴巴集团', 'channel'), identifiers.parse('#阿里巴巴集团'))
     self.assertEquals(('#❤💔💗💓💕💖💞💘💌💋💍💎👤👥💬👣💭', 'channel'),
                       identifiers.parse('#❤💔💗💓💕💖💞💘💌💋💍💎👤👥💬👣💭'))
Example #14
0
 def test_parse_phone(self):
     self.assertEquals(('+123456', 'phone'), identifiers.parse('+123456'))
     self.assertEquals(('+123456', 'phone'),
                       identifiers.parse('+1 2 3 4 5 6'))
     self.assertEquals(('+1234567890', 'phone'),
                       identifiers.parse('+1 (234) 56-7890'))
     self.assertEquals(('+123456789012345678901234567890', 'phone'),
                       identifiers.parse('+123456789012345678901234567890'))
     self.assertEquals(
         ('+123456789012345678901234567890', 'phone'),
         identifiers.parse('+1 (234) 56-789012345678901234567890'))
     self.assertEquals(('+123456', 'phone'),
                       identifiers.parse('+123456abc'))
     self.assertEquals(('+123456', 'phone'),
                       identifiers.parse('+123abc456'))
     self.assertEquals(('+1239415487', 'phone'),
                       identifiers.parse('++1239415487'))
     self.assertEquals(('+1239415487', 'phone'),
                       identifiers.parse('+#1239415487'))
     self.assertEquals(('+1239415487', 'phone'),
                       identifiers.parse('+@1239415487'))
     self.assertEquals(('+123456', 'phone'),
                       identifiers.parse('*****@*****.**'))
     self.assertEquals(('+123456', 'phone'),
                       identifiers.parse('+✂1✒2✏3 4 56 '))
     self.assertEquals(('+123456', 'phone'),
                       identifiers.parse('+12@34!5-6k'))
     self.assertEquals(('+123456', 'phone'),
                       identifiers.parse('+阿里123456巴巴集团'))
     self.assertEquals(('+123456', 'phone'),
                       identifiers.parse('+❤1💔2💗3💓4💕5💖6💞💘💌💋💍💎👤👥💬👣💭'))
Example #15
0
 def test_parse_email_service(self):
     self.assertEquals(('email:b.c/a', 'email'),
                       identifiers.parse(' email:B.C/A '))
     self.assertEquals(('email:b.c/a%2Bb%2Bxyz', 'email'),
                       identifiers.parse(' email:B.C/A%2Bb%2BXYZ '))