def _get_auth_data(username):
    """
    Get authorization data for given user

    Return:
    {
        'dn': 'user DN',
        'clearances': ['U', 'S'],
        'formal_accesses': ['AB', 'CD'],
        'visas': ['ABC', 'XYZ'],
        'duty_org': 'org',
        'is_org_steward': False,
        'is_apps_mall_steward': False,
        'is_metrics_user': True
    }
    """
    profile = model_access.get_profile(username)
    # get user's basic data
    url = settings.OZP["OZP_AUTHORIZATION"]["USER_INFO_URL"] % (profile.dn, profile.issuer_dn)
    r = requests.get(url)
    logger.debug("hitting url %s for user with dn %s" % (url, profile.dn))

    if r.status_code != 200:
        raise errors.AuthorizationFailure("Error contacting authorization server: %s" % r.text)
    user_data = r.json()

    # convert dutyorg -> duty_org
    user_data["duty_org"] = user_data["dutyorg"]
    user_data.pop("dutyorg", None)

    # convert formalAcccesses -> formal_accesses
    user_data["formal_accesses"] = user_data["formalAccesses"]
    user_data.pop("formalAccesses", None)

    # get groups for user
    url = settings.OZP["OZP_AUTHORIZATION"]["USER_GROUPS_URL"] % (
        profile.dn,
        settings.OZP["OZP_AUTHORIZATION"]["PROJECT_NAME"],
    )
    r = requests.get(url)
    if r.status_code != 200:
        raise errors.AuthorizationFailure("Error contacting authorization server: %s" % r.text)

    groups = r.json()["groups"]
    user_data["is_org_steward"] = False
    user_data["is_apps_mall_steward"] = False
    user_data["is_metrics_user"] = False

    for g in groups:
        if settings.OZP["OZP_AUTHORIZATION"]["APPS_MALL_STEWARD_GROUP_NAME"] == utils.find_between(g, "cn=", ","):
            user_data["is_apps_mall_steward"] = True
        if settings.OZP["OZP_AUTHORIZATION"]["ORG_STEWARD_GROUP_NAME"] == utils.find_between(g, "cn=", ","):
            user_data["is_org_steward"] = True
        if settings.OZP["OZP_AUTHORIZATION"]["METRICS_GROUP_NAME"] == utils.find_between(g, "cn=", ","):
            user_data["is_org_steward"] = True

    return user_data
Ejemplo n.º 2
0
def _get_profile_by_dn(dn, issuer_dn="default issuer dn"):
    """
    Returns a user profile for a given DN

    If a profile isn't found with the given DN, create one
    """
    # look up the user with this dn. if the user doesn't exist, create them
    try:
        profile = models.Profile.objects.get(dn=dn)
        if not profile.user.is_active:
            logger.warning("User %s tried to login but is inactive" % dn)
            return None
        return profile
    except models.Profile.DoesNotExist:
        logger.info("creating new user for dn: %s" % dn)
        if "CN=" in dn:
            cn = utils.find_between(dn, "CN=", ",")
        else:
            cn = dn
        kwargs = {"display_name": cn, "dn": dn, "issuer_dn": issuer_dn}
        # sanitize username
        username = cn[0:30]  # limit to 30 chars
        username = username.replace(" ", "_")  # no spaces
        username = username.replace("'", "")  # no apostrophes
        username = username.lower()  # all lowercase
        # make sure this username doesn't exist
        count = User.objects.filter(username=username).count()
        if count != 0:
            username = "******" % (username, count + 1)

        profile = models.Profile.create_user(username, **kwargs)
        logger.debug("created new profile for user %s" % profile.user.username)
        return profile
Ejemplo n.º 3
0
def _get_profile_by_dn(dn, issuer_dn='default issuer dn'):
    """
    Returns a user profile for a given DN

    If a profile isn't found with the given DN, create one
    """
    # look up the user with this dn. if the user doesn't exist, create them
    profile = models.Profile.objects.filter(dn__iexact=dn).first()
    if profile:
        if not profile.user.is_active:
            logger.warning(
                'User {0!s} tried to login but is inactive'.format(dn))
            return None
        # update the issuer_dn
        if profile.issuer_dn != issuer_dn:
            logger.info('updating issuer dn for user {0!s}'.format(
                profile.user.username))
            profile.issuer_dn = issuer_dn
            profile.save()
        return profile
    else:
        logger.info('creating new user for dn: {0!s}'.format(dn))
        if 'CN=' in dn:
            cn = utils.find_between(dn, 'CN=', ',')
        else:
            cn = dn

        kwargs = {'display_name': cn, 'dn': dn, 'issuer_dn': issuer_dn}
        # sanitize username
        username = cn[0:30]
        username = username.replace(' ', '_')  # no spaces
        username = username.replace("'", "")  # no apostrophes
        username = username.lower()  # all lowercase
        # make sure this username doesn't exist
        count = User.objects.filter(username=username).count()
        if count != 0:
            new_username = username[0:27]
            count = User.objects.filter(
                username__startswith=new_username).count()
            new_username = '******'.format(new_username, count + 1)
            username = new_username

        # now check again - if this username exists, we have a problemce
        count = User.objects.filter(username=username).count()
        if count != 0:
            logger.error(
                'Cannot create new user for dn {0!s}, username {1!s} already exists'
                .format(dn, username))
            return None

        profile = models.Profile.create_user(username, **kwargs)
        logger.info('created new profile for user {0!s}'.format(
            profile.user.username))
        dispatcher.publish('profile_created', profile=profile)
        return profile
def get_columns(table):
    """
    Get the columns of a table in an array

    Columns will be in the same order as the values appear in the data
    """
    with open('%s/%s.sql' % (SQL_FILE_PATH, table), 'r') as f:
        data = f.read().replace('\n', '')
    # extract a string like (`id`, `version`, `created_by_id`)
    columns = utils.find_between(data, "INSERT INTO `%s`" % table, " VALUES")
    # remove parenthesis, backticks, and spaces
    columns = re.sub('[`() ]', '', columns)
    columns = columns.split(',')
    return columns
Ejemplo n.º 5
0
def _get_profile_by_dn(dn, issuer_dn='default issuer dn'):
    """
    Returns a user profile for a given DN

    If a profile isn't found with the given DN, create one
    """
    # look up the user with this dn. if the user doesn't exist, create them
    profile = models.Profile.objects.filter(dn__iexact=dn).first()
    if profile:
        if not profile.user.is_active:
            logger.warning('User %s tried to login but is inactive' % dn)
            return None
        # update the issuer_dn
        if profile.issuer_dn != issuer_dn:
            logger.info('updating issuer dn for user %s' % profile.user.username)
            profile.issuer_dn = issuer_dn
            profile.save()
        return profile
    else:
        logger.info('creating new user for dn: %s' % dn)
        if 'CN=' in dn:
            cn = utils.find_between(dn, 'CN=', ',')
        else:
            cn = dn

        kwargs = {'display_name': cn, 'dn': dn, 'issuer_dn': issuer_dn}
        # sanitize username
        username = cn[0:30]
        username = username.replace(' ', '_')  # no spaces
        username = username.replace("'", "")  # no apostrophes
        username = username.lower()  # all lowercase
        # make sure this username doesn't exist
        count = User.objects.filter(username=username).count()
        if count != 0:
            new_username = username[0:27]
            count = User.objects.filter(username__startswith=new_username).count()
            new_username = '******' % (new_username, count + 1)
            username = new_username

        # now check again - if this username exists, we have a problem
        count = User.objects.filter(
            username=username).count()
        if count != 0:
            logger.error('Cannot create new user for dn %s, username %s already exists' % (dn, username))
            return None

        profile = models.Profile.create_user(username, **kwargs)
        logger.info('created new profile for user %s' % profile.user.username)
        return profile
def get_columns(table):
    """
    Get the columns of a table in an array

    Columns will be in the same order as the values appear in the data
    """
    with open('{0!s}/{1!s}.sql'.format(SQL_FILE_PATH, table), 'r') as f:
        data = f.read().replace('\n', '')
    # extract a string like (`id`, `version`, `created_by_id`)
    columns = utils.find_between(data, "INSERT INTO `{0!s}`".format(table),
                                 " VALUES")
    # remove parenthesis, backticks, and spaces
    columns = re.sub('[`() ]', '', columns)
    columns = columns.split(',')
    return columns
Ejemplo n.º 7
0
 def test_find_between(self):
     result = utils.find_between('a*str-a', '*', '-')
     self.assertEqual(result, 'str')
Ejemplo n.º 8
0
 def test_find_between(self):
     result = utils.find_between('a*str-a', '*', '-')
     self.assertEqual(result, 'str')
Ejemplo n.º 9
0
    def _get_auth_data(self, username):
        """
        Get authorization data for given user

        Return:
        {
            'dn': 'user DN',
            'clearances': ['U', 'S'],
            'formal_accesses': ['AB', 'CD'],
            'visas': ['ABC', 'XYZ'],
            'duty_org': 'org',
            'is_org_steward': False,
            'is_apps_mall_steward': False,
            'is_metrics_user': True
        }
        """
        profile = model_access.get_profile(username)
        # get user's basic data
        url = self.settings.OZP['OZP_AUTHORIZATION']['USER_INFO_URL'] % (profile.dn, profile.issuer_dn)
        server_crt = self.settings.OZP['OZP_AUTHORIZATION']['SERVER_CRT']
        server_key = self.settings.OZP['OZP_AUTHORIZATION']['SERVER_KEY']
        r = self.requests.get(url, cert=(server_crt, server_key), verify=False)
        # logger.debug('hitting url %s for user with dn %s' % (url, profile.dn), extra={'request':request})

        if r.status_code != 200:
            raise errors.AuthorizationFailure('Error contacting authorization server: {0!s}'.format(r.text))
        user_data = r.json()

        user_json_keys = ['dn', 'formalAccesses', 'clearances', 'dutyorg', 'visas']
        for user_key in user_json_keys:
            if user_key not in user_data:
                raise ValueError('Endpoint {0!s} not return value output - missing key: {1!s}'.format(url, user_key))

        # convert dutyorg -> duty_org
        user_data['duty_org'] = user_data['dutyorg']
        user_data.pop('dutyorg', None)

        # convert formalAcccesses -> formal_accesses
        user_data['formal_accesses'] = user_data['formalAccesses']
        user_data.pop('formalAccesses', None)

        # get groups for user
        url = self.settings.OZP['OZP_AUTHORIZATION']['USER_GROUPS_URL'] % (profile.dn, self.settings.OZP['OZP_AUTHORIZATION']['PROJECT_NAME'])
        # logger.debug('hitting url %s for user with dn %s for group info' % (url, profile.dn), extra={'request':request})
        r = self.requests.get(url, cert=(server_crt, server_key), verify=False)
        if r.status_code != 200:
            raise errors.AuthorizationFailure('Error contacting authorization server: {0!s}'.format(r.text))
        group_data = r.json()

        if 'groups' not in group_data:
            raise ValueError('Endpoint {0!s} not return value output - missing key: {1!s}'.format(url, 'groups'))

        groups = group_data['groups']
        user_data['is_org_steward'] = False
        user_data['is_apps_mall_steward'] = False
        user_data['is_metrics_user'] = False

        for g in groups:
            if self.settings.OZP['OZP_AUTHORIZATION']['APPS_MALL_STEWARD_GROUP_NAME'] == utils.find_between(g, 'cn=', ','):
                user_data['is_apps_mall_steward'] = True
            if self.settings.OZP['OZP_AUTHORIZATION']['ORG_STEWARD_GROUP_NAME'] == utils.find_between(g, 'cn=', ','):
                user_data['is_org_steward'] = True
            if self.settings.OZP['OZP_AUTHORIZATION']['METRICS_GROUP_NAME'] == utils.find_between(g, 'cn=', ','):
                user_data['is_org_steward'] = True

        return user_data
def get_values(table, column_count):
    """
    Get the values of a table in an array of arrays

    Args:
        table: name of the database table
        column_count: number of columns in this table
    """
    values = []
    with open('%s/%s.sql' % (SQL_FILE_PATH, table), 'r') as f:
        data = f.read().replace('\n', '')
    # extract the data we want
    values_str = utils.find_between(data, "VALUES ", ");") + ')'

    # values can contain special chars like paranthesis and commas, so we
    # have to be smart about how we extract the data

    while values_str:
        if values_str[0] != '(':
            print('Error: each value must start with opening paranthesis')
            return None
        # remove leading '('
        values_str = values_str[1:]
        # create empty array that will hold all values for this entry
        entry_values = []
        current_entry_finished = False
        columns_processed = 0
        while not current_entry_finished:
            # check for hex value
            if values_str[:2] == '0x':
                val = '0x' + utils.find_between(values_str, '0x', ',')
                entry_values.append(val)
                # remove extracted data from the original string
                idx = len(val)
                values_str = values_str[idx:]
                columns_processed += 1
                print('got hex value: %s' % val)
                # remove comma
                if values_str[0] != ',' and columns_processed != column_count:
                    print('Error: comma not found after extracting hex value')
                    return None
                if columns_processed < column_count:
                    values_str = values_str[1:]
            # check for a string value
            elif values_str[0] == "'":
                # read all chars between this quote and next unescaped quote
                # remove the leading quote
                values_str = values_str[1:]
                # find the index of the next unescaped quote
                idx = get_index_next_unescaped_quote(values_str)
                val = values_str[:idx]
                entry_values.append(val)
                # remove extracted data from original string
                idx = len(val) + 1 # +1 for the trailing quote
                values_str = values_str[idx:]
                columns_processed += 1
                print('got string value: %s' % val)
                # remove comma
                if values_str[0] != ',' and columns_processed != column_count:
                    print('Error: comma not found after extracting string value. string[0]: %s' % values_str[0])
                    return None
                if columns_processed < column_count:
                    values_str = values_str[1:]
            # check for NULL value
            elif values_str[0:4] == 'NULL':
                val = None
                entry_values.append(val)
                values_str = values_str[4:]
                columns_processed += 1
                print('got NULL value: %s' % val)
                # remove comma
                if values_str[0] != ',' and columns_processed != column_count:
                    print('Error: comma not found after extracting NULL value')
                    return None
                if columns_processed < column_count:
                    values_str = values_str[1:]
            # check for integer value
            elif values_str[0] in ['0','1','2','3','4','5','6','7','8','9']:
                val = re.findall(r'\d+', values_str)[0]
                entry_values.append(val)
                # remove extracted data from original string
                idx = len(val)
                values_str = values_str[idx:]
                columns_processed += 1
                print('got integer value: %s' % val)
                # remove comma
                if values_str[0] != ',' and columns_processed != column_count:
                    print('Error: comma not found after extracting integer value')
                    return None
                if columns_processed < column_count:
                    values_str = values_str[1:]
            else:
                print('Error: found invalid character in data: %s' % values_str[0])
                return None

            if columns_processed == column_count:
                current_entry_finished = True
                print('completed processing of row')
                # remove closing parenthesis
                if values_str[0] != ')':
                    print('Error: closing parenthesis not found at end of row data')
                    return None
                values_str = values_str[1:]
                # remove the comma between entries, unless this is the last entry
                if values_str:
                    values_str = values_str[1:]

        values.append(entry_values)
    return values
def get_values(table, column_count):
    """
    Get the values of a table in an array of arrays

    Args:
        table: name of the database table
        column_count: number of columns in this table
    """
    values = []
    with open('{0!s}/{1!s}.sql'.format(SQL_FILE_PATH, table), 'r') as f:
        data = f.read().replace('\n', '')
    # extract the data we want
    values_str = utils.find_between(data, "VALUES ", ");") + ')'

    # values can contain special chars like parenthesis and commas, so we
    # have to be smart about how we extract the data

    while values_str:
        if values_str[0] != '(':
            logging.error(
                'Error: each value must start with opening parenthesis')
            return None
        # remove leading '('
        values_str = values_str[1:]
        # create empty array that will hold all values for this entry
        entry_values = []
        current_entry_finished = False
        columns_processed = 0
        while not current_entry_finished:
            # check for hex value (includes booleans)
            if values_str[:2] == '0x':
                val = re.findall(r'0x[0-9ABCDEF]*', values_str)[0]
                if val == '0x00':
                    entry_values.append(False)
                elif val == '0x01':
                    entry_values.append(True)
                else:
                    # assume the hex value is a UUID
                    entry_values.append(uuid.UUID(hex=val[2:]))
                # remove extracted data from the original string
                idx = len(val)
                values_str = values_str[idx:]
                columns_processed += 1
                # logging.debug('got hex value: %s' % val)
                # remove comma
                if values_str[0] != ',' and columns_processed != column_count:
                    logging.error(
                        'Error: comma not found after extracting hex value')
                    return None
                if columns_processed < column_count:
                    values_str = values_str[1:]
            # check for a string value
            elif values_str[0] == "'":
                # read all chars between this quote and next unescaped quote
                # remove the leading quote
                values_str = values_str[1:]
                # find the index of the next unescaped quote
                idx = get_index_next_unescaped_quote(values_str)
                val = values_str[:idx]
                entry_values.append(val)
                # remove extracted data from original string
                idx = len(val) + 1  # +1 for the trailing quote
                values_str = values_str[idx:]
                columns_processed += 1
                # logging.debug('got string value: %s' % val)
                # remove comma
                if values_str[0] != ',' and columns_processed != column_count:
                    logging.error(
                        'Error: comma not found after extracting string value. string[0]: {0!s}'
                        .format(values_str[0]))
                    return None
                if columns_processed < column_count:
                    values_str = values_str[1:]
            # check for NULL value
            elif values_str[0:4] == 'NULL':
                val = None
                entry_values.append(val)
                values_str = values_str[4:]
                columns_processed += 1
                # logging.debug('got NULL value: %s' % val)
                # remove comma
                if values_str[0] != ',' and columns_processed != column_count:
                    logging.error(
                        'Error: comma not found after extracting NULL value')
                    return None
                if columns_processed < column_count:
                    values_str = values_str[1:]
            # check for integer value
            elif values_str[0] in [
                    '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'
            ]:
                val = re.findall(r'\d+', values_str)[0]
                entry_values.append(val)
                # remove extracted data from original string
                idx = len(val)
                values_str = values_str[idx:]
                columns_processed += 1
                # logging.debug('got integer value: %s' % val)
                # remove comma
                if values_str[0] != ',' and columns_processed != column_count:
                    logging.error(
                        'Error: comma not found after extracting integer value'
                    )
                    return None
                if columns_processed < column_count:
                    values_str = values_str[1:]
            else:
                logging.error(
                    'Error: found invalid character in data: {0!s}'.format(
                        values_str[0]))
                return None

            if columns_processed == column_count:
                current_entry_finished = True
                # logging.debug('completed processing of row')
                # remove closing parenthesis
                if values_str[0] != ')':
                    logging.error(
                        'Error: closing parenthesis not found at end of row data'
                    )
                    return None
                values_str = values_str[1:]
                # remove the comma between entries, unless this is the last entry
                if values_str:
                    values_str = values_str[1:]

        values.append(entry_values)
    return values