def POST(self): form = web.input() subject = form['subject'] email_body = form['body'] to = form['to'] receivers = [] if to=="admins": receivers =[u for u in User.selectBy(admin=True, disabled=False)] elif to=="supadmins": receivers=[u for u in User.selectBy(super_admin=True).distinct()] elif to == 'contrib': id_channel=form['select_channel'] c = PluginChannel.get(id_channel) receivers = [u for u in c.get_contribs()] elif to=="channel_editor_users": pc = PluginChannel.select() for elem in pc: if elem.plugin.name=="editor": l1=[u1 for u1 in elem.get_admins()] l2=[u2 for u2 in elem.get_contribs()] list_users = l1+l2 receivers=[u for u in list_users] else: for s in Screen.select(): receivers=[u for u in s.owners] try: for u in receivers: web.sendmail(web.config.smtp_sendername, u.email, subject, email_body, headers={'Content-Type': 'text/html;charset=utf-8'}) except smtplib.SMTPException: logger.error('An error occured when sending email ', exc_info=True) return web.seeother("/")
def runTest(self): """ Subscribes and unsubscribes a screen from some channels and checks that it has been successfully subscribed/unsubscribed """ screen = self.screen # subscribe to some plugin_channels diff = {self.plugin_channels[i].id: True for i in range(len(self.plugin_channels)) if i % 2 == 0} # also subscribe to a bundle diff[self.bundle_channels[1].id] = True post_params = {"diff": json.dumps(diff)} assert self.testApp.post("/screens/%s/subscriptions" % screen.id, post_params, status=303).body is not None verify_diff(diff, screen) # Now, remove one channel and the added bundle, then, subscribe to another new channel diff = {self.plugin_channels[0].id: False, self.bundle_channels[1].id: False, self.plugin_channels[1].id: True} post_params = {"diff": json.dumps(diff)} assert self.testApp.post("/screens/%s/subscriptions" % screen.id, post_params, status=303).body is not None verify_diff(diff, screen) # Now, re-subscribe to and un-subscribe from the first plugin_channel and bundle_channel when they are # restricted channels and we are in its authorized subscribers channel = self.plugin_channels[0] bundle = self.bundle_channels[0] channel.subscription_right = "restricted" bundle.subscription_right = "restricted" user = User.selectBy(email=self.user_screen_owner_email).getOne() self.ictv_app.test_user = {"email": user.email} channel.safe_add_user(user) bundle.safe_add_user(user) diff = {channel.id: True, bundle.id: True} post_params = {"diff": json.dumps(diff)} assert self.testApp.post("/screens/%s/subscriptions" % screen.id, post_params, status=303).body is not None verify_diff(diff, screen) diff = {channel.id: False, bundle.id: False} post_params = {"diff": json.dumps(diff)} assert self.testApp.post("/screens/%s/subscriptions" % screen.id, post_params, status=303).body is not None
def get(self, email): u = User.selectBy(email=email).getOne(None) if u is not None: self.session['user'] = u.to_dictionary(['id', 'fullname', 'email']) if 'sidebar' in self.session: self.session.pop('sidebar') resp.seeother('/')
def get(self, secret): user = User.selectBy(reset_secret=secret).getOne(None) if not user: logger.warning('IP %s tried to access password reset page with invalid secret', flask.request.remote_addr) if 'user' in self.session: logger.warning('User %s is currently connected', User.get(self.session['user']['id']).log_name) resp.seeother('/') return self.standalone_renderer.reset(user=user)
def post(self): """ Receive the POST binding request from IDP. - process the request - extract user attributes - create a new User if it doesn't exist - fill in the session - redirect to RelayState or / """ # SAML boiler plate code req = prepare_request() settings = build_settings(self.config['saml2']) # this is the object to interact with the shibboleth parameters auth = init_saml_auth(req, settings) errors = [] not_auth_warn = False success_slo = False input_data = flask.request.form if 'acs' in flask.request.args: auth.process_response() # decrypt and extract informations errors = auth.get_errors() not_auth_warn = not auth.is_authenticated() if len(errors) == 0: attrs = auth.get_attributes( ) # get attributes returned by the shibboleth idp for key in attrs.keys(): print("(" + key + ", " + str(attrs[key]) + ")") username = attrs[settings['sp']['attrs']['username']][0] realname = attrs[settings['sp']['attrs']['realname']][0] email = attrs[settings['sp']['attrs']['email']][0] u = User.selectBy(email=email).getOne(None) if not u: # The user does not exist in our DB u = User(username=username, email=email, fullname=realname, super_admin=False, disabled=True) self.session['user'] = u.to_dictionary( ['id', 'fullname', 'username', 'email']) self_url = OneLogin_Saml2_Utils.get_self_url(req) if 'RelayState' in input_data and self_url != input_data[ 'RelayState']: return resp.seeother( auth.redirect_to(input_data['RelayState'])) return resp.seeother('/')
def runTest(self): """ Tests the User object """ try: User(username='******', fullname='test test', email='*****@*****.**', super_admin=True, disabled=False) except DuplicateEntryError: assert_true(False) b = User.selectBy(username="******").getOne() assert_not_equal(b, None) assert_equal(b.username, "test") try: b.set(username="******") except DuplicateEntryError: assert_true(False) assert_equal(b.username, "newName") b.set(username="******") l = b.get_subscriptions_of_owned_screens() assert_true(l.count() >= 0) una = User(username='******', fullname='testnoadmin test', email='*****@*****.**', super_admin=False, disabled=False) l = una.get_subscriptions_of_owned_screens() assert_true(l.count() >= 0) User.delete(una.id) b.set(disabled=True) assert_equal(b.disabled, True) t = b.owns_screen() assert_equal(t, False) b = User.selectBy(username="******").getOne() b.addScreen(Screen(name='A', building=Building(name='A'))) t = b.owns_screen() assert_equal(t, True) b = User.selectBy(username="******").getOne() t = User.delete(b.id) assert_equal(t, None) b = User.selectBy(username="******").getOne(None) assert_true(None == b)
def log_as(): u = User.selectBy(email=target_user).getOne() real_user_dict = self.session[ 'user'] if 'real_user' not in self.session else self.session[ 'real_user'] real_user = User.selectBy(email=real_user_dict['email']).getOne() if u is not None: if u.highest_permission_level in real_user.highest_permission_level: self.session['real_user'] = self.session[ 'user'] if 'real_user' not in self.session else self.session[ 'real_user'] self.session['user'] = u.to_dictionary( ['id', 'fullname', 'email']) self.logger.info( 'the super_administrator %s has been logged as %s', real_user.log_name, u.log_name) resp.seeother('/') else: resp.forbidden()
def GET(self, secret): user = User.selectBy(reset_secret=secret).getOne(None) if not user: logger.warning( 'IP %s tried to access password reset page with invalid secret', web.ctx.ip) if 'user' in self.session: logger.warning('User %s is currently connected', User.get(self.session['user']['id']).log_name) raise web.redirect('/') return self.standalone_renderer.reset(user=user)
def authentication_processor(handler): def post_auth(): if 'user' in app.session: User.get(id=app.session['user']['id']) app.session.pop('sidebar', None) return handler() class_path, _ = match(app.mapping, web.ctx.path) if class_path: if '.' in class_path: mod, cls = class_path.rsplit('.', 1) mod = __import__(mod, None, None, ['']) cls = getattr(mod, cls) else: cls = app.fvars[class_path] if issubclass(cls, ICTVAuthPage): if is_test(): if hasattr(app, 'test_user'): u = User.selectBy( email=app.test_user['email']).getOne() app.session['user'] = u.to_dictionary( ['id', 'fullname', 'username', 'email']) return post_auth() elif 'user' in app.session: del app.session[ 'user'] # This may not be the ideal way of changing users if app.config['debug']['autologin']: u = User.selectBy(email='admin@ictv').getOne(None) if u is not None: app.session['user'] = u.to_dictionary( ['id', 'fullname', 'username', 'email']) return post_auth() mode = app.config['authentication'][ 0] # The first mode is the main authentication mode if mode not in mode_to_processor: raise Exception( 'Authentication method "%s" specified in config file is not supported' % app.config['authentication']) return mode_to_processor[mode](post_auth) return post_auth()
def runTest(self): """ Tries to create duplicate users and checks that no duplication occurs and that it is handled properly for the user """ username = "******" fullname = "Test FullName" # test with duplicate email post_params = { "action": "create", "admin": "", "super_admin": "", "username": username, "fullname": fullname, "email": self.user_nothing_email } user_before = repr( User.selectBy(email=self.user_nothing_email).getOne(None)) assert self.testApp.post("/users", post_params, status=303).body is not None u = User.selectBy(email=self.user_nothing_email).getOne(None) assert u is not None user_after = repr(u) assert user_after == user_before # test with duplicate username post_params = { "action": "create", "admin": "", "super_admin": "", "username": self.user_nothing_username, "fullname": fullname, "email": "*****@*****.**" } user_before = repr( User.selectBy(username=self.user_nothing_username).getOne(None)) assert self.testApp.post("/users", post_params, status=303).body is not None u = User.selectBy(username=self.user_nothing_username).getOne(None) assert u is not None user_after = repr(u) assert user_after == user_before
def get_visible_channels_of(cls, user): """ Returns the channels that are accessible for the user (public channels or channels with the user specified in authorized_subscribers, or all channels if the user is superadmin) :param user: The user to retrieve the accessible channels. :return: A iterable with the accessible channels (iterable of sqlobjects) """ if UserPermissions.administrator in user.highest_permission_level: return set(Channel.select()) public_channels = set(Channel.selectBy(subscription_right='public')) if UserPermissions.screen_administrator in \ user.highest_permission_level else set() return public_channels | set(Role.selectBy(user=user).throughTo.channel) | set( User.selectBy(id=user.id).throughTo.authorized_channels)
def authentication_processor(): #Avoid processing for static files if request_static(): return def post_auth(): if 'user' in app.session: User.get(id=app.session['user']['id']) app.session.pop('sidebar', None) endpoint, _ = app.create_url_adapter(flask.request).match() view_class = app.view_functions.get(endpoint).view_class if issubclass(view_class, ICTVAuthPage): if is_test(): if hasattr(app, 'test_user'): u = User.selectBy(email=app.test_user['email']).getOne() app.session['user'] = u.to_dictionary( ['id', 'fullname', 'username', 'email']) return post_auth() elif 'user' in app.session: del app.session[ 'user'] # This may not be the ideal way of changing users if app.config['debug']['autologin']: u = User.selectBy(email='admin@ictv').getOne(None) if u is not None: app.session['user'] = u.to_dictionary( ['id', 'fullname', 'username', 'email']) return post_auth() mode = app.config['authentication'][ 0] # The first mode is the main authentication mode if mode not in mode_to_processor: raise Exception( 'Authentication method "%s" specified in config file is not supported' % app.config['authentication']) return mode_to_processor[mode](post_auth) post_auth()
def post(self): if 'user' in self.session: resp.seeother('/') form = self.form try: user = User.selectBy(email=form.email, password=hash_password(form.password)).getOne(None) if not user: raise ImmediateFeedback('login', 'invalid_credentials') self.session['user'] = user.to_dictionary(['id', 'fullname', 'username', 'email']) except ImmediateFeedback: store_form(form) return self.render_page() resp.seeother('/')
def runTest(self): username = "******" fullname = "Test FullName" email = "user@localhost" email2 = "2" + email post_params = { "action": "create", "admin": "", "super_admin": "", "username": username, "fullname": fullname, "email": email } assert self.testApp.post("/users", post_params, status=303).body is not None u = User.selectBy(email=email).getOne(None) assert u is not None assert u.username == username assert u.email == email assert u.fullname == fullname for username in ["", " ", " ", " ", " \t "]: post_params = { "action": "create", "admin": "", "super_admin": "", "username": username, "fullname": "", "email": email2 } assert self.testApp.post("/users", post_params, status=303).body is not None u = User.selectBy(email=email2).getOne(None) assert u is not None assert u.username is None assert u.fullname == "" assert u.email == email2
def post(self): form = self.form subject = form['subject'] email_body = form['body'] to = form['to'] receivers = [] if to == "admins": receivers = [u for u in User.selectBy(admin=True, disabled=False)] elif to == "supadmins": receivers = [u for u in User.selectBy(super_admin=True).distinct()] elif to == 'contrib': id_channel = form['select_channel'] c = PluginChannel.get(id_channel) receivers = [u for u in c.get_contribs()] elif to == "channel_editor_users": pc = PluginChannel.select() for elem in pc: if elem.plugin.name == "editor": l1 = [u1 for u1 in elem.get_admins()] l2 = [u2 for u2 in elem.get_contribs()] list_users = l1 + l2 receivers = [u for u in list_users] else: for s in Screen.select(): receivers = [u for u in s.owners] try: mail = Mail(self.app) msg = Message( recipients=[u.email for u in receivers], subject=subject, body=email_body, extra_headers={'Content-Type': 'text/html;charset=utf-8'}) mail.send(msg) except smtplib.SMTPException: logger.error('An error occured when sending email ', exc_info=True) resp.seeother("/")
def post(self, secret): user = User.selectBy(reset_secret=secret).getOne(None) form = self.form try: if form.get('password1') != form.get('password2'): raise ImmediateFeedback('reset', 'passwords_do_not_match') password = form.password1.strip() if len(password) <= 3: raise ImmediateFeedback('reset', 'password_insufficient') user.password = hash_password(form.password1) user.reset_secret = utils.generate_secret() # Make this token one time use logger.info('User %s has reset its password from IP %s', user.log_name, flask.g.ip) except ImmediateFeedback: return self.standalone_renderer.reset(user=user) add_feedback('reset', 'ok') resp.seeother(flask.url_for("LoginPage"))
def send_email_alert(self, channel, filtered_out_content): message = 'the content of channel %s contained a total of %d slide(s) with non-complying field(s):\n' % ( channel.name, len(filtered_out_content)) for slide in filtered_out_content: for f in slide: message += 'The field %s from template %s allows up to %d characters but it was provided with "%s" for a total of %d characters.\n' % ( f[0], f[1], f[3], f[4], f[2]) message += '\n' message_hash = hash(message) message = ('At %s, ' % datetime.now()) + message if Role.selectBy(channel=channel, permission_level='channel_administrator').count() == 0: for super_admin in User.selectBy(super_admin=True): self.template_limits_email_digester.add_email(super_admin, message, message_hash) else: for administrator in Role.selectBy(channel=channel, permission_level='channel_administrator').throughTo.user: self.template_limits_email_digester.add_email(administrator, message, message_hash)
def post(self): """ Handles user creation, editing and deletion. """ form = self.form super_admin = form.get('super_admin', False) == 'on' admin = form.get('admin', False) == 'on' if super_admin: admin = False current_user = User.get(self.session['user']['id']) try: if form.action == 'create': username = form.username.strip() fullname = form.fullname.strip() form.email = form.email.strip() email = None if len(form.email) == 0 or not self.pattern.match( form.email) else form.email if email is None and len(form.email) != 0: raise ImmediateFeedback(form.action, 'invalid_email') if len(email) > User.sqlmeta.columns['email'].length: raise ImmediateFeedback(form.action, 'too_long_email') if len(username) > User.sqlmeta.columns['username'].length: raise ImmediateFeedback(form.action, 'too_long_username') if not username: username = None elif len(username) < 3: raise ImmediateFeedback(form.action, 'invalid_username') try: User(username=username, fullname=fullname, email=email, super_admin=super_admin, disabled=False) except DuplicateEntryError: u = User.selectBy(email=form.email).getOne(None) if u is not None: raise ImmediateFeedback(form.action, 'email_already_exists') u = User.selectBy(username=username).getOne(None) if u is not None: raise ImmediateFeedback(form.action, 'username_already_exists') elif form.action == 'edit': try: form.id = int(form.id) u = User.get(form.id) form.email = form.email.strip() email = None if len( form.email) == 0 or not self.pattern.match( form.email) else form.email form.username = u.username form.fullname = u.fullname if email is None and len(form.email) != 0: raise ImmediateFeedback(form.action, 'invalid_email') if email: try: u.email = email except DuplicateEntryError: raise ImmediateFeedback(form.action, 'email_already_exists') form.email = u.email if len(email) > User.sqlmeta.columns['email'].length: raise ImmediateFeedback(form.action, 'too_long_email') if not current_user.super_admin: if u.super_admin: resp.forbidden() else: if self.session['user']['id'] != form.id: u.set(super_admin=super_admin, admin=admin) except (SQLObjectNotFound, ValueError): raise ImmediateFeedback(form.action, 'invalid_id') elif form.action == 'toggle-activation': if not current_user.super_admin: resp.forbidden() try: form.id = int(form.id) u = User.get(form.id) form.email = u.email u.disabled = not u.disabled add_feedback( form.action, 'activated' if not u.disabled else 'deactivated') except (SQLObjectNotFound, ValueError): raise ImmediateFeedback(form.action, 'invalid_id') add_feedback(form.action, 'ok') except ImmediateFeedback: pass store_form(form) resp.seeother('/users')