def test_user_with_email_exists(self): api = UserApi(None) u = api.create_user() api.update(u, 'bibi', 'bibi@bibi', True) transaction.commit() eq_(True, api.user_with_email_exists('bibi@bibi')) eq_(False, api.user_with_email_exists('unknown'))
def post( self, name: str, email: str, password: str, is_tracim_manager: str = 'off', is_tracim_admin: str = 'off', send_email: str = 'off', ): is_tracim_manager = h.on_off_to_boolean(is_tracim_manager) is_tracim_admin = h.on_off_to_boolean(is_tracim_admin) send_email = h.on_off_to_boolean(send_email) current_user = tmpl_context.current_user if current_user.profile.id < Group.TIM_ADMIN: # A manager can't give large rights is_tracim_manager = False is_tracim_admin = False api = UserApi(current_user) if api.user_with_email_exists(email): tg.flash( _('A user with email address "{}" already exists.').format( email), CST.STATUS_ERROR) tg.redirect(self.url()) user = api.create_user() user.email = email user.display_name = name if password: user.password = password elif send_email: # Setup a random password to send email at user password = self.generate_password() user.password = password user.webdav_left_digest_response_hash = '%s:/:%s' % (email, password) api.save(user) # Now add the user to related groups group_api = GroupApi(current_user) user.groups.append(group_api.get_one(Group.TIM_USER)) if is_tracim_manager: user.groups.append(group_api.get_one(Group.TIM_MANAGER)) if is_tracim_admin: user.groups.append(group_api.get_one(Group.TIM_ADMIN)) api.save(user) if send_email: email_manager = get_email_manager() email_manager.notify_created_account(user, password=password) api.execute_created_user_actions(user) tg.flash( _('User {} created.').format(user.get_display_name()), CST.STATUS_OK) tg.redirect(self.url())
def post( self, name: str, email: str, password: str, is_tracim_manager: str='off', is_tracim_admin: str='off', send_email: str='off', ): is_tracim_manager = h.on_off_to_boolean(is_tracim_manager) is_tracim_admin = h.on_off_to_boolean(is_tracim_admin) send_email = h.on_off_to_boolean(send_email) current_user = tmpl_context.current_user if current_user.profile.id < Group.TIM_ADMIN: # A manager can't give large rights is_tracim_manager = False is_tracim_admin = False api = UserApi(current_user) if api.user_with_email_exists(email): tg.flash(_('A user with email address "{}" already exists.').format(email), CST.STATUS_ERROR) tg.redirect(self.url()) user = api.create_user() user.email = email user.display_name = name if password: user.password = password elif send_email: # Setup a random password to send email at user password = str(uuid.uuid4()) user.password = password user.webdav_left_digest_response_hash = '%s:/:%s' % (email, password) api.save(user) # Now add the user to related groups group_api = GroupApi(current_user) user.groups.append(group_api.get_one(Group.TIM_USER)) if is_tracim_manager: user.groups.append(group_api.get_one(Group.TIM_MANAGER)) if is_tracim_admin: user.groups.append(group_api.get_one(Group.TIM_ADMIN)) api.save(user) if send_email: email_manager = get_email_manager() email_manager.notify_created_account(user, password=password) tg.flash(_('User {} created.').format(user.get_display_name()), CST.STATUS_OK) tg.redirect(self.url())
def post(self, name, email, password, is_tracim_manager='off', is_tracim_admin='off'): is_tracim_manager = h.on_off_to_boolean(is_tracim_manager) is_tracim_admin = h.on_off_to_boolean(is_tracim_admin) current_user = tmpl_context.current_user if current_user.profile.id < Group.TIM_ADMIN: # A manager can't give large rights is_tracim_manager = False is_tracim_admin = False api = UserApi(current_user) if api.user_with_email_exists(email): tg.flash(_('A user with email address "{}" already exists.').format(email), CST.STATUS_ERROR) tg.redirect(self.url()) user = api.create_user() user.email = email user.display_name = name if password: user.password = password api.save(user) # Now add the user to related groups group_api = GroupApi(current_user) user.groups.append(group_api.get_one(Group.TIM_USER)) if is_tracim_manager: user.groups.append(group_api.get_one(Group.TIM_MANAGER)) if is_tracim_admin: user.groups.append(group_api.get_one(Group.TIM_ADMIN)) api.save(user) tg.flash(_('User {} created.').format(user.get_display_name()), CST.STATUS_OK) tg.redirect(self.url())
class LDAPSearchAuthenticatorPlugin(BaseLDAPSearchAuthenticatorPlugin): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self._auth = None self._user_api = UserApi(None) def set_auth(self, auth): self._auth = auth def authenticate(self, environ, identity, allow_auth_token: bool=False): # Note: super().authenticate return None if already authenticated or not found email = super().authenticate(environ, identity) if email: self._sync_ldap_user(email, environ, identity) if not email and allow_auth_token and self.user_exist(email): # Proceed to internal token auth user = self.sa_auth.dbsession.query(self.sa_auth.user_class).filter( and_( self.sa_auth.user_class.is_active == True, self.sa_auth.user_class.email == identity['login'] ) ).first() if user: user.ensure_auth_token() if user.auth_token == identity['password']: email = identity['login'] return email def _sync_ldap_user(self, email, environ, identity): # Create or get user for connected email if not self._user_api.user_with_email_exists(email): user = User(email=email, imported_from=LDAPAuth.name) DBSession.add(user) else: user = self._user_api.get_one_by_email(email) # Retrieve ldap user attributes self._auth.ldap_user_provider.add_metadata_for_auth(environ, identity) # Update user with ldap attributes user_ldap_values = identity.get('user').copy() for field_name in user_ldap_values: setattr(user, field_name, user_ldap_values[field_name]) DBSession.flush() transaction.commit() def user_exist(self, email): with make_connection(self.url, self.bind_dn, self.bind_pass) as conn: if self.start_tls: conn.start_tls() if not conn.bind(): return False search = self.search_pattern % email conn.search(self.base_dn, search, self.search_scope) if len(conn.response) > 0: return True return False
class UserCommand(AppContextCommand): ACTION_CREATE = 'create' ACTION_UPDATE = 'update' action = NotImplemented def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self._session = DBSession self._transaction = transaction self._user_api = UserApi(None) self._group_api = GroupApi(None) def get_description(self): return '''Create or update user.''' def get_parser(self, prog_name): parser = super().get_parser(prog_name) parser.add_argument( "-l", "--login", help='User login (email)', dest='login', required=True ) parser.add_argument( "-p", "--password", help='User password', dest='password', required=False, default=None ) parser.add_argument( "-g", "--add-to-group", help='Add user to group', dest='add_to_group', nargs='*', action=Extender, default=[], ) parser.add_argument( "-rmg", "--remove-from-group", help='Remove user from group', dest='remove_from_group', nargs='*', action=Extender, default=[], ) parser.add_argument( "--send-email", help='Send mail to user', dest='send_email', required=False, action='store_true', default=False, ) return parser def _user_exist(self, login): return self._user_api.user_with_email_exists(login) def _get_group(self, name): return self._group_api.get_one_with_name(name) def _add_user_to_named_group(self, user, group_name): group = self._get_group(group_name) if user not in group.users: group.users.append(user) self._session.flush() def _remove_user_from_named_group(self, user, group_name): group = self._get_group(group_name) if user in group.users: group.users.remove(user) self._session.flush() def _create_user(self, login, password, **kwargs): if not password: if self._password_required(): raise CommandAbortedError("You must provide -p/--password parameter") password = '' try: user = User(email=login, password=password, **kwargs) self._session.add(user) self._session.flush() except IntegrityError: self._session.rollback() raise AlreadyExistError() return user def _update_password_for_login(self, login, password): user = self._user_api.get_one_by_email(login) user.password = password self._session.flush() transaction.commit() def take_action(self, parsed_args): super().take_action(parsed_args) user = self._proceed_user(parsed_args) self._proceed_groups(user, parsed_args) print("User created/updated") def _proceed_user(self, parsed_args): self._check_context(parsed_args) if self.action == self.ACTION_CREATE: try: user = self._create_user(login=parsed_args.login, password=parsed_args.password) except AlreadyExistError: raise CommandAbortedError("Error: User already exist (use `user update` command instead)") if parsed_args.send_email: email_manager = get_email_manager() email_manager.notify_created_account( user=user, password=parsed_args.password, ) else: if parsed_args.password: self._update_password_for_login(login=parsed_args.login, password=parsed_args.password) user = self._user_api.get_one_by_email(parsed_args.login) return user def _proceed_groups(self, user, parsed_args): # User always in "users" group self._add_user_to_named_group(user, 'users') for group_name in parsed_args.add_to_group: self._add_user_to_named_group(user, group_name) for group_name in parsed_args.remove_from_group: self._remove_user_from_named_group(user, group_name) def _password_required(self): if config.get('auth_type') == LDAPAuth.name: return False return True def _check_context(self, parsed_args): if config.get('auth_type') == LDAPAuth.name: auth_instance = config.get('auth_instance') if not auth_instance.ldap_auth.user_exist(parsed_args.login): raise LDAPUserUnknown( "LDAP is enabled and user with login/email \"%s\" not found in LDAP" % parsed_args.login )
class UserCommand(AppContextCommand): ACTION_CREATE = 'create' ACTION_UPDATE = 'update' action = NotImplemented def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self._session = DBSession self._transaction = transaction self._user_api = UserApi(None) self._group_api = GroupApi(None) def get_description(self): return '''Create or update user.''' def get_parser(self, prog_name): parser = super().get_parser(prog_name) parser.add_argument("-l", "--login", help='User login (email)', dest='login', required=True) parser.add_argument("-p", "--password", help='User password', dest='password', required=False, default=None) parser.add_argument( "-g", "--add-to-group", help='Add user to group', dest='add_to_group', nargs='*', action=Extender, default=[], ) parser.add_argument( "-rmg", "--remove-from-group", help='Remove user from group', dest='remove_from_group', nargs='*', action=Extender, default=[], ) parser.add_argument( "--send-email", help='Send mail to user', dest='send_email', required=False, action='store_true', default=False, ) return parser def _user_exist(self, login): return self._user_api.user_with_email_exists(login) def _get_group(self, name): return self._group_api.get_one_with_name(name) def _add_user_to_named_group(self, user, group_name): group = self._get_group(group_name) if user not in group.users: group.users.append(user) self._session.flush() def _remove_user_from_named_group(self, user, group_name): group = self._get_group(group_name) if user in group.users: group.users.remove(user) self._session.flush() def _create_user(self, login, password, **kwargs): if not password: if self._password_required(): raise CommandAbortedError( "You must provide -p/--password parameter") password = '' try: user = User(email=login, password=password, **kwargs) user.update_webdav_digest_auth(password) self._session.add(user) self._session.flush() # We need to enable radicale if it not already done daemons = DaemonsManager() daemons.run('radicale', RadicaleDaemon) user_api = UserApi(user) user_api.execute_created_user_actions(user) except IntegrityError: self._session.rollback() raise AlreadyExistError() return user def _update_password_for_login(self, login, password): user = self._user_api.get_one_by_email(login) user.password = password user.update_webdav_digest_auth(password) self._session.flush() transaction.commit() def take_action(self, parsed_args): super().take_action(parsed_args) user = self._proceed_user(parsed_args) self._proceed_groups(user, parsed_args) print("User created/updated") def _proceed_user(self, parsed_args): self._check_context(parsed_args) if self.action == self.ACTION_CREATE: try: user = self._create_user(login=parsed_args.login, password=parsed_args.password) except AlreadyExistError: raise CommandAbortedError( "Error: User already exist (use `user update` command instead)" ) if parsed_args.send_email: email_manager = get_email_manager() email_manager.notify_created_account( user=user, password=parsed_args.password, ) else: if parsed_args.password: self._update_password_for_login(login=parsed_args.login, password=parsed_args.password) user = self._user_api.get_one_by_email(parsed_args.login) return user def _proceed_groups(self, user, parsed_args): # User always in "users" group self._add_user_to_named_group(user, 'users') for group_name in parsed_args.add_to_group: self._add_user_to_named_group(user, group_name) for group_name in parsed_args.remove_from_group: self._remove_user_from_named_group(user, group_name) def _password_required(self): if config.get('auth_type') == LDAPAuth.name: return False return True def _check_context(self, parsed_args): if config.get('auth_type') == LDAPAuth.name: auth_instance = config.get('auth_instance') if not auth_instance.ldap_auth.user_exist(parsed_args.login): raise LDAPUserUnknown( "LDAP is enabled and user with login/email \"%s\" not found in LDAP" % parsed_args.login)
class LDAPSearchAuthenticatorPlugin(BaseLDAPSearchAuthenticatorPlugin): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self._auth = None self._user_api = UserApi(None) def set_auth(self, auth): self._auth = auth def authenticate(self, environ, identity, allow_auth_token: bool = False): # Note: super().authenticate return None if already authenticated or not found email = super().authenticate(environ, identity) if email: self._sync_ldap_user(email, environ, identity) if not email and allow_auth_token and self.user_exist(email): # Proceed to internal token auth user = self.sa_auth.dbsession.query( self.sa_auth.user_class).filter( and_(self.sa_auth.user_class.is_active == True, self.sa_auth.user_class.email == identity['login'])).first() if user: user.ensure_auth_token() if user.auth_token == identity['password']: email = identity['login'] return email def _sync_ldap_user(self, email, environ, identity): # Create or get user for connected email if not self._user_api.user_with_email_exists(email): user = User(email=email, imported_from=LDAPAuth.name) DBSession.add(user) else: user = self._user_api.get_one_by_email(email) # Retrieve ldap user attributes self._auth.ldap_user_provider.add_metadata_for_auth(environ, identity) # Update user with ldap attributes user_ldap_values = identity.get('user').copy() for field_name in user_ldap_values: setattr(user, field_name, user_ldap_values[field_name]) DBSession.flush() transaction.commit() def user_exist(self, email): with make_connection(self.url, self.bind_dn, self.bind_pass) as conn: if self.start_tls: conn.start_tls() if not conn.bind(): return False search = self.search_pattern % email conn.search(self.base_dn, search, self.search_scope) if len(conn.response) > 0: return True return False