def test_remove_object_from_permission_bad_org(cursor, valueset,
                                               new_permission, new_forecast,
                                               permorg):
    org = valueset[0][0]
    user = valueset[1][0]
    role = valueset[2][0]
    auth0id = user['auth0_id']
    if permorg:
        permission = new_permission('read', 'forecasts', False, org=org)
    else:
        permission = new_permission('read', 'forecasts', False)
    updateperm = new_permission('update', 'permissions', False, org=org)
    cursor.execute(
        'INSERT INTO role_permission_mapping (role_id, permission_id) '
        'VALUES (%s, %s)', (role['id'], updateperm['id']))
    fx = new_forecast(org=org)
    cursor.executemany(
        'INSERT INTO permission_object_mapping (permission_id, object_id) '
        'VALUES (%s, %s)', [(permission['id'], fx['id']),
                            (updateperm['id'], permission['id'])])
    objid = str(bin_to_uuid(fx['id']))
    permid = str(bin_to_uuid(permission['id']))
    with pytest.raises(pymysql.err.OperationalError) as e:
        cursor.callproc('remove_object_from_permission',
                        (auth0id, objid, permid))
    assert e.value.args[0] == 1142
def test_remove_role_from_user(cursor, valueset, new_role, allow_revoke_roles,
                               new_user, new_permission, roleorg, userorg):
    org = valueset[0][0]
    user = valueset[1][0]
    auth0id = user['auth0_id']
    if roleorg:
        newrole = new_role(org=org)
    else:
        newrole = new_role()
    if userorg:
        newuser = new_user(org=org)
    else:
        newuser = new_user()
    cursor.execute(
        'INSERT INTO user_role_mapping (user_id, role_id) '
        'VALUES (%s, %s)', (newuser['id'], newrole['id']))
    uid = str(bin_to_uuid(newuser['id']))
    rid = str(bin_to_uuid(newrole['id']))
    cursor.execute(
        'SELECT COUNT(role_id) FROM arbiter_data.user_role_mapping WHERE'
        ' user_id = UUID_TO_BIN(%s, 1)', uid)
    assert cursor.fetchone()[0] > 0
    cursor.callproc('remove_role_from_user', (auth0id, rid, uid))
    cursor.execute(
        'SELECT COUNT(role_id) FROM arbiter_data.user_role_mapping WHERE'
        ' user_id = UUID_TO_BIN(%s, 1)', uid)
    assert cursor.fetchone()[0] == 0
def test_remove_role_from_user_bad_org(cursor, valueset, new_role,
                                       allow_revoke_roles, new_user,
                                       new_permission, roleorg, userorg):
    org = valueset[0][0]
    user = valueset[1][0]
    role = valueset[2][0]
    auth0id = user['auth0_id']
    permission = new_permission('update', 'users', False, org=org)
    cursor.execute(
        'INSERT INTO role_permission_mapping (role_id, permission_id) '
        'VALUES (%s, %s)', (role['id'], permission['id']))
    if roleorg:
        newrole = new_role(org=org)
    else:
        newrole = new_role()
    if userorg:
        newuser = new_user(org=org)
    else:
        newuser = new_user()
    cursor.execute(
        'INSERT INTO permission_object_mapping (permission_id, object_id) '
        'VALUES (%s, %s)', (permission['id'], newuser['id']))
    cursor.execute(
        'INSERT INTO user_role_mapping (user_id, role_id) '
        'VALUES (%s, %s)', (newuser['id'], newrole['id']))
    uid = str(bin_to_uuid(newuser['id']))
    rid = str(bin_to_uuid(newrole['id']))
    with pytest.raises(pymysql.err.OperationalError) as e:
        cursor.callproc('remove_role_from_user', (auth0id, rid, uid))
    assert e.value.args[0] == 1142
def test_promote_user_to_org_admin_missing_roles(cursor, new_user):
    user = new_user()
    with pytest.raises(pymysql.err.IntegrityError) as e:
        cursor.callproc('promote_user_to_org_admin',
                        (str(bin_to_uuid(user['id'])),
                         str(bin_to_uuid(user['organization_id']))))
    assert e.value.args[0] == 1048
    assert e.value.args[1] == "Column 'role_id' cannot be null"
def role_user_obj(cursor, new_role, new_user, valueset):
    auth0id = valueset[1][0]['auth0_id']
    org = valueset[0][0]
    role = new_role(org=org)
    user = new_user(org=org)
    cursor.execute(
        'INSERT INTO user_role_mapping (user_id, role_id)'
        ' VALUES (%s, %s)', (user['id'], role['id']))
    return auth0id, str(bin_to_uuid(user['id'])), str(bin_to_uuid(role['id']))
def test_add_user_to_org_affiliated_user(dictcursor, new_user,
                                         new_organization):
    user = new_user()
    org = new_organization()
    strorgid = str(bin_to_uuid(org['id']))
    struserid = str(bin_to_uuid(user['id']))
    with pytest.raises(pymysql.err.OperationalError) as e:
        dictcursor.callproc('add_user_to_org', (struserid, strorgid))
    assert e.value.args[0] == 1142
    assert e.value.args[1] == 'Cannot add affiliated user to organization'
def test_list_aggregates(dictcursor, twosets):
    authid = twosets[0]['auth0_id']
    agg = twosets[9]
    dictcursor.callproc('list_aggregates', (authid, ))
    res = dictcursor.fetchall()
    assert ([str(bin_to_uuid(a['id']))
             for a in agg] == [r['aggregate_id'] for r in res])
    assert (set(res[0].keys()) - set(
        ('created_at', 'modified_at', 'provider', 'aggregate_id',
         'observations')) == set(agg[0].keys()) - set(
             ('organization_id', 'id', 'obs_list')))
    assert ([str(bin_to_uuid(o['id'])) for a in agg
             for o in a['obs_list']] == [
                 b['observation_id'] for r in res
                 for b in json.loads(r['observations'])
             ])
def permission_object_obj(permission_obj, cursor, new_forecast):
    auth0id, permstrid, permission = permission_obj
    fx = new_forecast()
    cursor.execute(
        'INSERT INTO permission_object_mapping (permission_id, object_id)'
        ' VALUES (%s, %s)', (permission['id'], fx['id']))
    return auth0id, permstrid, str(bin_to_uuid(fx['id']))
def perm_role_obj(role_obj, cursor, new_permission):
    auth0id, rolestrid, role = role_obj
    perm = new_permission('read', 'permissions', False)
    cursor.execute(
        'INSERT INTO role_permission_mapping (role_id, permission_id)'
        ' VALUES (%s, %s)', (role['id'], perm['id']))
    return auth0id, rolestrid, str(bin_to_uuid(perm['id']))
def test_delete_observation_from_aggregate(cursor, agg_obj,
                                           allow_update_aggregate):
    auth0id, aggid, agg = agg_obj
    # add more of same obs to verify all are deleted
    for i in range(1, 3):
        cursor.execute(
            'INSERT INTO arbiter_data.aggregate_observation_mapping '
            '(aggregate_id, observation_id, _incr) VALUES '
            '(UUID_TO_BIN(%s, 1), %s, %s)',
            (aggid, agg['obs_list'][0]['id'], i))
    cursor.execute(
        'SELECT COUNT(*) FROM arbiter_data.aggregate_observation_mapping '
        'WHERE aggregate_id = UUID_TO_BIN(%s, 1) and observation_id = %s',
        (aggid, agg['obs_list'][0]['id']))
    assert cursor.fetchone()[0] == 3
    cursor.execute(
        'SELECT COUNT(*) FROM arbiter_data.aggregate_observation_mapping '
        'WHERE aggregate_id = UUID_TO_BIN(%s, 1) and observation_id != %s',
        (aggid, agg['obs_list'][0]['id']))
    assert cursor.fetchone()[0] == 1

    cursor.callproc(
        'delete_observation_from_aggregate',
        (auth0id, aggid, str(bin_to_uuid(agg['obs_list'][0]['id']))))
    cursor.execute(
        'SELECT COUNT(*) FROM arbiter_data.aggregate_observation_mapping '
        'WHERE aggregate_id = UUID_TO_BIN(%s, 1) and observation_id=%s',
        (aggid, agg['obs_list'][0]['id']))
    assert cursor.fetchone()[0] == 0

    cursor.execute(
        'SELECT COUNT(*) FROM arbiter_data.aggregate_observation_mapping '
        'WHERE aggregate_id = UUID_TO_BIN(%s, 1) and observation_id != %s',
        (aggid, agg['obs_list'][0]['id']))
    assert cursor.fetchone()[0] == 1
def test_set_org_accepted_tou_org_dne(dictcursor):
    orgid = newuuid()
    with pytest.raises(pymysql.err.InternalError) as e:
        dictcursor.callproc('set_org_accepted_tou',
                            (str(bin_to_uuid(orgid)), ))
    assert e.value.args[0] == 1305
    assert e.value.args[1] == "Organization does not exist"
def test_delete_observation_from_aggregate_denied(cursor, agg_obj,
                                                  allow_delete_aggregate):
    auth0id, aggid, agg = agg_obj
    with pytest.raises(pymysql.err.OperationalError) as e:
        cursor.callproc(
            'delete_observation_from_aggregate',
            (auth0id, aggid, str(bin_to_uuid(agg['obs_list'][0]['id']))))
    assert e.value.args[0] == 1142
def test_add_user_to_org(dictcursor, new_organization, new_unaffiliated_user,
                         unaffiliated_organization):
    userid = new_unaffiliated_user()['id']
    dictcursor.execute('SELECT organization_id FROM users WHERE id = %s',
                       userid)
    user_orgid = dictcursor.fetchone()['organization_id']
    assert user_orgid == unaffiliated_organization['id']

    orgid = new_organization()['id']
    strorgid = str(bin_to_uuid(orgid))
    struserid = str(bin_to_uuid(userid))
    dictcursor.callproc('add_user_to_org', (struserid, strorgid))

    dictcursor.execute('SELECT organization_id FROM users WHERE id = %s',
                       userid)
    new_user_orgid = dictcursor.fetchone()['organization_id']
    assert new_user_orgid == orgid
def test_set_org_accepted_tou(dictcursor):
    orgid = newuuid()
    dictcursor.execute(
        'INSERT INTO organizations (id, name, accepted_tou)'
        'VALUES (%s, %s, FALSE)', (orgid, "OrgHasntacceptedTOU"))
    dictcursor.callproc('set_org_accepted_tou', (str(bin_to_uuid(orgid)), ))
    dictcursor.execute('SELECT accepted_tou FROM organizations WHERE id = %s',
                       orgid)
    assert dictcursor.fetchone()
def test_list_observations(dictcursor, twosets):
    authid = twosets[0]['auth0_id']
    obs = twosets[5]
    dictcursor.callproc('list_observations', (authid, ))
    res = dictcursor.fetchall()
    assert ([str(bin_to_uuid(ob['id']))
             for ob in obs] == [r['observation_id'] for r in res])
    assert (set(res[0].keys()) - set(
        ('created_at', 'modified_at', 'provider', 'observation_id')) == set(
            obs[0].keys()) - set(('organization_id', 'id')))
def test_list_reports(dictcursor, twosets):
    authid = twosets[0]['auth0_id']
    reports = twosets[7]
    dictcursor.callproc('list_reports', (authid, ))
    res = dictcursor.fetchall()
    assert ([str(bin_to_uuid(rep['id']))
             for rep in reports] == [r['report_id'] for r in res])
    assert (set(res[0].keys()) - set(
        ('created_at', 'modified_at', 'provider', 'report_id')) == (
            (set(reports[0].keys()) | set(('status', ))) - set(
                ('organization_id', 'id'))))
def test_grant_job_role(cursor, new_user, role, precreate):
    user = new_user()
    struserid = str(bin_to_uuid(user['id']))
    if precreate is not None:
        cursor.callproc(precreate, (user['organization_id'], ))

    cursor.callproc('grant_job_role', (struserid, role))
    cursor.execute(
        'SELECT 1 FROM user_role_mapping WHERE user_id = %s AND role_id = '
        '(SELECT id FROM roles WHERE name = %s AND organization_id = %s)',
        (user['id'], role, user['organization_id']))
    assert cursor.fetchone()[0]
def test_promote_user_to_org_admin_external_user(cursor, new_user):
    # depends on the roles provided by create_organization
    cursor.callproc('create_organization', ('test_org', ))
    cursor.execute('SELECT BIN_TO_UUID(id, 1) FROM arbiter_data.organizations '
                   'WHERE name = "test_org"')
    orgid = cursor.fetchone()
    user = new_user()
    with pytest.raises(pymysql.err.OperationalError) as e:
        cursor.callproc('promote_user_to_org_admin',
                        (str(bin_to_uuid(user['id'])), orgid))
    assert e.value.args[0] == 1142
    assert e.value.args[1] == 'Cannot promote admin from outside organization.'
def test_promote_user_to_org_admin(dictcursor, new_user):
    # depends on the roles provided by create_organization
    dictcursor.callproc('create_organization', ('test_org', ))
    dictcursor.execute('SELECT * FROM arbiter_data.organizations '
                       'WHERE name = "test_org"')
    user = new_user(org=dictcursor.fetchone())
    dictcursor.callproc('promote_user_to_org_admin', (str(
        bin_to_uuid(user['id'])), str(bin_to_uuid(user['organization_id']))))
    dictcursor.execute(
        'SELECT role_id FROM user_role_mapping WHERE user_id = %s', user['id'])
    role_ids = [r['role_id'] for r in dictcursor.fetchall()]
    assert len(role_ids) == 6
    dictcursor.execute(
        'SELECT name FROM roles WHERE id IN (%s,%s,%s,%s,%s,%s)', role_ids)
    names = [r['name'] for r in dictcursor.fetchall()]
    assert 'Create metadata' in names
    assert 'Read all' in names
    assert 'Delete metadata' in names
    assert 'Write all values' in names
    assert 'Administer data access controls' in names
    assert 'Update all' in names
def test_list_users(dictcursor, twosets):
    user = twosets[0]
    authid = twosets[0]['auth0_id']
    dictcursor.callproc('list_users', (authid, ))
    res = dictcursor.fetchall()[0]
    del res['created_at']
    del res['modified_at']
    del res['organization']
    del user['organization_id']
    del res['roles']
    user['user_id'] = str(bin_to_uuid(user.pop('id')))
    assert res == user
def test_list_roles(dictcursor, twosets):
    authid = twosets[0]['auth0_id']
    role = twosets[1]
    dictcursor.callproc('list_roles', (authid, ))
    res = dictcursor.fetchall()[0]
    del res['created_at']
    del res['modified_at']
    del res['organization']
    del role['organization_id']
    del res['permissions']
    role['role_id'] = str(bin_to_uuid(role.pop('id')))
    assert res == role
def test_remove_user_facing_permissions_and_default_roles(cursor, new_user):
    user = new_user()
    cursor.callproc('create_default_user_role',
                    (user['id'], user['organization_id']))
    cursor.execute(('SELECT 1 FROM arbiter_data.roles WHERE '
                    'name = CONCAT("DEFAULT User role ", %s)'),
                   str(bin_to_uuid(user['id'])))
    assert cursor.fetchone()[0] == 1
    cursor.execute(('SELECT 1 FROM arbiter_data.permissions WHERE '
                    'description = CONCAT("DEFAULT Read Self User ", %s)'),
                   str(bin_to_uuid(user['id'])))
    assert cursor.fetchone()[0] == 1
    cursor.execute(('SELECT 1 FROM arbiter_data.permissions WHERE '
                    'description = CONCAT("DEFAULT Read User Role ", %s)'),
                   str(bin_to_uuid(user['id'])))
    assert cursor.fetchone()[0] == 1

    cursor.callproc('remove_user_facing_permissions_and_default_roles',
                    (user['id'], ))
    cursor.execute(('SELECT 1 FROM arbiter_data.roles WHERE name '
                    '= CONCAT("DEFAULT User role ", %s)'),
                   str(bin_to_uuid(user['id'])))
    assert cursor.fetchone() is None
    cursor.execute(('SELECT 1 FROM arbiter_data.permissions WHERE '
                    'description = CONCAT("DEFAULT Read Self User ", %s)'),
                   str(bin_to_uuid(user['id'])))
    assert cursor.fetchone() is None
    cursor.execute(('SELECT 1 FROM arbiter_data.permissions WHERE '
                    'description = CONCAT("DEFAULT Read User Role ", %s)'),
                   str(bin_to_uuid(user['id'])))
    assert cursor.fetchone() is None
def test_list_permissions(dictcursor, twosets):
    authid = twosets[0]['auth0_id']
    perms = twosets[2]
    dictcursor.callproc('list_permissions', (authid, ))
    res = dictcursor.fetchall()
    for r in res:
        del r['created_at']
        del r['organization']
        del r['objects']
    for p in perms:
        p['permission_id'] = str(bin_to_uuid(p.pop('id')))
        del p['organization_id']
    assert res == perms
def test_delete_job(new_job, cursor):
    job = new_job()
    cursor.execute('select id from scheduled_jobs where id = %s',
                   (job['id'], ))
    out = cursor.fetchall()
    assert len(out) == 1
    assert out[0][0] == job['id']

    cursor.callproc('delete_job', (bin_to_uuid(job['id']), ))
    cursor.execute('select id from scheduled_jobs where id = %s',
                   (job['id'], ))
    out = cursor.fetchall()
    assert len(out) == 0
def test_list_cdf_forecast_groups(dictcursor, twosets):
    authid = twosets[0]['auth0_id']
    cdf = twosets[6]
    dictcursor.callproc('list_cdf_forecasts_groups', (authid, ))
    res = dictcursor.fetchall()
    assert res[0]['site_id'] is not None
    assert res[0]['aggregate_id'] is None
    assert res[1]['site_id'] is None
    assert res[1]['aggregate_id'] is not None
    assert ([str(bin_to_uuid(fx['id']))
             for fx in cdf] == [r['forecast_id'] for r in res])
    assert (set(res[0].keys()) - set(
        ('created_at', 'modified_at', 'provider', 'forecast_id')) == set(
            cdf[0].keys()) - set(('organization_id', 'id')))
def test_list_cdf_forecast_groups_no_singles(dictcursor, twosets):
    authid = twosets[0]['auth0_id']
    cdf = twosets[6]
    dictcursor.execute('DELETE FROM cdf_forecasts_singles')
    dictcursor.callproc('list_cdf_forecasts_groups', (authid, ))
    res = dictcursor.fetchall()
    assert ([str(bin_to_uuid(fx['id']))
             for fx in cdf] == [r['forecast_id'] for r in res])
    assert (set(res[0].keys()) - set((
        'created_at',
        'modified_at',
        'provider',
        'forecast_id',
    )) == set(cdf[0].keys()) - set(('organization_id', 'id')))
def test_delete_user(dictcursor, new_user):
    user = new_user()
    dictcursor.callproc('create_default_user_role',
                        (user['id'], user['organization_id']))
    dictcursor.callproc('delete_user', (str(bin_to_uuid(user['id'])), ))
    for q in (
            'SELECT * FROM users WHERE id = %s',
            'SELECT * FROM user_role_mapping WHERE user_id = %s',
            "SELECT 1 FROM permissions WHERE description = CONCAT('DEFAULT Read Self User ', BIN_TO_UUID(%s, 1))",  # NOQA
            "SELECT 1 FROM permissions WHERE description = CONCAT('DEFAULT Read User Role ', BIN_TO_UUID(%s, 1))",  # NOQA
            "SELECT 1 FROM roles WHERE name = CONCAT('DEFAULT User role ', BIN_TO_UUID(%s, 1))"  # NOQA
    ):
        dictcursor.execute(q, user['id'])
        assert len(dictcursor.fetchall()) == 0
def test_fetch_token(dictcursor, new_user):
    user = new_user()
    dictcursor.callproc('store_token', (user['auth0_id'], 'testtoken'))
    dictcursor.execute('SELECT * FROM job_tokens where id = %s',
                       (user['id'], ))
    out = dictcursor.fetchall()
    assert len(out) == 1
    assert out[0]['id'] == user['id']
    assert out[0]['token'] == 'testtoken'

    dictcursor.callproc('fetch_token', (bin_to_uuid(user['id']), ))
    out = dictcursor.fetchall()
    assert len(out) == 1
    assert out[0]['token'] == 'testtoken'
def test_delete_aggregate_obs(cursor, agg_obj, allow_delete_observation):
    auth0id, aggid, agg = agg_obj
    cursor.execute(
        'SELECT COUNT(*) FROM arbiter_data.aggregate_observation_mapping '
        'WHERE aggregate_id = UUID_TO_BIN(%s, 1) AND observation_deleted_at is'
        ' NULL', aggid)
    assert cursor.fetchone()[0] == 2
    cursor.callproc('delete_observation',
                    (auth0id, str(bin_to_uuid(agg['obs_list'][0]['id']))))
    cursor.execute(
        'SELECT COUNT(*) FROM arbiter_data.aggregate_observation_mapping '
        'WHERE aggregate_id = UUID_TO_BIN(%s, 1) AND observation_deleted_at is'
        ' NULL', aggid)
    assert cursor.fetchone()[0] == 1
def test_list_sites(dictcursor, twosets, new_site):
    authid = twosets[0]['auth0_id']
    sites = twosets[3]
    org = twosets[-3]
    for site in sites:
        site['climate_zones'] = '[]'  # NOQA
    sites += [new_site(org=org, latitude=32, longitude=-110)]
    sites[-1]['climate_zone'] = '["Reference Region 3"]'
    dictcursor.callproc('list_sites', (authid, ))
    res = dictcursor.fetchall()
    assert [str(bin_to_uuid(site['id']))
            for site in sites] == [r['site_id'] for r in res]
    assert (set(res[0].keys()) - set(
        ('created_at', 'modified_at', 'provider', 'site_id')) == set(
            sites[0].keys()) - set(('organization_id', 'id')))