Esempio n. 1
0
def save_token(token_data, request, *args, **kwargs):
    # For the implicit flow
    # Check issue: https://github.com/lepture/flask-oauthlib/issues/209
    if request.grant_type == 'authorization_code':
        user = request.user
    elif request.grant_type is None:  # implicit flow
        user = session.user
    else:
        raise ValueError('Invalid grant_type')
    requested_scopes = set(token_data['scope'].split())
    token = OAuthToken.find_first(OAuthApplication.client_id == request.client.client_id,
                                  OAuthToken.user == user,
                                  _join=OAuthApplication)
    if token is None:
        application = OAuthApplication.find_one(client_id=request.client.client_id)
        token = OAuthToken(application=application, user=user)
        db.session.add(token)
        token.access_token = token_data['access_token']
        token.scopes = requested_scopes
    elif requested_scopes - token.scopes:
        logger.info('Added scopes to {}: {}'.format(token, requested_scopes - token.scopes))
        # use the new access_token when extending scopes
        token.access_token = token_data['access_token']
        token.scopes |= requested_scopes
    else:
        token_data['access_token'] = token.access_token
    token_data.pop('refresh_token', None)  # we don't support refresh tokens so far
    token_data.pop('expires_in', None)  # our tokens currently do not expire
    return token
Esempio n. 2
0
def test_save_token_no_application(dummy_application, dummy_request,
                                   token_data):
    dummy_request.client.client_id = str(uuid4())
    assert not OAuthApplication.find(
        client_id=dummy_request.client.client_id).count()
    with pytest.raises(NoResultFound):
        save_token(token_data, dummy_request)
Esempio n. 3
0
def create_all_tables(db, verbose=False, add_initial_data=True):
    """Create all tables and required initial objects."""
    from indico.modules.categories import Category
    from indico.modules.designer import TemplateType
    from indico.modules.designer.models.templates import DesignerTemplate
    from indico.modules.oauth.models.applications import OAuthApplication, SystemAppType
    from indico.modules.users import User
    if verbose:
        print(cformat('%{green}Creating tables'))
    db.create_all()
    if add_initial_data:
        if verbose:
            print(cformat('%{green}Creating system user'))
        db.session.add(User(id=0, is_system=True, first_name='Indico', last_name='System'))
        if verbose:
            print(cformat('%{green}Creating root category'))
        cat = Category(id=0, title='Home', protection_mode=ProtectionMode.public)
        db.session.add(cat)
        db.session.flush()
        if verbose:
            print(cformat('%{green}Creating default ticket template for root category '))
        dtt = DesignerTemplate(category_id=0, title='Default ticket', type=TemplateType.badge,
                               data=DEFAULT_TICKET_DATA, is_system_template=True)
        dbt = DesignerTemplate(category_id=0, title='Default badge', type=TemplateType.badge,
                               data=DEFAULT_BADGE_DATA, is_system_template=True)
        cat.default_ticket_template = dtt
        cat.default_badge_template = dbt
        db.session.add(dtt)
        db.session.add(dbt)
        if verbose:
            print(cformat('%{green}Creating system oauth apps'))
        for sat in SystemAppType:
            if sat != SystemAppType.none:
                db.session.add(OAuthApplication(system_app_type=sat, **sat.default_data))
        db.session.commit()
Esempio n. 4
0
    def _process(self):
        config = Config.getInstance()

        # QRCode (Version 6 with error correction L can contain up to 106 bytes)
        qr = qrcode.QRCode(version=6,
                           error_correction=qrcode.constants.ERROR_CORRECT_M,
                           box_size=4,
                           border=1)

        checkin_app_client_id = config.getCheckinAppClientId()
        checkin_app = OAuthApplication.find_first(
            client_id=checkin_app_client_id)

        qr_data = {
            "event_id": self.event_new.id,
            "title": self.event_new.title,
            "date": format_date(self.event_new.start_dt_local
                                ),  # XXX: switch to utc+isoformat?
            "server": {
                "baseUrl": config.getBaseURL(),
                "consumerKey": checkin_app.client_id,
                "auth_url": url_for('oauth.oauth_authorize', _external=True),
                "token_url": url_for('oauth.oauth_token', _external=True)
            }
        }
        json_qr_data = json.dumps(qr_data)
        qr.add_data(json_qr_data)
        qr.make(fit=True)
        qr_img = qr.make_image()

        output = BytesIO()
        qr_img.save(output)
        output.seek(0)

        return send_file('config.png', output, 'image/png')
Esempio n. 5
0
def save_token(token_data, request, *args, **kwargs):
    # For the implicit flow
    # Check issue: https://github.com/lepture/flask-oauthlib/issues/209
    if request.grant_type == 'authorization_code':
        user = request.user
    elif request.grant_type is None:  # implicit flow
        user = session.user
    else:
        raise ValueError('Invalid grant_type')
    requested_scopes = set(token_data['scope'].split())
    token = OAuthToken.find_first(
        OAuthApplication.client_id == request.client.client_id,
        OAuthToken.user == user,
        _join=OAuthApplication)
    if token is None:
        application = OAuthApplication.find_one(
            client_id=request.client.client_id)
        token = OAuthToken(application=application, user=user)
        db.session.add(token)
        token.access_token = token_data['access_token']
        token.scopes = requested_scopes
    elif requested_scopes - token.scopes:
        logger.info('Added scopes to %s: %s', token,
                    requested_scopes - token.scopes)
        # use the new access_token when extending scopes
        token.access_token = token_data['access_token']
        token.scopes |= requested_scopes
    else:
        token_data['access_token'] = token.access_token
    token_data.pop('refresh_token',
                   None)  # we don't support refresh tokens so far
    token_data.pop('expires_in', None)  # our tokens currently do not expire
    return token
Esempio n. 6
0
    def _process(self):
        # QRCode (Version 6 with error correction L can contain up to 106 bytes)
        qr = qrcode.QRCode(
            version=6,
            error_correction=qrcode.constants.ERROR_CORRECT_M,
            box_size=4,
            border=1
        )

        checkin_app = OAuthApplication.find_one(system_app_type=SystemAppType.checkin)
        qr_data = {
            "event_id": self.event.id,
            "title": self.event.title,
            "date": self.event.start_dt.isoformat(),
            "version": 1,
            "server": {
                "base_url": config.BASE_URL,
                "consumer_key": checkin_app.client_id,
                "auth_url": url_for('oauth.oauth_authorize', _external=True),
                "token_url": url_for('oauth.oauth_token', _external=True)
            }
        }
        json_qr_data = json.dumps(qr_data)
        qr.add_data(json_qr_data)
        qr.make(fit=True)
        qr_img = qr.make_image()

        output = BytesIO()
        qr_img.save(output)
        output.seek(0)

        return send_file('config.png', output, 'image/png')
Esempio n. 7
0
 def _process_args(self):
     try:
         UUID(hex=request.args['client_id'])
     except ValueError:
         raise NoResultFound
     self.application = OAuthApplication.find_one(
         client_id=request.args['client_id'])
Esempio n. 8
0
def celery_cmd(args):
    # remove the celery shell command
    next(funcs for group, funcs, _ in command_classes
         if group == 'Main').remove('shell')
    del CeleryCommand.commands['shell']

    if args and args[0] == 'flower':
        # Somehow flower hangs when executing it using CeleryCommand() so we simply exec it directly.
        # It doesn't really need the celery config anyway (besides the broker url)

        try:
            import flower  # noqa: F401
        except ImportError:
            print(cformat('%{red!}Flower is not installed'))
            sys.exit(1)

        app = OAuthApplication.find_one(system_app_type=SystemAppType.flower)
        if not app.redirect_uris:
            print(
                cformat(
                    '%{yellow!}Authentication will fail unless you configure the redirect url for the {} OAuth '
                    'application in the administration area.').format(
                        app.name))

        print(
            cformat('%{green!}Only Indico admins will have access to flower.'))
        print(
            cformat(
                '%{yellow}Note that revoking admin privileges will not revoke Flower access.'
            ))
        print(cformat('%{yellow}To force re-authentication, restart Flower.'))
        auth_args = [
            '--auth=^Indico Admin$',
            '--auth_provider=indico.core.celery.flower.FlowerAuthHandler'
        ]
        auth_env = {
            'INDICO_FLOWER_CLIENT_ID':
            app.client_id,
            'INDICO_FLOWER_CLIENT_SECRET':
            app.client_secret,
            'INDICO_FLOWER_AUTHORIZE_URL':
            url_for('oauth.oauth_authorize', _external=True),
            'INDICO_FLOWER_TOKEN_URL':
            url_for('oauth.oauth_token', _external=True),
            'INDICO_FLOWER_USER_URL':
            url_for('users.authenticated_user', _external=True)
        }
        if config.FLOWER_URL:
            auth_env['INDICO_FLOWER_URL'] = config.FLOWER_URL
        args = ['celery', '-b', config.CELERY_BROKER] + args + auth_args
        env = dict(os.environ, **auth_env)
        os.execvpe('celery', args, env)
    elif args and args[0] == 'shell':
        print(cformat('%{red!}Please use `indico shell`.'))
        sys.exit(1)
    else:
        CeleryCommand(celery).execute_from_commandline(['indico celery'] +
                                                       args)
Esempio n. 9
0
def load_client(client_id):
    try:
        UUID(hex=client_id)
    except ValueError:
        raise InvalidClientIdError
    app = OAuthApplication.find_first(client_id=client_id)
    if not app.is_enabled:
        raise DisabledClientIdError
    return app
Esempio n. 10
0
def load_client(client_id):
    try:
        UUID(hex=client_id)
    except ValueError:
        raise InvalidClientIdError
    app = OAuthApplication.find_first(client_id=client_id)
    if not app.is_enabled:
        raise DisabledClientIdError
    return app
Esempio n. 11
0
 def validate_name(self, field):
     query = OAuthApplication.find(name=field.data)
     if self.application:
         query = query.filter(
             db.func.lower(OAuthApplication.name) !=
             self.application.name.lower())
     if query.count():
         raise ValidationError(
             _("There is already an application with this name"))
Esempio n. 12
0
 def _create_application(name, **params):
     params.setdefault('client_id', unicode(uuid4()))
     params.setdefault('default_scopes', 'read:user')
     params.setdefault('redirect_uris', 'http://localhost:10500')
     params.setdefault('is_trusted', True)
     application = OAuthApplication(name=name, **params)
     db.session.add(application)
     db.session.flush()
     return application
Esempio n. 13
0
 def _process(self):
     form = ApplicationForm(obj=FormDefaults(is_enabled=True))
     if form.validate_on_submit():
         application = OAuthApplication()
         form.populate_obj(application)
         db.session.add(application)
         db.session.flush()
         logger.info("Application %s created by %s", application, session.user)
         flash(_("Application {} registered successfully").format(application.name), 'success')
         return redirect(url_for('.app_details', application))
     return WPOAuthAdmin.render_template('app_new.html', form=form)
Esempio n. 14
0
    def _check_ticket_app_enabled(self):
        config = Config.getInstance()
        checkin_app_client_id = config.getCheckinAppClientId()

        if checkin_app_client_id is None:
            flash(_("indico-checkin client_id is not defined in the Indico configuration"), 'warning')
            return False

        checkin_app = OAuthApplication.find_first(client_id=checkin_app_client_id)
        if checkin_app is None:
            flash(_("indico-checkin is not registered as an OAuth application with client_id {}")
                  .format(checkin_app_client_id), 'warning')
            return False
        return True
Esempio n. 15
0
    def _check_ticket_app_enabled(self):
        config = Config.getInstance()
        checkin_app_client_id = config.getCheckinAppClientId()

        if checkin_app_client_id is None:
            flash(_("indico-checkin client_id is not defined in the Indico configuration"), 'warning')
            return False

        checkin_app = OAuthApplication.find_first(client_id=checkin_app_client_id)
        if checkin_app is None:
            flash(_("indico-checkin is not registered as an OAuth application with client_id {}")
                  .format(checkin_app_client_id), 'warning')
            return False
        return True
Esempio n. 16
0
    def run(self, args):
        # disable the zodb commit hook
        update_session_options(db)
        # remove the celery shell command
        next(funcs for group, funcs, _ in command_classes if group == 'Main').remove('shell')
        del CeleryCommand.commands['shell']

        if args and args[0] == 'flower':
            # Somehow flower hangs when executing it using CeleryCommand() so we simply exec it directly.
            # It doesn't really need the celery config anyway (besides the broker url)

            try:
                import flower
            except ImportError:
                print cformat('%{red!}Flower is not installed')
                sys.exit(1)

            client_id = Config.getInstance().getFlowerClientId()
            if client_id:
                app = OAuthApplication.find_first(client_id=client_id)
                if app is None:
                    print cformat('%{red!}There is no OAuth application with the client id {}.').format(client_id)
                    sys.exit(1)
                elif 'read:user' not in app.default_scopes:
                    print cformat('%{red!}The {} application needs the read:user scope.').format(app.name)
                    sys.exit(1)
                print cformat('%{green!}Only Indico admins will have access to flower.')
                print cformat('%{yellow}Note that revoking admin privileges will not revoke Flower access.')
                print cformat('%{yellow}To force re-authentication, restart Flower.')
                auth_args = ['--auth=^Indico Admin$', '--auth_provider=indico.core.celery.flower.FlowerAuthHandler']
                auth_env = {'INDICO_FLOWER_CLIENT_ID': app.client_id,
                            'INDICO_FLOWER_CLIENT_SECRET': app.client_secret,
                            'INDICO_FLOWER_AUTHORIZE_URL': url_for('oauth.oauth_authorize', _external=True),
                            'INDICO_FLOWER_TOKEN_URL': url_for('oauth.oauth_token', _external=True),
                            'INDICO_FLOWER_USER_URL': url_for('users.authenticated_user', _external=True)}
            else:
                print cformat('%{red!}WARNING: %{yellow!}Flower authentication is disabled.')
                print cformat('%{yellow!}Having access to Flower allows one to shutdown Celery workers.')
                print
                auth_args = []
                auth_env = {}
            args = ['celery', '-b', Config.getInstance().getCeleryBroker()] + args + auth_args
            env = dict(os.environ, **auth_env)
            os.execvpe('celery', args, env)
        elif args and args[0] == 'shell':
            print cformat('%{red!}Please use `indico shell`.')
            sys.exit(1)
        else:
            CeleryCommand(celery).execute_from_commandline(['indico celery'] + args)
Esempio n. 17
0
    def run(self, args):
        # disable the zodb commit hook
        update_session_options(db)
        # remove the celery shell command
        next(funcs for group, funcs, _ in command_classes if group == 'Main').remove('shell')
        del CeleryCommand.commands['shell']

        if args and args[0] == 'flower':
            # Somehow flower hangs when executing it using CeleryCommand() so we simply exec it directly.
            # It doesn't really need the celery config anyway (besides the broker url)

            try:
                import flower
            except ImportError:
                print cformat('%{red!}Flower is not installed')
                sys.exit(1)

            client_id = Config.getInstance().getFlowerClientId()
            if client_id:
                app = OAuthApplication.find_first(client_id=client_id)
                if app is None:
                    print cformat('%{red!}There is no OAuth application with the client id {}.').format(client_id)
                    sys.exit(1)
                elif 'read:user' not in app.default_scopes:
                    print cformat('%{red!}The {} application needs the read:user scope.').format(app.name)
                    sys.exit(1)
                print cformat('%{green!}Only Indico admins will have access to flower.')
                print cformat('%{yellow}Note that revoking admin privileges will not revoke Flower access.')
                print cformat('%{yellow}To force re-authentication, restart Flower.')
                auth_args = ['--auth=^Indico Admin$', '--auth_provider=indico.core.celery.flower.FlowerAuthHandler']
                auth_env = {'INDICO_FLOWER_CLIENT_ID': app.client_id,
                            'INDICO_FLOWER_CLIENT_SECRET': app.client_secret,
                            'INDICO_FLOWER_AUTHORIZE_URL': url_for('oauth.oauth_authorize', _external=True),
                            'INDICO_FLOWER_TOKEN_URL': url_for('oauth.oauth_token', _external=True),
                            'INDICO_FLOWER_USER_URL': url_for('users.authenticated_user', _external=True)}
            else:
                print cformat('%{red!}WARNING: %{yellow!}Flower authentication is disabled.')
                print cformat('%{yellow!}Having access to Flower allows one to shutdown Celery workers.')
                print
                auth_args = []
                auth_env = {}
            args = ['celery', '-b', Config.getInstance().getCeleryBroker()] + args + auth_args
            env = dict(os.environ, **auth_env)
            os.execvpe('celery', args, env)
        elif args and args[0] == 'shell':
            print cformat('%{red!}Please use `indico shell`.')
            sys.exit(1)
        else:
            CeleryCommand(celery).execute_from_commandline(['indico celery'] + args)
Esempio n. 18
0
def celery_cmd(args):
    # remove the celery shell command
    next(funcs for group, funcs, _ in command_classes if group == 'Main').remove('shell')
    del CeleryCommand.commands['shell']

    if args and args[0] == 'flower':
        # Somehow flower hangs when executing it using CeleryCommand() so we simply exec it directly.
        # It doesn't really need the celery config anyway (besides the broker url)

        try:
            import flower
        except ImportError:
            print cformat('%{red!}Flower is not installed')
            sys.exit(1)

        app = OAuthApplication.find_one(system_app_type=SystemAppType.flower)
        if not app.redirect_uris:
            print cformat('%{yellow!}Authentication will fail unless you configure the redirect url for the {} OAuth '
                          'application in the administration area.').format(app.name)

        print cformat('%{green!}Only Indico admins will have access to flower.')
        print cformat('%{yellow}Note that revoking admin privileges will not revoke Flower access.')
        print cformat('%{yellow}To force re-authentication, restart Flower.')
        auth_args = ['--auth=^Indico Admin$', '--auth_provider=indico.core.celery.flower.FlowerAuthHandler']
        auth_env = {'INDICO_FLOWER_CLIENT_ID': app.client_id,
                    'INDICO_FLOWER_CLIENT_SECRET': app.client_secret,
                    'INDICO_FLOWER_AUTHORIZE_URL': url_for('oauth.oauth_authorize', _external=True),
                    'INDICO_FLOWER_TOKEN_URL': url_for('oauth.oauth_token', _external=True),
                    'INDICO_FLOWER_USER_URL': url_for('users.authenticated_user', _external=True)}
        if config.FLOWER_URL:
            auth_env['INDICO_FLOWER_URL'] = config.FLOWER_URL
        args = ['celery', '-b', config.CELERY_BROKER] + args + auth_args
        env = dict(os.environ, **auth_env)
        os.execvpe('celery', args, env)
    elif args and args[0] == 'shell':
        print cformat('%{red!}Please use `indico shell`.')
        sys.exit(1)
    else:
        CeleryCommand(celery).execute_from_commandline(['indico celery'] + args)
Esempio n. 19
0
    def _getAnswer(self):
        config = Config.getInstance()
        checkin_app_client_id = config.getCheckinAppClientId()
        if checkin_app_client_id is None:
            raise NoReportError(_("indico-checkin client_id is not defined in the Indico configuration"))
        checkin_app = OAuthApplication.find_first(client_id=checkin_app_client_id)
        if checkin_app is None:
            raise NoReportError(
                _("indico-checkin is not registered as an OAuth application with client_id {}").format(
                    checkin_app_client_id
                )
            )

        # QRCode (Version 6 with error correction L can contain up to 106 bytes)
        qr = QRCode(version=6, error_correction=constants.ERROR_CORRECT_M, box_size=4, border=1)

        baseURL = config.getBaseSecureURL() if config.getBaseSecureURL() else config.getBaseURL()
        qr_data = {
            "event_id": self._conf.getId(),
            "title": self._conf.getTitle(),
            "date": format_date(self._conf.getAdjustedStartDate()),
            "server": {
                "baseUrl": baseURL,
                "consumerKey": checkin_app.client_id,
                "auth_url": url_for("oauth.oauth_authorize", _external=True),
                "token_url": url_for("oauth.oauth_token", _external=True),
            },
        }
        json_qr_data = json.dumps(qr_data)
        qr.add_data(json_qr_data)
        qr.make(fit=True)
        qr_img = qr.make_image()

        output = StringIO()
        qr_img._img.save(output, format="png")
        im_data = output.getvalue()

        return "data:image/png;base64,{0}".format(base64.b64encode(im_data))
Esempio n. 20
0
    def _process(self):
        config = Config.getInstance()

        # QRCode (Version 6 with error correction L can contain up to 106 bytes)
        qr = qrcode.QRCode(
            version=6,
            error_correction=qrcode.constants.ERROR_CORRECT_M,
            box_size=4,
            border=1
        )

        checkin_app_client_id = config.getCheckinAppClientId()
        checkin_app = OAuthApplication.find_first(client_id=checkin_app_client_id)

        base_url = config.getBaseSecureURL() if config.getBaseSecureURL() else config.getBaseURL()
        qr_data = {
            "event_id": self._conf.getId(),
            "title": self._conf.getTitle(),
            "date": format_date(self._conf.getAdjustedStartDate()),
            "server": {
                "baseUrl": base_url,
                "consumerKey": checkin_app.client_id,
                "auth_url": url_for('oauth.oauth_authorize', _external=True),
                "token_url": url_for('oauth.oauth_token', _external=True)
            }
        }
        json_qr_data = json.dumps(qr_data)
        qr.add_data(json_qr_data)
        qr.make(fit=True)
        qr_img = qr.make_image()

        output = BytesIO()
        qr_img.save(output)
        output.seek(0)

        return send_file('config.png', output, 'image/png')
Esempio n. 21
0
 def validate_name(self, field):
     query = OAuthApplication.find(name=field.data)
     if self.application:
         query = query.filter(db.func.lower(OAuthApplication.name) != self.application.name.lower())
     if query.count():
         raise ValidationError(_("There is already an application with this name"))
Esempio n. 22
0
 def _process(self):
     applications = OAuthApplication.find().order_by(
         db.func.lower(OAuthApplication.name)).all()
     return WPOAuthAdmin.render_template('apps.html',
                                         applications=applications)
Esempio n. 23
0
 def _checkParams(self):
     self.application = OAuthApplication.get(request.view_args['id'])
Esempio n. 24
0
 def _process_args(self):
     self.application = OAuthApplication.get(request.view_args['id'])
Esempio n. 25
0
def _create_oauth_apps():
    for sat in SystemAppType:
        if sat != SystemAppType.none:
            db.session.add(
                OAuthApplication(system_app_type=sat, **sat.default_data))
    db.session.commit()
Esempio n. 26
0
 def _process_args(self):
     self.application = OAuthApplication.get(request.view_args['id'])
Esempio n. 27
0
def test_save_token_no_application(dummy_application, dummy_request, token_data):
    dummy_request.client.client_id = unicode(uuid4())
    assert not OAuthApplication.find(client_id=dummy_request.client.client_id).count()
    with pytest.raises(NoResultFound):
        save_token(token_data, dummy_request)
Esempio n. 28
0
 def _checkParams(self):
     self.application = OAuthApplication.get(request.view_args['id'])
Esempio n. 29
0
 def _process(self):
     applications = OAuthApplication.find().order_by(db.func.lower(OAuthApplication.name)).all()
     return WPOAuthAdmin.render_template('apps.html', applications=applications)
Esempio n. 30
0
 def _checkParams(self):
     try:
         UUID(hex=request.args['client_id'])
     except ValueError:
         raise NoResultFound
     self.application = OAuthApplication.find_one(client_id=request.args['client_id'])