Exemple #1
0
    def sync(self):
        """
        Goes through every user to identify those with registered devices, and syncs to KVstore. The list of
        old_registered_users must be fetched first to avoid a possible race condition.
        :return:
        """
        old_registered_users = get_all_mobile_users(self.session_key)
        all_splunk_users = get_all_users(self.session_key) + ['nobody']
        registered_users = [
            user for user in all_splunk_users
            if user_has_registered_devices(user, self.session_key)
        ]

        kvstore_users = KvStore(constants.REGISTERED_USERS_COLLECTION_NAME,
                                self.session_key)
        try:
            [
                kvstore_users.insert_single_item({u'_key': user})
                for user in registered_users
                if user not in old_registered_users
            ]
            [
                kvstore_users.delete_item_by_key(user)
                for user in old_registered_users
                if user not in registered_users
            ]
            LOGGER.info(
                "Completed Registered Users Sync in process PID={}".format(
                    os.getpid()))
        except:
            LOGGER.exception(
                "Exception performing RegisteredUsersSync for collection={}".
                format(constants.REGISTERED_USERS_COLLECTION_NAME))
Exemple #2
0
def delete_device(user, device_owner, device_key, system_authtoken, user_authtoken):
    """
    Deletes a specific device from the kvstore. This function:
        1. Checks if the user has the necessary privileges to delete the given device
        2. Attempts to delete the device from the kvstore

    :param user: User making the deletion request
    :param device_owner: User who owns the device being deleted
    :param device_key: kvstore _key of the device being deleted
    :param system_authtoken: Authorization token with system-level privileges. Used to allow users to delete
    their own devices even when they don't have unrestricted kvstore write access
    :param user_authtoken: Authorization token with the same permissions as "user"
    :return: Success message
    """

    # Checks if the user has the necessary privileges to delete the given device
    kvstore_user = KvStore(constants.REGISTERED_DEVICES_COLLECTION_NAME, user_authtoken, owner=device_owner)
    if user == device_owner:
        kvstore_user = KvStore(constants.REGISTERED_DEVICES_COLLECTION_NAME, system_authtoken, owner=device_owner)

    kvstore_nobody = KvStore(constants.DEVICE_PUBLIC_KEYS_COLLECTION_NAME, system_authtoken)

    r, record = kvstore_user.get_item_by_key(device_key)
    record = json.loads(record)

    # Attempts to delete the device from the kvstore
    kvstore_user.delete_item_by_key(device_key)
    try:
        kvstore_nobody.delete_item_by_key(device_key)
    except splunk.RESTException:
        LOGGER.info("public for device not found, device_id=%s" % device_key)

    LOGGER.info('device_key=%s (of device_owner=%s) deleted from kvstore by user=%s' % (device_key, device_owner, user))

    delete_device_from_spacebridge(record['device_id'], system_authtoken)
    LOGGER.info('device key=%s (of device_owner=%s) deleted from spacebridge by user=%s' % (device_key, device_owner, user))

    if not user_has_registered_devices(device_owner, system_authtoken):
        kvstore_nobody = KvStore(constants.REGISTERED_USERS_COLLECTION_NAME, system_authtoken)
        kvstore_nobody.delete_item_by_key(device_owner)

    return {
        'payload': 'Device with key %s successfully deleted' % device_key,
        'status': 200,
    }
Exemple #3
0
def handle_confirmation(auth_code, user, session_token, system_authtoken, body):
    """
    Handler for the final DevicePairingConfirmationRequest call. This function:
        1. Authenticates the supplied username and password
        2. Retrieves temporary record from the kvstore
        3. Checks if app_type has been disabled since registration
        4. Makes the DevicePairingConfirmationRequest request to the server
        5. Creates a new permanent record for the device in the kvstore
        6. Deletes the temporary kvstore record

    :param auth_code: User-entered authorization code to be returned to Spacebridge
    :param body: Parsed JSON body of the incoming POST request
    :param kvstore_unconfirmed: Access object for the temporary registration kvstore
    :param system_authtoken: System-level access token for writing to the kvstore
    :return: Success message
    """

    # Authenticates the supplied username and password
    kvstore_temp = KvStore(constants.UNCONFIRMED_DEVICES_COLLECTION_NAME, system_authtoken, owner=user)
    encryption_context = SplunkEncryptionContext(system_authtoken, constants.SPACEBRIDGE_APP_NAME)
    username = extract_parameter(body, USERNAME_LABEL, BODY_LABEL)
    password = extract_parameter(body, PASSWORD_LABEL, BODY_LABEL)

    try:
        # use what Splunk thinks the username is to generate the session token
        auth =  BasicAuthHeader(username, password)
        content = get_current_context(auth)
        username = content[constants.ENTRY][0][constants.CONTENT][constants.USERNAME]
    except SpacebridgePermissionsError as e:
        LOGGER.exception('Invalid credentials passed to current-context API')
        raise e


    LOGGER.info('Received new registration confirmation request by user=%s for device_owner=%s' % (user, username))

    # Retrieves temporary record from the kvstore
    temp_key = extract_parameter(body, KVSTORE_TEMPORARY_ID_LABEL, BODY_LABEL)
    r, temp_record = kvstore_temp.get_item_by_key(temp_key)
    temp_record = json.loads(temp_record)

    device_id = temp_record[DEVICE_ID_LABEL]
    device_id_raw = base64.b64decode(device_id)

    device_registration = {'_key': py23.urlsafe_b64encode_to_str(device_id_raw)}
    device_public_keys = {'_key': py23.urlsafe_b64encode_to_str(device_id_raw)}

    for k in temp_record.keys():
        if k in DEVICE_REGISTRATION_ATTRS:
            device_registration[k] = temp_record[k]
        if k in DEVICE_PUBLIC_KEYS_ATTRS:
            device_public_keys[k] = temp_record[k]


    # Checks if app_type has been disabled since registration
    app_name = temp_record[DEVICE_TYPE_LABEL]

    if not retrieve_state_of_app(app_name, system_authtoken):
        disabled_message = 'Registration Error: Application type app_name="%s" is disabled' % app_name
        LOGGER.info(disabled_message)
        return {
            'payload': {
                'message': disabled_message,
                'app_name': app_name,
            },
            'status': 422,
        }

    device_encryption_info = DeviceInfo(
        base64.b64decode(temp_record['encrypt_public_key']),
        base64.b64decode(temp_record['sign_public_key']),
        base64.b64decode(temp_record['device_id']),
        "NA",
        app_id=temp_record['app_id'],
        app_name=temp_record['device_type']
    )

    deployment_friendly_name = get_deployment_friendly_name(system_authtoken)

    try:
        credentials = SplunkJWTCredentials(username, password=password)
        credentials.load_jwt_token(SplunkAuthHeader(session_token))
        LOGGER.info("Successfully fetched jwt token")
    except Exception as e:
        LOGGER.info("Failed to fetch jwt token with message={}. Using basic credentials instead.".format(e))
        credentials = SimpleUserCredentials(username, password)

    pair_device(auth_code, credentials, device_encryption_info, encryption_context,
                server_name=deployment_friendly_name, config=config, server_app_id=constants.SPLAPP_APP_ID)

    # Creates a new permanent record for the device in the kvstore
    kvstore_user = KvStore(constants.REGISTERED_DEVICES_COLLECTION_NAME, system_authtoken, owner=username)
    kvstore_user.insert_single_item(device_registration)

    # Adds the user to the list of users with registered devices, if not already there
    kvstore_users = KvStore(constants.REGISTERED_USERS_COLLECTION_NAME, system_authtoken)
    kvstore_users.insert_or_update_item_containing_key({'_key': username})

    kvstore_nobody = KvStore(constants.DEVICE_PUBLIC_KEYS_COLLECTION_NAME, system_authtoken)
    kvstore_nobody.insert_single_item(device_public_keys)

    # Deletes the temporary kvstore record
    kvstore_temp.delete_item_by_key(temp_key)

    LOGGER.info('Device registration confirmed. Device with device_name=\"%s\" was recorded in the kvstore.' %
                temp_record[DEVICE_NAME_LABEL])

    return {
        'payload': 'Device registration successful',
        'status': 201,
    }
def register_device(auth_code, user, system_authtoken, temp_key):
    """
    Handler for the final DevicePairingConfirmationRequest call. This function:
        2. Retrieves temporary record from the kvstore
        3. Checks if app_type has been disabled since registration
        4. Makes the DevicePairingConfirmationRequest request to the server
        5. Creates a new permanent record for the device in the kvstore
        6. Deletes the temporary kvstore record

    :param auth_code: User-entered authorization code to be returned to Spacebridge
    :param body: Parsed JSON body of the incoming POST request
    :param kvstore_unconfirmed: Access object for the temporary registration kvstore
    :param system_authtoken: System-level access token for writing to the kvstore
    :return: Success message
    """

    kvstore_temp = KvStore(constants.UNCONFIRMED_DEVICES_COLLECTION_NAME,
                           system_authtoken,
                           owner=user)
    encryption_context = SplunkEncryptionContext(
        system_authtoken, constants.SPACEBRIDGE_APP_NAME)

    LOGGER.info('Received new registration confirmation request by user=%s' %
                (user))

    # Retrieves temporary record from the kvstore
    r, temp_record = kvstore_temp.get_item_by_key(temp_key)
    temp_record = json.loads(temp_record)

    device_id = temp_record[DEVICE_ID_LABEL]
    device_id_raw = base64.b64decode(device_id)

    device_registration = {'_key': base64.urlsafe_b64encode(device_id_raw)}
    device_public_keys = {'_key': base64.urlsafe_b64encode(device_id_raw)}

    for k in temp_record.keys():
        if k in DEVICE_REGISTRATION_ATTRS:
            device_registration[k] = temp_record[k]
        if k in DEVICE_PUBLIC_KEYS_ATTRS:
            device_public_keys[k] = temp_record[k]

    # Checks if app_type has been disabled since registration
    app_name = temp_record[DEVICE_TYPE_LABEL]

    if not retrieve_state_of_app(app_name, system_authtoken):
        disabled_message = 'Registration Error: Application type app_name="%s" is disabled' % app_name
        LOGGER.info(disabled_message)
        return {
            'payload': {
                'message': disabled_message,
                'app_name': app_name,
            },
            'status': 422,
        }

    device_encryption_info = DeviceInfo(
        base64.b64decode(temp_record['encrypt_public_key']),
        base64.b64decode(temp_record['sign_public_key']),
        base64.b64decode(temp_record['device_id']),
        "NA",
        app_id=temp_record['app_id'],
        app_name=temp_record['device_type'])

    deployment_friendly_name = get_deployment_friendly_name(system_authtoken)
    pair_device(auth_code,
                SimpleUserCredentials("dummy", "dummy"),
                device_encryption_info,
                encryption_context,
                server_name=deployment_friendly_name,
                config=config)

    # Creates a new permanent record for the device in the kvstore
    kvstore_user = KvStore(constants.REGISTERED_DEVICES_COLLECTION_NAME,
                           system_authtoken,
                           owner=user)
    kvstore_user.insert_single_item(device_registration)

    # Adds the user to the list of users with registered devices, if not already there
    kvstore_users = KvStore(constants.REGISTERED_USERS_COLLECTION_NAME,
                            system_authtoken)
    kvstore_users.insert_or_update_item_containing_key({'_key': user})

    kvstore_nobody = KvStore(constants.DEVICE_PUBLIC_KEYS_COLLECTION_NAME,
                             system_authtoken)
    kvstore_nobody.insert_single_item(device_public_keys)

    # Deletes the temporary kvstore record
    kvstore_temp.delete_item_by_key(temp_key)

    LOGGER.info(
        'Device registration confirmed. Device with device_name=\"%s\" was recorded in the kvstore.'
        % temp_record[DEVICE_NAME_LABEL])

    return {
        'payload': 'Device registration successful',
        'status': 201,
    }
Exemple #5
0
def handle_saml_confirmation(auth_code, user, session_token, system_authtoken,
                             body):
    """
    Handler for the final DevicePairingConfirmationRequest call. This function:
        1. Authenticates the supplied user name
        2. Retrieves temporary record from the kvstore
        3. Checks if app_type has been disabled since registration
        4. Makes the DevicePairingConfirmationRequest request to the server
        5. Creates a new permanent record for the device in the kvstore
        6. Deletes the temporary kvstore record

    :param auth_code: User-entered authorization code to be returned to Spacebridge
    :param user: User provided by rest handler
    :param body: Parsed JSON body of the incoming POST request
    :param kvstore_unconfirmed: Access object for the temporary registration kvstore
    :param system_authtoken: System-level access token for writing to the kvstore
    :return: Success message
    """

    # Authenticates the supplied user name
    kvstore_temp = KvStore(constants.UNCONFIRMED_DEVICES_COLLECTION_NAME,
                           system_authtoken,
                           owner=user)
    encryption_context = SplunkEncryptionContext(
        system_authtoken, constants.SPACEBRIDGE_APP_NAME)

    LOGGER.info(
        'Received new registration confirmation request by user={}'.format(
            user))

    # Retrieves temporary record from the kvstore
    temp_key = extract_parameter(body, KVSTORE_TEMPORARY_ID_LABEL, BODY_LABEL)
    r, temp_record = kvstore_temp.get_item_by_key(temp_key)
    temp_record = json.loads(temp_record)

    device_id = temp_record[DEVICE_ID_LABEL]
    device_id_raw = base64.b64decode(device_id)

    device_registration = {
        constants.KEY: py23.urlsafe_b64encode_to_str(device_id_raw)
    }
    device_public_keys = {
        constants.KEY: py23.urlsafe_b64encode_to_str(device_id_raw)
    }

    for k in temp_record.keys():
        if k in DEVICE_REGISTRATION_ATTRS:
            device_registration[k] = temp_record[k]
        if k in DEVICE_PUBLIC_KEYS_ATTRS:
            device_public_keys[k] = temp_record[k]

    # Checks if app_type has been disabled since registration
    app_name = temp_record[DEVICE_TYPE_LABEL]

    device_encryption_info = DeviceInfo(
        base64.b64decode(temp_record['encrypt_public_key']),
        base64.b64decode(temp_record['sign_public_key']),
        base64.b64decode(temp_record['device_id']),
        "NA",
        app_id=temp_record['app_id'],
        app_name=temp_record['device_type'])

    deployment_friendly_name = get_deployment_friendly_name(system_authtoken)

    valid_request = is_valid_session_token(user, session_token)
    if valid_request:
        try:
            credentials = SplunkJWTCredentials(user)
            credentials.load_jwt_token(SplunkAuthHeader(system_authtoken))
            LOGGER.info(
                "Successfully fetched jwt token for SAML auth user with username={}"
                .format(user))
        except Exception as e:
            LOGGER.info(
                "Failed to fetch jwt token for user={} with message={}".format(
                    user, e.message))
            jwt_error_message = 'Registration Error: Failed to fetch jwt token for user={}'.format(
                user)
            return {
                'payload': {
                    'message': jwt_error_message,
                    'app_name': app_name,
                },
                'status': 422,
            }

        pair_device(auth_code,
                    credentials,
                    device_encryption_info,
                    encryption_context,
                    server_name=deployment_friendly_name,
                    config=config,
                    server_app_id=constants.SPLAPP_APP_ID)

        # Creates a new permanent record for the device in the kvstore
        kvstore_user = KvStore(constants.REGISTERED_DEVICES_COLLECTION_NAME,
                               system_authtoken,
                               owner=user)
        kvstore_user.insert_single_item(device_registration)

        # Adds the user to the list of users with registered devices, if not already there
        kvstore_users = KvStore(constants.REGISTERED_USERS_COLLECTION_NAME,
                                system_authtoken)
        kvstore_users.insert_or_update_item_containing_key(
            {constants.KEY: user})

        kvstore_nobody = KvStore(constants.DEVICE_PUBLIC_KEYS_COLLECTION_NAME,
                                 system_authtoken)
        kvstore_nobody.insert_single_item(device_public_keys)

        # Deletes the temporary kvstore record
        kvstore_temp.delete_item_by_key(temp_key)

        LOGGER.info(
            'Device registration confirmed. Device with device_name=\"%s\" was recorded in the kvstore.'
            % temp_record[DEVICE_NAME_LABEL])
    else:
        LOGGER.info("Error: Mismatched user={} and session token".format(user))
        jwt_error_message = 'Registration Error: Failed to fetch jwt token for user={}'.format(
            user)
        return {
            'payload': {
                'message': jwt_error_message,
                'app_name': app_name,
            },
            'status': 422,
        }

    return {
        'payload': 'Device registration successful',
        'status': 201,
    }