コード例 #1
0
    def setup(self, researcher=True, apikey=True, study=True):
        """
        This function is used to initialize that database for each test.

        This was written in this fashion because of a known issue with the HybridTest class that does not consistently
        use database changes that persist between tests
        """
        if apikey and not researcher:
            raise Exception("invalid setup criteria")
        if researcher:
            self.researcher = Researcher.create_with_password(
                username=TEST_USERNAME, password=TEST_PASSWORD)
        if apikey:
            self.api_key = ApiKey.generate(self.researcher,
                                           has_tableau_api_permissions=True)
            self.api_key_public = self.api_key.access_key_id
            self.api_key_private = self.api_key.access_key_secret_plaintext
        if study:
            self.study = Study.create_with_object_id(
                device_settings=DeviceSettings(),
                encryption_key=TEST_STUDY_ENCRYPTION_KEY,
                name=TEST_STUDY_NAME,
            )
            if researcher:
                self.study_relation = StudyRelation(
                    study=self.study,
                    researcher=self.researcher,
                    relationship="researcher",
                ).save()
コード例 #2
0
def edit_study(study_id=None):
    # get the data points for display for all researchers in this study
    query = Researcher.filter_alphabetical(study_relations__study_id=study_id).values_list(
        "id", "username", "study_relations__relationship", "site_admin"
    )

    # transform raw query data as needed
    listed_researchers = []
    for pk, username, relationship, site_admin in query:
        listed_researchers.append((
            pk,
            username,
            "Site Admin" if site_admin else relationship.replace("_", " ").title(),
            site_admin
        ))

    return render_template(
        'edit_study.html',
        study=Study.objects.get(pk=study_id),
        administerable_researchers=get_administerable_researchers(),
        allowed_studies=get_researcher_allowed_studies(),
        listed_researchers=listed_researchers,
        is_admin=researcher_is_an_admin(),
        redirect_url='/edit_study/{:s}'.format(study_id),
        session_researcher=get_session_researcher(),
    )
コード例 #3
0
ファイル: index.py プロジェクト: jakehemmerle/beiwe-backend
def refresh_data_access_credentials(freq, ssm_client=None, webserver=False):
    """
    Refresh the data access credentials for a particular BATCH USER user and upload them
    (encrypted) to the AWS Parameter Store. This enables AWS batch jobs to get the
    credentials and thereby access the data access API (DAA).
    :param freq: string, one of 'hourly' | 'daily' | 'weekly' | 'monthly' | 'manually'
    This is used to know what call the data access credentials on AWS.
    """

    # Get or create Researcher with no password. This means that nobody can log in as this
    # Researcher in the web interface.
    researcher_name = 'BATCH USER {}'.format(freq)
    mock_researchers = Researcher.objects.filter(username=researcher_name)
    if not mock_researchers.exists():
        mock_researcher = Researcher.create_without_password(researcher_name)
    else:
        mock_researcher = mock_researchers.get()
        mock_researcher.save()

    # Ensure that the Researcher is attached to all Studies. This allows them to access all
    # data via the DAA.
    for study in Study.objects.all():
        StudyRelation.objects.get_or_create(
            study=study,
            researcher=mock_researcher,
            relationship=ResearcherRole.researcher,
            is_batch_user=True,
        )

    # Reset the credentials. This ensures that they aren't stale.
    access_key, secret_key = mock_researcher.reset_access_credentials()

    if not webserver:
        generic_config = get_generic_config()
    else:
        generic_config = get_eb_config()

    # Append the frequency to the SSM (AWS Systems Manager) names. This ensures that the
    # different frequency jobs' keys do not overwrite each other.
    access_key_ssm_name = '{}-{}'.format(generic_config['access_key_ssm_name'],
                                         freq)
    secret_key_ssm_name = '{}-{}'.format(generic_config['secret_key_ssm_name'],
                                         freq)

    # Put the credentials (encrypted) into AWS Parameter Store
    if not ssm_client:
        ssm_client = get_boto_client('ssm')
    ssm_client.put_parameter(
        Name=access_key_ssm_name,
        Value=access_key,
        Type='SecureString',
        Overwrite=True,
    )
    ssm_client.put_parameter(
        Name=secret_key_ssm_name,
        Value=secret_key,
        Type='SecureString',
        Overwrite=True,
    )
コード例 #4
0
def get_administerable_researchers():
    """ Site admins see all researchers, study admins see researchers on their studies. """
    researcher_admin = get_session_researcher()
    if researcher_admin.site_admin:
        relevant_researchers = Researcher.get_all_researchers_by_username()
    else:
        relevant_researchers = researcher_admin.get_administered_researchers_by_username()
    return relevant_researchers
コード例 #5
0
def migrate_admins():
    
    d_admin_list = []
    
    # Build all Researchers
    for m_admin in MAdminSet.iterator():
        with error_handler:
            d_admin = DAdmin(
                username=m_admin['_id'],
                admin=m_admin['system_admin'],
                access_key_id=m_admin['access_key_id'] or None,  # access_key_id is unique and therefore nullable
                access_key_secret=m_admin['access_key_secret'] or '',
                access_key_secret_salt=m_admin['access_key_secret_salt'] or '',
                password=m_admin['password'] or 'NoPassword',
                salt=m_admin['salt'],
                deleted=False,
            )
            
            # Validate the Researcher and add it to the bulk_create list
            d_admin.full_clean()
            d_admin_list.append(d_admin)
    
    # Bulk_create the list of Researchers
    DAdmin.objects.bulk_create(d_admin_list)
    
    # Now that the Researchers have primary keys, fill in the Study-Researcher ManyToMany relationship
    # Create a mapping from Researcher's username to primary key
    admin_username_to_pk_dict = dict(DAdmin.objects.values_list('username', 'pk'))
    
    d_study_admin_relation_list = []
    for study_id, admin_username in d_study_admin_list:
        with error_handler:
            try:
                admin_id = admin_username_to_pk_dict[admin_username]
            except KeyError:
                # study_name = DStudy.objects.get(pk=study_id).name
                print('Admin {} is referenced by a Study but does not exist.'.format(admin_username))
                continue
            # Populate a list of database objects in the Study-Researcher relationship table
            new_relation = DAdmin.studies.through(study_id=study_id, researcher_id=admin_id)
            d_study_admin_relation_list.append(new_relation)
        
    # Bulk_create the Study-Researcher relationship objects
    with error_handler:
        DAdmin.studies.through.objects.bulk_create(d_study_admin_relation_list)
コード例 #6
0
def edit_study(study_id=None):
    study = Study.objects.get(pk=study_id)
    all_researchers = Researcher.get_all_researchers_by_username()
    return render_template(
        'edit_study.html',
        study=study,
        all_researchers=all_researchers,
        allowed_studies=get_admins_allowed_studies(),
        system_admin=admin_is_system_admin(),
        redirect_url='/edit_study/{:s}'.format(study_id),
    )
コード例 #7
0
def login():
    """ Authenticates administrator login, redirects to login page if authentication fails. """
    if request.method == 'POST':
        username = request.values["username"]
        password = request.values["password"]
        if Researcher.check_password(username, password):
            admin_authentication.log_in_admin(username)
            return redirect("/choose_study")
        else:
            flash("Incorrect username & password combination; try again.", 'danger')

    return redirect("/")
コード例 #8
0
def manage_researchers():
    researcher_list = []
    for researcher in Researcher.get_all_researchers_by_username():
        allowed_studies = Study.get_all_studies_by_name().filter(researchers=researcher).values_list('name', flat=True)
        researcher_list.append((researcher.as_native_python(), list(allowed_studies)))

    return render_template(
        'manage_researchers.html',
        admins=json.dumps(researcher_list),
        allowed_studies=get_admins_allowed_studies(),
        system_admin=admin_is_system_admin()
    )
コード例 #9
0
def reset_admin_password():
    username = session['admin_username']
    current_password = request.values['current_password']
    new_password = request.values['new_password']
    confirm_new_password = request.values['confirm_new_password']
    if not Researcher.check_password(username, current_password):
        flash("The Current Password you have entered is invalid", 'danger')
        return redirect('/manage_credentials')
    if not check_password_requirements(new_password, flash_message=True):
        return redirect("/manage_credentials")
    if new_password != confirm_new_password:
        flash("New Password does not match Confirm New Password", 'danger')
        return redirect('/manage_credentials')
    Researcher.objects.get(username=username).set_password(new_password)
    flash("Your password has been reset!", 'success')
    return redirect('/manage_credentials')
コード例 #10
0
def create_new_researcher():
    if request.method == 'GET':
        return render_template('create_new_researcher.html')

    # Drop any whitespace or special characters from the username
    username = ''.join(e for e in request.form.get('admin_id', '')
                       if e.isalnum())
    password = request.form.get('password', '')

    if Researcher.objects.filter(username=username).exists():
        flash(f"There is already a researcher with username {username}",
              'danger')
        return redirect('/create_new_researcher')
    else:
        researcher = Researcher.create_with_password(username, password)
        return redirect('/edit_researcher/{:d}'.format(researcher.pk))
コード例 #11
0
    def test_all_routes(self):
        """
        Tests urls
        """
        app2 = subdomain("frontend")
        app2.register_blueprint(admin_pages.admin_pages)

        long_encryption_key = 'aabbccddefggiijjkklmnoppqqrrsstt'

        researcher = Researcher.create_with_password('test_user',
                                                     'test_password')
        researcher.admin = True
        researcher.reset_access_credentials()
        researcher.save()

        study = Study.create_with_object_id(name='test_study',
                                            encryption_key=long_encryption_key)
        researcher.studies.add(study)

        self.selenium.get("localhost:54321")
        self.selenium.find_element_by_name('username').send_keys('test_user')
        self.selenium.find_element_by_name('password').send_keys(
            'test_password')
        self.selenium.find_element_by_name('submit').click()

        for rule in app2.url_map.iter_rules():
            str_rule = str(rule)
            self.assertIn(str_rule, ADMIN_PAGES)

            if ADMIN_PAGES[str_rule]['method'] == 'get':
                self.selenium.get("localhost:54321" + str_rule)
            elif ADMIN_PAGES[str_rule]['method'] == 'post':
                continue
            elif ADMIN_PAGES[str_rule]['method'] == 'get_param':
                str_rule_formatted = re.sub(r"<\w+:\w+>", str(study.id),
                                            str_rule)
                self.selenium.get("localhost:54321" + str_rule_formatted)
            else:
                continue

            response = self.determine_errors()
            self.assertEqual(response, '200')
コード例 #12
0
 def handle(self, *args, **options):
     new_researcher = Researcher.create_with_password("admin", "admin")
     new_researcher.elevate_to_site_admin()
コード例 #13
0
ファイル: tests.py プロジェクト: onnela-lab/beiwe-backend
 def test_researcher_mongo_integrity(self):
     researcher = Researcher(**self.translated_reference_researcher)
     x = compare_dictionaries(self.translated_reference_researcher,
                              researcher.as_unpacked_native_python(),
                              ignore=["deleted", "id"])
     self.assertTrue(x)
コード例 #14
0
from sys import path
path.insert(0, abspath(__file__).rsplit('/', 2)[0])

import itertools
import requests

from config.constants import ResearcherRole
from pprint import pprint
from data_access_api_reference import download_data
from database.study_models import Study
from database.user_models import Researcher, StudyRelation

try:
    test_user = Researcher.objects.get(username="******")
except Researcher.DoesNotExist:
    test_user = Researcher.create_without_password("test_user")

download_data.API_URL_BASE = "http://127.0.0.1:8080/"
debugging_study = Study.objects.get(name='debugging study')

download_data.RUNNING_IN_TEST_MODE = True
download_data.SKIP_DOWNLOAD = True


def helper(allowed_on_study, corrupt_access_id, corrupt_secret_key,
           researcher_admin, site_admin, batch_user, study_as_object_id,
           wrong_access_key, wrong_secret_key, is_test_study,
           corrupt_study_object_id):
    if not study_as_object_id and corrupt_study_object_id:
        # invalid test scenario, skip
        return