def test_signal_when_feature_is_missing(self):
    expected_feature = 'newfeature'

    @feature_flags.missing_feature.connect
    def signal_handler(obj, feature):
      app.config[FLAG_CONFIG][feature] = True
      assert feature == expected_feature, u'Signal received wrong feature %s' % feature

    with self.app.test_request_context('/'):
      feature_flags.is_active(expected_feature)
      assert app.config[FLAG_CONFIG][expected_feature], u'Missing feature handler was not called'
Example #2
0
    def test_signal_when_feature_is_missing(self):
        expected_feature = 'newfeature'

        @feature_flags.missing_feature.connect
        def signal_handler(obj, feature):
            app.config[FLAG_CONFIG][feature] = True
            assert feature == expected_feature, u'Signal received wrong feature %s' % feature

        with self.app.test_request_context('/'):
            feature_flags.is_active(expected_feature)
            assert app.config[FLAG_CONFIG][
                expected_feature], u'Missing feature handler was not called'
Example #3
0
    def test_deferred_initialization_works(self):

        test_app = Flask(__name__)
        test_app.config[FLAG_CONFIG] = {FEATURE_NAME: True}

        feature_flagger = feature_flags.FeatureFlag()
        feature_flagger.init_app(test_app)

        with test_app.test_request_context("/"):
            # Test a couple basic cases to make sure we're actually exercising the code
            # when we make these calls
            self.assertTrue(feature_flags.is_active(FEATURE_NAME))
            self.assertFalse(feature_flags.is_active("DOES_NOT_EXIST"))
  def test_deferred_initialization_works(self):

    test_app = Flask(__name__)
    test_app.config[FLAG_CONFIG] = {FEATURE_NAME: True}

    feature_flagger = feature_flags.FeatureFlag()
    feature_flagger.init_app(test_app)

    with test_app.test_request_context("/"):
      # Test a couple basic cases to make sure we're actually exercising the code
      # when we make these calls
      self.assertTrue(feature_flags.is_active(FEATURE_NAME))
      self.assertFalse(feature_flags.is_active("DOES_NOT_EXIST"))
Example #5
0
def _record_audit_information(response):
    """Update the audit db table to record the current request.

    :param response: the response to modify, of type response_class()
    :return: the same response, unmodified.
    """
    if not audit_method.is_active(request.method):
        current_app.logger.debug("Skipping audit record for method '%s'" % request.method)
        return response
    else:
        current_app.logger.debug("Filling audit record for method '%s'" % request.method)

    from app import db
    try:
        record = Auditing()
        # Add any exception that may have occurred.
        record.exception_msg = str(flask_g.get("exception_msg"))
        # Add the correlation ID.
        record.correlation_id = get_correlation_id()
        # Add referring service
        record.referring_service = flask_g.get("referring_service")
        # Add request data to the record
        _fill_in_request(record)
        # Add response data to the record
        _fill_in_response(record, response)
        # The current session (db.session) may be in a broken state, so we're better off
        # creating a new session.  Luckily, sessions carry their factory around.
        session = db.session.session_factory()
        session.add(record)
        session.commit()
    except Exception:
        current_app.logger.exception("Failed to record auditing information")
    return response
    def test_buyer_pages_ok_if_logged_in_as_buyer(self, render_component):
        props = {
            "team": {
                "currentUserName": "******",
                "teamName": "My Team name",
                "members": [],
                "teamBriefs": {
                    "all": [],
                    "draft": [],
                    "live": [],
                    "closed": []
                },
                "briefs": {
                    "all": [],
                    "draft": [],
                    "live": [],
                    "closed": []
                }
            }
        }
        render_component.return_value.get_props.return_value = props

        with self.app.app_context():
            self.login_as_buyer()
            res = self.client.get(self.expand_path('/buyers'))
            page_text = res.get_data(as_text=True)
            assert res.status_code == 200
            assert 'private' in res.headers['Cache-Control']
            if feature.is_active('TEAM_VIEW'):
                assert 'My Team' in page_text
                assert 'My Team name' in page_text
Example #7
0
def run_async(function, deamon=True, **kwargs):
    app = current_app._get_current_object()

    if feature.is_active(FEATURE_MULTITHREADING):
        kwargs = copy(kwargs)
        kwargs["app"] = app

        threading.Thread(target=function, kwargs=kwargs, daemon=deamon).start()
    else:
        function(app=app, **kwargs)
Example #8
0
 def run(self, threshold=0.4):
     self.log.info(f'Starting new voting. vacancies = {self.vacancies}')
     self.log.debug(
         f'candidates = {sorted(self.candidates, key=attrgetter("id"))}')
     if feature.is_active(FEATURE_STV_REJECTION):
         self.reject_candidates(threshold)
     while len(self.candidates) > 0 and len(self.elected) < self.vacancies:
         self.round()
     results = {
         candidate: candidate.score[-1][0]
         for candidate in self.candidates
     }
     self.discarded += [
         candidate for candidate in sorted(results, key=results.get)
     ]
     self.log.info(f'Voting finished')
     self.log.info(f'elected = {self.elected}')
     self.log.info(f'discarded = {self.discarded}')
     if feature.is_active(FEATURE_STV_REJECTION):
         self.log.info(f'rejected = {self.rejected}')
     return self.elected, self.discarded, self.rejected
Example #9
0
def get_role_types():
    logger = logging.getLogger(__name__)
    
    conn = connect.get_connection()
    cur = conn.cursor(cursor_factory=psycopg2.extras.RealDictCursor)
    cur.execute("SELECT displayname, id "
                "FROM codesystems "
                "WHERE name = 'OrganisationRole' "
                "ORDER BY displayname;")
    
    rows = cur.fetchall()
    result = []
    
    for row in rows:
        role_code = row['id']
        role_display_name = row['displayname']
        link_self_href = str.format('{0}/role-types/{1}',
                                    app.config['APP_HOSTNAME'],
                                    role_code)
        link_search_primary_role_code_href = str.format('{0}/organisations?primaryRoleCode={1}',
                                                        app.config['APP_HOSTNAME'],
                                                        role_code)
        link_search_role_code_href = str.format('{0}/organisations?roleCode={1}',
                                                app.config['APP_HOSTNAME'],
                                                role_code)
        result_data = {
            'name': role_display_name,
            'code': role_code,
            'links': [{
                'rel': 'self',
                'href': link_self_href
            }, {
                'rel': 'organisations.searchByRoleCode',
                'href': link_search_role_code_href
            }]
        }
        
        if not feature.is_active('SuppressPrimaryRoleSearchLink'):
            result_data['links'].append({
                'rel': 'organisations.searchByPrimaryRoleCode',
                'href': link_search_primary_role_code_href
            })
        
        result.append(result_data)
    
    logger.debug("Returning: {result}".format(result=result))
    
    return result
    def get_briefs(self):
        if not self.validate():
            raise ValueError("Invalid form")

        statuses = self.status.data or tuple(id for id, label in self.status.choices)
        lots = self.lot.data or tuple(id for id, label in self.lot.choices)

        # disable framework filtering when digital marketplace framework is live
        kwargs = {} if flask_featureflags.is_active('DM_FRAMEWORK') else {"framework": self._framework_slug}

        return self._data_api_client.find_briefs(
            status=",".join(statuses),
            lot=",".join(lots),
            page=self.page.data,
            per_page=75,
            human=True,
            **kwargs
        )
Example #11
0
def updateGlobalSession():
    ''' updates the Marvin config with the global Flask session '''

    # check if mpl versions in session
    if 'versions' not in current_session:
        setGlobalSession()
    elif 'drpver' not in current_session or \
         'dapver' not in current_session:
        set_session_versions(config.release)
    elif 'release' not in current_session:
        current_session['release'] = config.release
    elif 'release' in current_session:
        if current_session['release'] not in config._allowed_releases:
            current_session['release'] = config.release

    # reset the session versions if on public site
    if feature.is_active('public'):
        current_session['versions'] = update_allowed()
Example #12
0
    def get_briefs(self):
        if not self.validate():
            raise ValueError("Invalid form")

        statuses = self.status.data or tuple(
            id for id, label in self.status.choices)
        lots = self.lot.data or tuple(id for id, label in self.lot.choices)

        # disable framework filtering when digital marketplace framework is live
        kwargs = {} if flask_featureflags.is_active('DM_FRAMEWORK') else {
            "framework": self._framework_slug
        }

        return self._data_api_client.find_briefs(status=",".join(statuses),
                                                 lot=",".join(lots),
                                                 page=self.page.data,
                                                 per_page=75,
                                                 human=True,
                                                 **kwargs)
Example #13
0
def get_role_type_by_id(role_id):
    sql = "SELECT displayname, id " \
          "FROM codesystems " \
          "WHERE name = 'OrganisationRole' " \
          "AND id = UPPER(%s);"
    
    data = (role_id,)
    
    cur = connect.get_cursor()
    cur.execute(sql, data)
    
    returned_row = cur.fetchone()
    
    role_code = returned_row['id']
    role_display_name = returned_row['displayname']
    link_self_href = str.format('{0}/role-types/{1}',
                                app.config['APP_HOSTNAME'],
                                role_code)
    link_search_primary_role_code_href = str.format('{0}/organisations?primaryRoleCode={1}',
                                                    app.config['APP_HOSTNAME'],
                                                    role_code)
    link_search_role_code_href = str.format('{0}/organisations?roleCode={1}',
                                            app.config['APP_HOSTNAME'],
                                            role_code)
    result = {
        'name': role_display_name,
        'code': role_code,
        'links': [{
            'rel': 'self',
            'href': link_self_href
        }, {
            'rel': 'searchOrganisationsWithThisRole',
            'href': link_search_role_code_href
        }]
    }
    
    if not feature.is_active('SuppressPrimaryRoleSearchLink'):
        result['links'].append({
            'rel': 'organisations.searchByPrimaryRoleCode',
            'href': link_search_primary_role_code_href
        })
    
    return result
Example #14
0
def redirect_logged_in_user(next_url=None):
    site_url_prefix = current_app.config['URL_PREFIX']
    if not site_url_prefix:
        site_url_prefix = '/'
    if current_user.is_authenticated:
        if next_url and next_url.startswith(site_url_prefix):
            return redirect(next_url)

        if current_user.role == 'buyer':
            return redirect(url_for('buyers.buyer_dashboard'))

        if current_user.role == 'supplier':
            if feature.is_active('DM_FRAMEWORK'):
                return redirect(url_for('.list_opportunities', framework_slug='digital-marketplace'))
            return redirect(url_for('.list_opportunities', framework_slug='digital-service-professionals'))

        if current_user.role == 'applicant':
            return redirect('/sellers/application')

    return redirect(url_for('.index'))
Example #15
0
    def decorated(*args, **kwargs):
        try:
            return f(*args, **kwargs)

        except Exception as ex:

            flask_g.exception_msg = traceback.format_exc()

            current_app.logger.exception(ex)

            if isinstance(ex, NotFound):
                return {'Error': ex.args[0]}, 404
            if isinstance(ex, BadRequest):
                return {'Error': ex.description}, 400

            return {
                'Error':
                ex.args[0] if feature.is_active('propagates_exception') else
                'Internal Server Error'
            }, 500
Example #16
0
def register():
    if current_user.is_authenticated:
        return redirect(url_for('base.index'))
    form = RegisterForm()
    if form.validate_on_submit():
        fellow = lada.fellow.register(email=form.email.data,
                                      password=form.password.data,
                                      name=form.name.data,
                                      surname=form.surname.data,
                                      studentid=form.studentid.data,
                                      newsletter=news_flags[NEWS_ALL])
        log.info(f"New fellow registered: {fellow}")
        if feature.is_active(FEATURE_EMAIL_VERIFICATION):
            send_verification_email(fellow)
            flash(
                'Registration successful. Please check your e-mail, including SPAM, for verification e-mail.'
            )
        else:
            fellow.set_verified(True)
            flash('Registration successful.')
        return redirect(url_for('fellow.login'))
    return render_template('fellow/register.html', form=form)
def buyer_overview():
    email_domain = current_user.email_address.split('@')[-1]
    teammembers_response = data_api_client.req.teammembers(email_domain).get()

    teammembers = list(sorted(teammembers_response['teammembers'], key=lambda tm: tm['name']))

    rendered_component = render_component(
        'bundles/BuyerDashboard/BuyerDashboardWidget.js',
        {
            'teammembers': teammembers,

            'meta': {
                'domain': email_domain,
                'teamname': teammembers_response['teamname']
            },
            'flag': feature.is_active('TEAM_VIEW')
        }
    )

    return render_template(
        '_react.html',
        page_title="Dashboard",
        component=rendered_component,
    )
 def test_flag_inactive(self):
   self.assertFalse(feature_flags.is_active("INACTIVE"))
 def test_flag_not_found(self):
   self.assertFalse(feature_flags.is_active("NOT_FOUND"))
def view_based_feature_flag():
  if feature_flags.is_active(FEATURE_NAME):
    return FEATURE_IS_ON
  else:
    return FEATURE_IS_OFF
 def test_flags(self):
     with self.flask.app_context():
         assert flask_featureflags.is_active('YES')
         assert not flask_featureflags.is_active('NO')
Example #22
0
  def test_checking_is_active_outside_request_context_returns_false(self):

    self.assertFalse(feature_flags.is_active("BOGUS_FEATURE_FLAG"))
Example #23
0
 def test_flag_not_found(self):
   self.assertFalse(feature_flags.is_active('not_found'))
Example #24
0
def view_based_feature_flag():
    if feature_flags.is_active(FEATURE_NAME):
        return FEATURE_IS_ON
    else:
        return FEATURE_IS_OFF
 def test_flag_active(self):
   self.assertTrue(feature_flags.is_active("ACTIVE"))
def buyer_dashboard(view=None):
    if feature.is_active('TEAM_VIEW'):
        current_user_name = current_user.name
        email_domain = current_user.email_address.split('@')[-1]
        teammembers_response = data_api_client.req.teammembers(email_domain).get()
        teamname = teammembers_response['teamname']
        teammembers = list(sorted(teammembers_response['teammembers'], key=lambda tm: tm['name']))

        team_briefs = data_api_client.req.briefs().teammembers(email_domain).get()

        # team_draft_briefs = add_unanswered_counts_to_briefs(
        #     [brief for brief in team_briefs if brief['status'] == 'draft'], content_loader)
        team_draft_briefs = []
        team_live_briefs = [brief for brief in team_briefs if brief['status'] == 'live']
        team_closed_briefs = [brief for brief in team_briefs if brief['status'] == 'closed']

        user_briefs = data_api_client.find_briefs(current_user.id).get('briefs', [])
        draft_briefs = add_unanswered_counts_to_briefs(
            [brief for brief in user_briefs if brief['status'] == 'draft'], content_loader)
        live_briefs = [brief for brief in user_briefs if brief['status'] == 'live']
        closed_briefs = [brief for brief in user_briefs if brief['status'] == 'closed']

        props = {
            "flag": feature.is_active('TEAM_VIEW'),
            "team": {
                "currentUserName": current_user_name,
                "teamName": teamname,
                "members": teammembers,
                "teamBriefs": {
                    "draft": team_draft_briefs,
                    "live": team_live_briefs,
                    "closed": team_closed_briefs
                },
                "briefs": {
                    "draft": draft_briefs,
                    "live": live_briefs,
                    "closed": closed_briefs
                }
            }
        }

        rendered_component = render_component(
            'bundles/BuyerDashboard/BuyerDashboardWidget.js',
            props
        )

        return render_template(
            '_react.html',
            page_title="Dashboard",
            component=rendered_component,
        )

    else:
        def get_teamname():
            email_domain = current_user.email_address.split('@')[-1]
            teammembers_response = data_api_client.req.teammembers(email_domain).get()
            teammembers = list(sorted(teammembers_response['teammembers'], key=lambda tm: tm['name']))
            return teammembers_response['teamname']

        user_briefs = data_api_client.find_briefs(current_user.id).get('briefs', [])
        draft_briefs = add_unanswered_counts_to_briefs([brief for brief in user_briefs if brief['status'] == 'draft'],
                                                       content_loader)
        live_briefs = [brief for brief in user_briefs if brief['status'] == 'live']
        closed_briefs = [brief for brief in user_briefs if brief['status'] == 'closed']

        return render_template(
            'buyers/dashboard-briefs.html',
            draft_briefs=draft_briefs,
            live_briefs=live_briefs,
            closed_briefs=closed_briefs,
            teamname=get_teamname()
        )
Example #27
0
 def test_flags(self):
     with self.flask.app_context():
         assert flask_featureflags.is_active('YES')
         assert not flask_featureflags.is_active('NO')
  def test_checking_is_active_outside_request_context_returns_false(self):

    self.assertFalse(feature_flags.is_active("BOGUS_FEATURE_FLAG"))
Example #29
0
 def test_flag_active(self):
   self.assertTrue(feature_flags.is_active('active'))
Example #30
0
def contract_review(framework_slug, agreement_id):
    framework = get_framework(data_api_client,
                              framework_slug,
                              allowed_statuses=['standstill', 'live'])
    # if there's no frameworkAgreementVersion key it means we're pre-G-Cloud 8 and shouldn't be using this route
    if not framework.get('frameworkAgreementVersion'):
        abort(404)
    supplier_framework = return_supplier_framework_info_if_on_framework_or_abort(
        data_api_client, framework_slug)
    agreement = data_api_client.get_framework_agreement(
        agreement_id)['agreement']
    check_agreement_is_related_to_supplier_framework_or_abort(
        agreement, supplier_framework)

    # if framework agreement doesn't have a name or a role or the agreement file, then 404
    if not (agreement.get('signedAgreementDetails')
            and agreement['signedAgreementDetails'].get('signerName')
            and agreement['signedAgreementDetails'].get('signerRole')
            and agreement.get('signedAgreementPath')):
        abort(404)

    agreements_bucket = s3.S3(current_app.config['DM_AGREEMENTS_BUCKET'])
    signature_page = agreements_bucket.get_key(
        agreement['signedAgreementPath'])

    form = ContractReviewForm()
    form_errors = None

    if request.method == 'POST':
        if form.validate_on_submit():
            data_api_client.sign_framework_agreement(
                agreement_id, current_user.email_address,
                {'uploaderUserId': current_user.id})

            try:
                email_body = render_template(
                    'emails/framework_agreement_with_framework_version_returned.html',
                    framework_name=framework['name'],
                    framework_slug=framework['slug'],
                    framework_live_date=content_loader.get_message(
                        framework_slug,
                        'dates')['framework_live_date'],  # noqa
                )

                send_email(
                    returned_agreement_email_recipients(supplier_framework),
                    email_body,
                    current_app.config['DM_MANDRILL_API_KEY'],
                    'Your {} signature page has been received'.format(
                        framework['name']),
                    current_app.config["DM_GENERIC_NOREPLY_EMAIL"],
                    current_app.config["FRAMEWORK_AGREEMENT_RETURNED_NAME"],
                    ['{}-framework-agreement'.format(framework_slug)],
                )
            except MandrillException as e:
                current_app.logger.error(
                    "Framework agreement email failed to send. "
                    "error {error} supplier_id {supplier_id} email_hash {email_hash}",
                    extra={
                        'error': six.text_type(e),
                        'supplier_id': current_user.supplier_id,
                        'email_hash': hash_email(current_user.email_address)
                    })
                abort(503, "Framework agreement email failed to send")

            session.pop('signature_page', None)

            flash(
                'Your framework agreement has been returned to the Crown Commercial Service to be countersigned.',
                'success')

            if feature.is_active('CONTRACT_VARIATION'):
                # Redirect to contract variation if it has not been signed
                if (framework.get('variations')
                        and not supplier_framework['agreedVariations']):
                    variation_slug = list(framework['variations'].keys())[0]
                    return redirect(
                        url_for('.view_contract_variation',
                                framework_slug=framework_slug,
                                variation_slug=variation_slug))

            return redirect(
                url_for(".framework_dashboard", framework_slug=framework_slug))

        else:
            form_errors = [{
                'question': form['authorisation'].label.text,
                'input_name': 'authorisation'
            }]

    form.authorisation.description = u"I have the authority to return this agreement on behalf of {}.".format(
        supplier_framework['declaration']['nameOfOrganisation'])

    return render_template(
        "frameworks/contract_review.html",
        agreement=agreement,
        form=form,
        form_errors=form_errors,
        framework=framework,
        signature_page=signature_page,
        supplier_framework=supplier_framework,
    ), 400 if form_errors else 200
Example #31
0
 def test_flag_inactive(self):
   self.assertFalse(feature_flags.is_active('inactive'))