示例#1
0
def test_create_secret(user_secrets, no_db_user):
    """Test creation of user secrets."""
    corev1_api_client = Mock()
    corev1_api_client.read_namespaced_secret = Mock(
        side_effect=ApiException(reason="Secret does not exist.", status=404))
    with patch("reana_commons.k8s.secrets."
               "current_k8s_corev1_api_client", corev1_api_client):
        secrets_store = REANAUserSecretsStore(no_db_user.id_)
        secrets_store.add_secrets(user_secrets)
        corev1_api_client.create_namespaced_secret.assert_called_once()
        corev1_api_client.replace_namespaced_secret.assert_called_once()
示例#2
0
def test_overwrite_secret(corev1_api_client_with_user_secrets, user_secrets,
                          no_db_user):
    """Test overwriting secrets."""
    with patch(
            "reana_commons.k8s.secrets."
            "current_k8s_corev1_api_client",
            corev1_api_client_with_user_secrets(user_secrets),
    ) as api_client:
        secrets_store = REANAUserSecretsStore(no_db_user.id_)
        secrets_store.add_secrets(user_secrets, overwrite=True)
        api_client.replace_namespaced_secret.assert_called()
示例#3
0
def test_create_existing_secrets_fail(corev1_api_client_with_user_secrets,
                                      user_secrets, no_db_user):
    """Test create secrets which already exist without overwrite."""
    with patch(
            "reana_commons.k8s.secrets."
            "current_k8s_corev1_api_client",
            corev1_api_client_with_user_secrets(user_secrets),
    ) as api_client:
        secrets_store = REANAUserSecretsStore(no_db_user)
        with pytest.raises(REANASecretAlreadyExists):
            secrets_store.add_secrets(user_secrets)
        api_client.replace_namespaced_secret.assert_not_called()
def test_overwrite_secret(corev1_api_client_with_user_secrets, user_secrets,
                          test_user):
    """Test overwriting secrets."""
    with patch('reana_commons.k8s.secrets.'
               'current_k8s_corev1_api_client',
               corev1_api_client_with_user_secrets):
        secrets_store = REANAUserSecretsStore(test_user)
        secrets_list = secrets_store.add_secrets(user_secrets, overwrite=True)
        corev1_api_client_with_user_secrets. \
            replace_namespaced_secret.assert_called()
示例#5
0
def add_secrets():  # noqa
    r"""Endpoint to create user secrets.

    ---
    post:
      summary: Add user secrets to REANA.
      description: >-
        This resource adds secrets for the authenticated user.
      operationId: add_secrets
      produces:
        - application/json
      parameters:
        - name: access_token
          in: query
          description: Secrets owner access token.
          required: false
          type: string
        - name: overwrite
          in: query
          description: Whether existing secret keys should be overwritten.
          required: false
          type: boolean
        - name: secrets
          in: body
          description: >-
            Optional. List of secrets to be added.
          required: true
          schema:
            type: object
            additionalProperties:
              type: object
              description: Secret definition.
              properties:
                name:
                  type: string
                  description: Secret name
                value:
                  type: string
                  description: Secret value
                type:
                  type: string
                  enum:
                    - env
                    - file
                  description: >-
                    How will be the secret assigned to the jobs, either
                    exported as an environment variable or mounted as a file.
      responses:
        201:
          description: >-
            Secrets successfully added.
          schema:
            type: object
            properties:
              message:
                type: string
          examples:
            application/json:
              {
                "message": "Secret(s) successfully added."
              }
        403:
          description: >-
            Request failed. Token is not valid.
          examples:
            application/json:
              {
                "message": "Token is not valid"
              }
        409:
          description: >-
            Request failed. Secrets could not be added due to a conflict.
          examples:
            application/json:
              {
                "message": "The submitted secrets api_key, password,
                            username already exist."
              }
        500:
          description: >-
            Request failed. Internal server error.
          examples:
            application/json:
              {
                "message": "Internal server error."
              }
    """
    try:
        if current_user.is_authenticated:
            user = _get_user_from_invenio_user(current_user.email)
        else:
            user = get_user_from_token(request.args.get('access_token'))
        secrets_store = REANAUserSecretsStore(str(user.id_))
        overwrite = json.loads(request.args.get('overwrite'))
        secrets_store.add_secrets(request.json, overwrite=overwrite)
        return jsonify({"message": "Secret(s) successfully added."}), 201
    except REANASecretAlreadyExists as e:
        return jsonify({"message": str(e)}), 409
    except ValueError:
        return jsonify({"message": "Token is not valid."}), 403
    except Exception as e:
        logging.error(traceback.format_exc())
        return jsonify({"message": str(e)}), 500
示例#6
0
def gitlab_oauth():  # noqa
    r"""Endpoint to authorize REANA on GitLab.
    ---
    get:
      summary: Get access token from GitLab
      operationId: gitlab_oauth
      description: >-
        Authorize REANA on GitLab.
      produces:
       - application/json
      responses:
        200:
          description: >-
            Ping succeeded.
          schema:
            type: object
            properties:
              message:
                type: string
              status:
                type: string
          examples:
            application/json:
              message: OK
              status: 200
        201:
          description: >-
            Authorization succeeded. GitLab secret created.
          schema:
            type: object
            properties:
              message:
                type: string
              status:
                type: string
          examples:
            application/json:
              message: GitLab secret created
              status: 201
        403:
          description: >-
            Request failed. User token not valid.
          examples:
            application/json:
              {
                "message": "Token is not valid."
              }
        500:
          description: >-
            Request failed. Internal controller error.
    """
    try:
        if current_user.is_authenticated:
            user = _get_user_from_invenio_user(current_user.email)
        else:
            user = get_user_from_token(request.args.get("access_token"))
        if "code" in request.args:
            # Verifies state parameter and obtain next url
            state_token = request.args.get("state")
            assert state_token
            # Checks authenticity and integrity of state and decodes the value.
            state = serializer.loads(state_token)
            # Verifies that state is for this session and that next parameter
            # has not been modified.
            assert state["sid"] == _create_identifier()
            # Stores next URL
            next_url = state["next"]
            gitlab_code = request.args.get("code")
            params = {
                "client_id": REANA_GITLAB_OAUTH_APP_ID,
                "client_secret": REANA_GITLAB_OAUTH_APP_SECRET,
                "redirect_uri": url_for(".gitlab_oauth", _external=True),
                "code": gitlab_code,
                "grant_type": "authorization_code",
            }
            gitlab_response = requests.post(REANA_GITLAB_URL + "/oauth/token",
                                            data=params).content
            secrets_store = REANAUserSecretsStore(str(user.id_))
            secrets_store.add_secrets(_format_gitlab_secrets(gitlab_response),
                                      overwrite=True)
            return redirect(next_url), 201
        else:
            return jsonify({"message": "OK"}), 200
    except ValueError:
        return jsonify({"message": "Token is not valid."}), 403
    except (AssertionError, BadData):
        return jsonify({"message": "State param is invalid."}), 403
    except Exception as e:
        logging.error(traceback.format_exc())
        return jsonify({"message": str(e)}), 500
示例#7
0
def gitlab_oauth():  # noqa
    r"""Endpoint to authorize REANA on GitLab.
    ---
    get:
      summary: Get access token from GitLab
      operationId: gitlab_oauth
      description: >-
        Authorize REANA on GitLab.
      produces:
       - application/json
      responses:
        200:
          description: >-
            Ping succeeded.
          schema:
            type: object
            properties:
              message:
                type: string
              status:
                type: string
          examples:
            application/json:
              message: OK
              status: 200
        201:
          description: >-
            Authorization succeeded. GitLab secret created.
          schema:
            type: object
            properties:
              message:
                type: string
              status:
                type: string
          examples:
            application/json:
              message: GitLab secret created
              status: 201
        403:
          description: >-
            Request failed. User token not valid.
          examples:
            application/json:
              {
                "message": "Token is not valid."
              }
        500:
          description: >-
            Request failed. Internal controller error.
    """
    try:
        if current_user.is_authenticated:
            user = _get_user_from_invenio_user(current_user.email)
        else:
            user = get_user_from_token(request.args.get('access_token'))
        if 'code' in request.args:
            gitlab_code = request.args.get('code')
            parameters = "client_id={0}&" + \
                         "client_secret={1}&code={2}&" + \
                         "grant_type=authorization_code&redirect_uri={3}"
            parameters = parameters.format(REANA_GITLAB_OAUTH_APP_ID,
                                           REANA_GITLAB_OAUTH_APP_SECRET,
                                           gitlab_code,
                                           REANA_GITLAB_OAUTH_REDIRECT_URL)
            gitlab_response = requests.post(REANA_GITLAB_URL + '/oauth/token',
                                            data=parameters).content
            secrets_store = REANAUserSecretsStore(str(user.id_))
            secrets_store.add_secrets(_format_gitlab_secrets(gitlab_response),
                                      overwrite=True)
            return jsonify({"message": "GitLab secret created"}), 201
        else:
            return jsonify({"message": "OK"}), 200
    except ValueError:
        return jsonify({"message": "Token is not valid."}), 403
    except Exception as e:
        logging.error(traceback.format_exc())
        return jsonify({"message": str(e)}), 500