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()
def join_service_content(self, service_content_id, autocreate=True, **kwargs): # Variable name should stay "service_content_id" to prevent duplicate in kwargs. try: service, team, resource = identifiers.parse_service( service_content_id) content_id = identifiers.build_service(service, team, resource) except: raise errors.InvalidArgument('Invalid service identifier') q = models.Stream.query(models.Stream.service_content_id == content_id) stream = q.get() if not stream: if not autocreate: raise errors.ResourceNotFound('Cannot join that stream') handler = self.get_or_create([], service_content_id=content_id, **kwargs) logging.debug('Created stream for %s (%r)', content_id, handler.title) return handler handler = Stream(stream).join(self.account, do_not_bump=True) if 'title' in kwargs and handler.title != kwargs['title']: handler.set_title(kwargs['title']) if not handler.visible: handler.show() logging.debug('Joined stream for %s (%r)', content_id, handler.title) members = kwargs.get('service_members') if members and set(handler.service_members) != set(members): handler._stream.service_members = members handler._stream.put() logging.debug('Updated member list of %s (%r)', content_id, handler.title) return handler
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)
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()
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()