示例#1
0
def default_acl(*args, **kwargs):
    """ Default ACLs for confidant: Allow access to all resource types
    and actions for users, except for certificate resource_type. Deny access
    to all resource types and actions for services, except:

    * resource_type: service
      actions: metadata, get
      resource_id: must match logged-in user's username
    * resource_type: certificate
      actions: get
      resource_id: must match against ACM_PRIVATE_CA_DOMAIN_REGEX setting
          for the CA for the CN in the CSR, and for all SAN values in the CSR,
          and the server_name named group in the regex must match the logged
          in user's username.
      kwargs (ca): CA used for this get
      kwargs (san): A list of subject alternative names in the CSR
    """
    resource_type = kwargs.get('resource_type')
    action = kwargs.get('action')
    resource_id = kwargs.get('resource_id')
    resource_kwargs = kwargs.get('kwargs')
    if authnz.user_is_user_type('user'):
        if resource_type == 'certificate':
            return False
        elif resource_type == 'ca':
            return False
        return True
    elif authnz.user_is_user_type('service'):
        if resource_type == 'service' and action in ['metadata', 'get']:
            # Does the resource ID match the authenticated username?
            if authnz.user_is_service(resource_id):
                return True
        elif resource_type == 'ca' and action in ['list', 'get']:
            return True
        elif resource_type == 'certificate' and action in ['get']:
            ca_object = certificatemanager.get_ca(resource_kwargs.get('ca'))
            # Require a name pattern
            if not ca_object.settings['name_regex']:
                return False
            cert_pattern = re.compile(ca_object.settings['name_regex'])
            domains = [resource_id]
            domains.extend(resource_kwargs.get('san', []))
            # Ensure the CN and every value in the SAN is allowed for this
            # user.
            for domain in domains:
                match = cert_pattern.match(domain)
                if not match:
                    return False
                service_name = match.group('service_name')
                if not service_name:
                    return False
                if not authnz.user_is_service(service_name):
                    return False
            return True
        return False
    else:
        # This should never happen, but paranoia wins out
        return False
示例#2
0
 def test_user_is_service(self):
     app.config['USE_AUTH'] = False
     self.assertTrue(authnz.user_is_service('anything'))
     app.config['USE_AUTH'] = True
     with patch('confidant.authnz.g') as g_mock:
         g_mock.username = '******'
         self.assertTrue(authnz.user_is_service('confidant-unitttest'))
     with patch('confidant.authnz.g') as g_mock:
         g_mock.username = '******'
         self.assertFalse(authnz.user_is_service('notconfidant-unitttest'))
示例#3
0
 def test_user_is_service(self):
     app.config['USE_AUTH'] = False
     self.assertTrue(authnz.user_is_service('anything'))
     app.config['USE_AUTH'] = True
     with patch('confidant.authnz.g') as g_mock:
         g_mock.username = '******'
         self.assertTrue(authnz.user_is_service('confidant-unitttest'))
     with patch('confidant.authnz.g') as g_mock:
         g_mock.username = '******'
         self.assertFalse(authnz.user_is_service('notconfidant-unitttest'))
示例#4
0
def test_user_is_service(mocker):
    mocker.patch('confidant.authnz.settings.USE_AUTH', False)
    assert authnz.user_is_service('anything') is True

    mocker.patch('confidant.authnz.settings.USE_AUTH', True)
    g_mock = mocker.patch('confidant.authnz.g')
    g_mock.username = '******'
    assert authnz.user_is_service('confidant-unitttest') is True

    g_mock = mocker.patch('confidant.authnz.g')
    g_mock.username = '******'
    assert authnz.user_is_service('notconfidant-unitttest') is False
示例#5
0
def get_service(id):
    '''
    Get service metadata and all credentials for this service. This endpoint
    allows basic authentication.
    '''
    if authnz.user_in_role('service') and not authnz.user_is_service(id):
        logging.warning('Authz failed for service {0}.'.format(id))
        msg = 'Authenticated user is not authorized.'
        return jsonify({'error': msg}), 401
    logging.debug('Authz succeeded for service {0}.'.format(id))
    try:
        service = Service.get(id)
    except Service.DoesNotExist:
        return jsonify({}), 404
    if (service.data_type != 'service' and
            service.data_type != 'archive-service'):
        return jsonify({}), 404
    try:
        credentials = _get_credentials(service.credentials)
    except KeyError:
        return jsonify({'error': 'Decryption error.'}), 500
    return jsonify({
        'id': service.id,
        'credentials': credentials,
        'enabled': service.enabled,
        'revision': service.revision,
        'modified_date': service.modified_date,
        'modified_by': service.modified_by
    })
示例#6
0
def get_service(id):
    '''
    Get service metadata and all credentials for this service. This endpoint
    allows basic authentication.
    '''
    if authnz.user_in_role('service') and not authnz.user_is_service(id):
        log.warning('Authz failed for service {0}.'.format(id))
        msg = 'Authenticated user is not authorized.'
        return jsonify({'error': msg}), 401
    log.debug('Authz succeeded for service {0}.'.format(id))
    try:
        service = Service.get(id)
    except Service.DoesNotExist:
        return jsonify({}), 404
    if (service.data_type != 'service'
            and service.data_type != 'archive-service'):
        return jsonify({}), 404
    try:
        credentials = _get_credentials(service.credentials)
    except KeyError:
        return jsonify({'error': 'Decryption error.'}), 500
    return jsonify({
        'id': service.id,
        'credentials': credentials,
        'enabled': service.enabled,
        'revision': service.revision,
        'modified_date': service.modified_date,
        'modified_by': service.modified_by
    })
示例#7
0
def default_acl(*args, **kwargs):
    """ Default ACLs for confidant: always return true for users, but enforce
    ACLs for services, restricting access to:

    * resource_type: service
      actions: metadata, get
    """
    resource_type = kwargs.get('resource_type')
    action = kwargs.get('action')
    resource_id = kwargs.get('resource_id')
    # Some ACL checks also pass extra args in via kwargs, which we would
    # access via:
    #    resource_kwargs = kwargs.get('kwargs')
    if authnz.user_is_user_type('user'):
        return True
    elif authnz.user_is_user_type('service'):
        if resource_type == 'service' and action in ['metadata', 'get']:
            # Does the resource ID match the authenticated username?
            if authnz.user_is_service(resource_id):
                return True
        # We currently only allow services to access service get/metadata
        return False
    else:
        # This should never happen, but paranoia wins out
        return False
示例#8
0
def get_service(id):
    '''
    Get service metadata and all credentials for this service. This endpoint
    allows basic authentication.
    '''
    #_init_.py에 정의된 user_is_user_type함수를 통해 service값이라면 제어문 안으로
    if authnz.user_is_user_type('service'):
        #_init_.py에 정의된 user_is_service함수를 통해 함수의 파라메터 값으로 받아온 id가 아니라면 로그에 'Authz failed for service {0}.', 'Authenticated user is not authorized.'라는 메시지와 함께 401error를 띄운다
        if not authnz.user_is_service(id):
            logging.warning('Authz failed for service {0}.'.format(id))
            msg = 'Authenticated user is not authorized.'
            return jsonify({'error': msg}), 401
    try:
        #service라는 변수에 id값 대입
        service = Service.get(id)
        #_init_.py에 정의된 service_in_account함수를 통해 account값이 일치하지 않는다면 제어문 안으로
        if not authnz.service_in_account(service.account):
            #아래와 같은 로그를 남긴다
            logging.warning(
                'Authz failed for service {0} (wrong account).'.format(id)
            )
            #msg에 아래와 같은 문자 대입
            msg = 'Authenticated user is not authorized.'
            #401error를 msg에 대입된 문자열과 함께 jsonify시켜 리턴
            return jsonify({'error': msg}), 401
    #위 try문의 코드에 error발생 시 예외처리
    except DoesNotExist:
        return jsonify({}), 404
    if (service.data_type != 'service' and
            service.data_type != 'archive-service'):
        return jsonify({}), 404
    logging.debug('Authz succeeded for service {0}.'.format(id))
    try:
        #credential을 가져온다
        credentials = _get_credentials(service.credentials)
    except KeyError:
        #error발생 시 500error발생
        logging.exception('KeyError occurred in getting credentials')
        return jsonify({'error': 'Decryption error.'}), 500
    blind_credentials = _get_blind_credentials(service.blind_credentials)
    return jsonify({
        'id': service.id,
        'account': service.account,
        'credentials': credentials,
        'blind_credentials': blind_credentials,
        'enabled': service.enabled,
        'revision': service.revision,
        'modified_date': service.modified_date,
        'modified_by': service.modified_by
    })
示例#9
0
def get_service(id):
    '''
    Get service metadata and all credentials for this service. This endpoint
    allows basic authentication.
    '''
    if authnz.user_is_user_type('service'):
        if not authnz.user_is_service(id):
            logging.warning('Authz failed for service {0}.'.format(id))
            msg = 'Authenticated user is not authorized.'
            return jsonify({'error': msg}), 401
    try:
        service = Service.get(id)
        if not authnz.service_in_account(service.account):
            logging.warning(
                'Authz failed for service {0} (wrong account).'.format(id)
            )
            msg = 'Authenticated user is not authorized.'
            return jsonify({'error': msg}), 401
    except DoesNotExist:
        return jsonify({}), 404
    if (service.data_type != 'service' and
            service.data_type != 'archive-service'):
        return jsonify({}), 404
    logging.debug('Authz succeeded for service {0}.'.format(id))
    try:
        credentials = _get_credentials(service.credentials)
    except KeyError:
        logging.exception('KeyError occurred in getting credentials')
        return jsonify({'error': 'Decryption error.'}), 500
    blind_credentials = _get_blind_credentials(service.blind_credentials)
    return jsonify({
        'id': service.id,
        'account': service.account,
        'credentials': credentials,
        'blind_credentials': blind_credentials,
        'enabled': service.enabled,
        'revision': service.revision,
        'modified_date': service.modified_date,
        'modified_by': service.modified_by
    })
示例#10
0
def get_service(id):
    '''
    Get service metadata and all credentials for this service. This endpoint
    allows basic authentication.
    '''
    permissions = {
        'metadata': False,
        'get': False,
        'update': False,
    }
    metadata_only = request.args.get('metadata_only', default=False, type=bool)
    if authnz.user_is_user_type('service'):
        if not authnz.user_is_service(id):
            logging.warning('Authz failed for service {0}.'.format(id))
            msg = 'Service is not authorized.'
            return jsonify({'error': msg}), 401
        permissions['metadata'] = True
        permissions['get'] = True
    else:
        logged_in_user = authnz.get_logged_in_user()
        action = 'metadata' if metadata_only else 'get'
        permissions['metadata'] = acl_module_check(
            resource_type='service',
            action=action,
            resource_id=id,
        )
        permissions['get'] = acl_module_check(
            resource_type='service',
            action=action,
            resource_id=id,
        )
        if not permissions[action]:
            msg = "{} does not have access to get service {}".format(
                authnz.get_logged_in_user(),
                id
            )
            error_msg = {'error': msg, 'reference': id}
            return jsonify(error_msg), 403

        logging.info(
            'get_service called on id={} by user={} metadata_only={}'.format(
                id,
                logged_in_user,
                metadata_only,
            )
        )
    try:
        service = Service.get(id)
        if not authnz.service_in_account(service.account):
            logging.warning(
                'Authz failed for service {0} (wrong account).'.format(id)
            )
            msg = 'Authenticated user is not authorized.'
            return jsonify({'error': msg}), 401
    except DoesNotExist:
        return jsonify({}), 404
    if (service.data_type != 'service' and
            service.data_type != 'archive-service'):
        return jsonify({}), 404
    logging.debug('Authz succeeded for service {0}.'.format(id))
    try:
        credentials = credentialmanager.get_credentials(service.credentials)
    except KeyError:
        logging.exception('KeyError occurred in getting credentials')
        return jsonify({'error': 'Decryption error.'}), 500
    blind_credentials = credentialmanager.get_blind_credentials(
        service.blind_credentials,
    )
    # TODO: this check can be expensive, so we're gating only to user auth.
    # We should probably add an argument that opts in for permission hints,
    # rather than always checking them.
    if authnz.user_is_user_type('user'):
        combined_cred_ids = (
            list(service.credentials) + list(service.blind_credentials)
        )
        permissions['update'] = acl_module_check(
            resource_type='service',
            action='update',
            resource_id=id,
            kwargs={
                'credential_ids': combined_cred_ids,
            },
        )
    service_response = ServiceResponse.from_service_expanded(
        service,
        credentials=credentials,
        blind_credentials=blind_credentials,
        metadata_only=metadata_only,
    )
    service_response.permissions = permissions
    return service_expanded_response_schema.dumps(service_response)