Commit e474c788 authored by Diego Molteni's avatar Diego Molteni Committed by Sacha Brants
Browse files

refactor: impersonation token

parent 69fc9d0e
......@@ -44,8 +44,7 @@ include:
file: "standard-setup.yml"
# build
- project: "osdu/platform/ci-cd-pipelines"
file: "build/seismic-store-service.yml"
- local: "devops/osdu/build/seismic-store-service.yml"
# scan
#fossa
......@@ -65,8 +64,7 @@ include:
# deploy
#azure
- project: "osdu/platform/ci-cd-pipelines"
file: "cloud-providers/azure-seismic-store-service.yml"
- local: "/devops/osdu/cloud-providers/azure-seismic-store-service.yml"
#ibm
- project: "osdu/platform/ci-cd-pipelines"
......
compile-and-unit-test:
image: community.opengroup.org:5555/osdu/platform/domain-data-mgmt-services/seismic/seismic-dms-suite/seismic-store-service/seismic-store-service-builder:14
tags: ["osdu-medium"]
stage: build
artifacts:
reports:
junit: test-results.xml
cobertura: coverage/cobertura-coverage.xml
paths:
- coverage/
expire_in: 15 days
script:
- chmod +x devops/scripts/utest_build_run.sh
- devops/scripts/utest_build_run.sh
variables:
CHART_PATH: devops/azure/chart
CLOUD_PROVIDER: azure
E2E_ADMIN_EMAIL: integration.test@azureglobal1.onmicrosoft.com
E2E_DATA_PARTITION: opendes
E2E_LEGALTAG01: opendes-public-usa-dataset-7643990
E2E_LEGALTAG02: opendes-dps-integration-test-valid2-legal-tag
E2E_SUBPROJECT: demosandbox02
E2E_SUBPROJECT_LONG_NAME: looooooooooooooooooooooooooooooooooooooooooooooooooooongnaaaaaaaaaaaaaaaaaaaameeeeeee
E2E_TENANT: opendes
POD_IDENTITY: osdu-identity
REDIS_INSTANCE_PORT: 6380
azure_deploy:
tags: ["osdu-medium"]
image: danielscholl/azure-build-image
stage: deploy
needs: ["push_runtime_image_azure"]
variables:
AZURE_KEYVAULT: osdu-svc-properties
DES_URL: ${AZURE_DNS_NAME}
IMAGE: ${AZURE_REGISTRY}.azurecr.io/${CI_PROJECT_NAME}-${CI_COMMIT_REF_SLUG}
SERVICE_NAME: ${AZURE_SERVICE}
TAG: ${CI_COMMIT_SHA}
before_script:
- az login --service-principal -u $AZURE_PRINCIPAL_ID -p $AZURE_PRINCIPAL_SECRET --tenant $AZURE_TENANT_ID
- az aks get-credentials -g $AZURE_UNIQUE-rg -n $AZURE_UNIQUE-aks
script:
# Replace values in config file
- cp ${CHART_PATH}/helm-config.yaml ${CHART_PATH}/values.yaml
- sed -i 's,#{CONTAINER_REGISTRY_NAME}#,'$IMAGE',' ${CHART_PATH}/values.yaml
- sed -i 's,#{DNS_HOST}#,'$DES_URL',' ${CHART_PATH}/values.yaml
- sed -i 's/#{ENVIRONMENT_NAME}#/'$ENVIRONMENT'/' ${CHART_PATH}/values.yaml
- sed -i 's/#{IMAGE_TAG}#/'$TAG'/' ${CHART_PATH}/values.yaml
- sed -i 's/#{KEYVAULT_NAME}#/'$AZURE_KEYVAULT'/' ${CHART_PATH}/values.yaml
- sed -i 's/#{PORT}#/'${PORT}'/' ${CHART_PATH}/values.yaml
- sed -i 's/#{PROVIDER_NAME}#/'$CLOUD_PROVIDER'/' ${CHART_PATH}/values.yaml
- sed -i 's/#{REDIS_HOST}#/'$REDIS_INSTANCE_ADDRESS'/' ${CHART_PATH}/values.yaml
- sed -i 's/#{REDIS_PORT}#/'$REDIS_INSTANCE_PORT'/' ${CHART_PATH}/values.yaml
- sed -i 's/#{REPLICA_COUNT}#/'$REPLICA'/' ${CHART_PATH}/values.yaml
# Install helm chart
- helm upgrade $SERVICE_NAME ${CHART_PATH} --install --dry-run --values $CHART_PATH/values.yaml
- helm upgrade $SERVICE_NAME ${CHART_PATH} --install --values $CHART_PATH/values.yaml
# Wait for service to be running to start
- kubectl rollout status deployment.v1.apps/$SERVICE_NAME -n osdu --timeout=900s
- pod=$(kubectl get pod -n osdu|grep $CI_PROJECT_NAME |tail -1 |awk '{print $1}')
- status=$(kubectl wait -n osdu --for=condition=Ready pod/$pod --timeout=600s)
- if [[ "$status" != *"met"* ]]; then echo "POD didn't start correctly" ; exit 1 ; fi
only:
variables:
- $AZURE == 'true'
azure_test:
tags: ["osdu-medium"]
image: node
stage: integration
needs: ["azure_deploy"]
variables:
AZURE_AD_APP_RESOURCE_ID: $AZURE_APP_ID
AZURE_AD_TENANT_ID: $AZURE_TENANT_ID
AZURE_TESTER_SERVICEPRINCIPAL_SECRET: $AZURE_PRINCIPAL_SECRET
INTEGRATION_TESTER: $AZURE_PRINCIPAL_ID
script:
- apt-get update
- apt-get install -y python
- apt-get install -y python-pip
- pip install msal
- svctoken=$(python devops/scripts/azure_jwt_client.py)
- echo $svctoken
- npm install -g newman
- chmod +x ./tests/e2e/run_e2e_tests.sh
- ./tests/e2e/run_e2e_tests.sh --seistore-svc-url="https://${AZURE_DNS_NAME}/seistore-svc/api/v3" --seistore-svc-api-key="NA" --user-idtoken="$svctoken" --user1-idtoken="$svctoken" --tenant="${E2E_TENANT}" --subproject="${E2E_SUBPROJECT}" --admin-email="${E2E_ADMIN_EMAIL}" --datapartition="${E2E_DATA_PARTITION}" --legaltag01="${E2E_LEGALTAG01}" --legaltag02="${E2E_LEGALTAG02}" --subproject-long-name="${E2E_SUBPROJECT_LONG_NAME}" --VCS-Provider="${ISGITLAB}"
only:
variables:
- $AZURE == 'true'
......@@ -227,7 +227,7 @@ paths:
<li>Required roles: subproject.admin, subproject.editor</li>
<li>Patchable fields: <ul>
<li><b>dataset_new_name:</b> new name to use for the dataset (rename).</li>
<li><b>filemetadata:</b> This is a seismic store specific field and describes how the physical data is stored in the cloud storage system (GCS/AzureContainer etc.). This metadata is mainly used by client libraries to correctly reconstruct the dataset. For example you can store a dataset as truncated in multiple objects of 64MB each, name them from 0 to N and save the filemetadata = “{nOboject: N, totalSize: 1024, objsize: 64, sizeUnit: MB}”.</li>
<li><b>filemetadata:</b> This is a seismic store specific field and describes how the physical data is stored in the cloud storage system (GCS/AzureContainer etc.). This metadata is mainly used by client libraries to correctly reconstruct the dataset. For example you can store a dataset as truncated in multiple objects of 64MB each, name them from 0 to N and save the filemetadata = “{nObject: N, totalSize: 1024, objsize: 64, sizeUnit: MB}”.</li>
<li><b>last_modified_date:</b> Mark this field as true to update the dataset last modified date.</li>
<li><b>gtags:</b> Upsert tags to an existing dataset metadata. If the dataset metadata already has gtags, then new gtags are appended to this list.</li>
<li><b>ltag:</b> Update the existing legalTag value.</b></li>
......@@ -835,19 +835,19 @@ paths:
<li>Required roles: app.trusted</li></ul>"
operationId: imp-token
tags:
- Impersonation Token
- Impersonation Token (Obsolete)
parameters:
- description: "Request body"
in: body
name: request body
required: true
schema:
$ref: "#/definitions/ImpTokenRequest"
$ref: "#/definitions/ImpersonationToken"
responses:
200:
description: "Generated a impersonation credentials token successfully."
schema:
$ref: "#/definitions/ImpToken"
$ref: "#/definitions/ImpersonationToken"
400:
description: "Bad request."
401:
......@@ -864,7 +864,7 @@ paths:
- api-key: []
operationId: imp-token-refresh
tags:
- Impersonation Token
- Impersonation Token (Obsolete)
parameters:
- description: "Request body"
in: body
......@@ -876,7 +876,7 @@ paths:
200:
description: "Refreshed impersonation credential token successfully."
schema:
$ref: "#/definitions/ImpToken"
$ref: "#/definitions/ImpersonationToken"
400:
description: "Bad request."
401:
......@@ -893,7 +893,7 @@ paths:
<li>Required roles: none</li></ul>"
operationId: imp-token-patch
tags:
- Impersonation Token
- Impersonation Token (Obsolete)
parameters:
- description: "Request body"
in: body
......@@ -905,7 +905,139 @@ paths:
200:
description: "Generated impersonation token successfully and its refresh url is updated."
schema:
$ref: "#/definitions/ImpToken"
$ref: "#/definitions/ImpersonationToken"
400:
description: "Bad request"
401:
description: "Unauthorized"
403:
description: "Forbidden"
404:
description: "Not found"
/api/v3/impersonation-token:
post:
summary: "Create an impersonation token credential."
description: "<ul><li>Generate a credential token to impersonate user access for a set of subproject resources.</li><li>Required roles: app.trusted</li></ul>"
operationId: impersonation-token-generate
tags:
- Impersonation Token
parameters:
- description: "The credential of the user to impersonate."
in: header
name: user-token
type: string
required: true
default: ""
- description: "Request body."
in: body
name: request body
required: true
schema:
$ref: "#/definitions/ImpersonationTokenRequest"
responses:
200:
description: "The impersonation token has been successfully created."
schema:
$ref: "#/definitions/ImpersonationToken"
400:
description: "Bad request"
401:
description: "Unauthorized"
403:
description: "Forbidden"
404:
description: "Not found"
put:
summary: "Refresh the impersonation credential token."
description: "<ul><li>Refresh an impersonation credential token.</li><li>Required roles: app.trusted</li></ul>"
operationId: impersonation-token-refresh
tags:
- Impersonation Token
parameters:
- description: "The impersonation token to refresh."
in: header
name: impersonation-token
type: string
required: true
default: ""
- description: "The name of the tenant/data-partition."
in: query
name: tenant-name
type: string
required: true
default: ""
responses:
200:
description: "Refreshed impersonation credential token successfully."
schema:
$ref: "#/definitions/ImpersonationToken"
400:
description: "Bad request"
401:
description: "Unauthorized"
403:
description: "Forbidden"
404:
description: "Not found"
delete:
summary: "Revoke the impersonation token and/or a list of impersonation token signatures."
description: "<ul><li>Revoke the impersonation token and/or a list of impersonation token signatures</li><li>Required roles: app.trusted</li></ul>"
operationId: impersonation-token-revoke
tags:
- Impersonation Token
parameters:
- description: "The impersonation token to revoke (required if the signatures body field is not specified)."
in: header
name: impersonation-token
type: string
required: false
default: ""
- description: "The name of the tenant/data-partition."
in: query
name: tenant-name
type: string
required: true
default: ""
- description: "List of impersonation token signatures."
in: query
name: signatures
required: false
type: array
items:
type: string
default: ""
collectionFormat: multi
responses:
200:
description: "The impersonation token and/or the requested signatures have been successfully revoked."
400:
description: "Bad request"
401:
description: "Unauthorized"
403:
description: "Forbidden"
404:
description: "Not found"
/api/v3/impersonation-token/signatures:
get:
summary: "Retrieve the list of active impersonation token signatures."
description: "<ul><li>Retrieve the list of active impersonation token signatures.</li><li>Required roles: app.trusted</li></ul>"
operationId: impersonation-token-signature
tags:
- Impersonation Token
parameters:
- description: "The name of the tenant/data-partition"
in: query
name: tenant-name
type: string
required: true
default: ""
responses:
200:
description: "The list of signatures with their metadata."
schema:
$ref: "#/definitions/ImpersonationTokenSignatureResponse"
400:
description: "Bad request."
401:
......@@ -1422,6 +1554,7 @@ paths:
# ===========================================================================
definitions:
# OK
Status:
required: ["status"]
......@@ -1712,25 +1845,25 @@ definitions:
type: number
description: Time in seconds for expiration of the access token.
example:
access_token: "ya29.fgdgsdngevrjbinb0ednberoibnerbnerber-fdsfwefwe_cece"
access_token: "ya29.fgdgsdngevrjbinb0exdnberoibnerbnerber-fdsfwefwe_cece.rfd43f3"
token_type: "Bearer"
expires_in: 3600
# OK
ImpToken:
ImpersonationToken:
required: ["impersonation_token", "token_type", "expires_in"]
properties:
impersonation_token:
type: string
description: Impersonation token.
description: The Impersonation token.
token_type:
type: string
description: Type of the token.
description: Token type.
expires_in:
type: number
description: Time in seconds for the expiration of the impersonation token.
description: Token expiration time.
example:
impersonation_token: "ya29.fgdgsdngevrjbinb0ednberoibnerbanerber-fdsfwefwe_cece"
impersonation_token: "ya29.fgdgsdngevrjbinb0exdnberoibnerbnerber-fdsfwefwe_cece.rfd43f3"
token_type: "Bearer"
expires_in: 3600
......@@ -1743,6 +1876,55 @@ definitions:
readonly:
type: boolean
# OK
ImpersonationTokenRequest:
required: ["resources"]
properties:
resources:
type: array
items:
$ref: "#/definitions/Resource"
metadata:
type: object
description: A general field to set extra meta-information to the impersonation token signature. These are saved along with the token signatures.
example:
resources:
[
{ "resource": "sd://tnx01/spx01", "readonly": true },
{ "resource": "sd://tnx01/spx02", "readonly": false }
]
metadata: { "jobId": 1234 }
# OK
ImpersonationTokenSignature:
required: ["created_by", "created_date", "resources", "signature"]
properties:
created_by:
type: string
description: The trusted app id .
created_date:
type: string
description: The create date and time.
resources:
type: array
items:
$ref: "#/definitions/Resource"
signature:
type: string
description: the impersonation token signature.
metadata:
type: object
description: the custom metadata associated.
# OK
ImpersonationTokenSignatureResponse:
required: ["signatures"]
properties:
signatures:
type: array
items:
$ref: "#/definitions/ImpersonationTokenSignature"
# OK
ImpTokenRequest:
required: ["token", "resources", "refresh-url"]
......@@ -1767,6 +1949,7 @@ definitions:
]
refresh-url: "https://httpstat.us/200"
# OK
ImpTokenPatchRequest:
required: ["token", "refresh-url"]
properties:
......@@ -1788,7 +1971,8 @@ definitions:
type: string
description: Impersonation token
example:
token: "eyJhbxGccCI6IkpX.fgdgsdngfwe_cec.xc2Vpc21pYy1ddzZXJ2aWNl"
token: "ya29.fgdgsdngevrjbinb0exdnberoibnerbnerber-fdsfwefwe_cece.rfd43f3"
# OK
SubProjectCreateBody:
required: ["admin", "storage_class", "storage_location", "access_policy"]
......@@ -1834,7 +2018,7 @@ definitions:
properties:
access_policy:
type: string
description: Acesss Policy for the subproject.
description: Access Policy for the subproject.
default: "dataset"
acls:
type: object
......@@ -1957,7 +2141,7 @@ definitions:
enum: [viewer, editor, admin]
example:
email: "test@slb.com"
path: "sd://slb/testproject"
path: "sd://slb/test_project"
group: "editor"
# OK
......@@ -1972,7 +2156,7 @@ definitions:
description: Seismic store path in the format sd://tenant/subproject.
example:
email: "test@email"
path: "sd://slb/testproject"
path: "sd://slb/test_project"
# OK
UserRoles:
......@@ -1994,7 +2178,7 @@ definitions:
description: Array of directories and datasets inside a subproject.
items:
type: string
example: ["subdirA/", "subdirB/", "dataset01", "dataset02", "dataset03"]
example: ["folderA/", "folderB/", "dataset01", "dataset02", "dataset03"]
# OK
LsPaginatedDatasets:
......@@ -2008,7 +2192,7 @@ definitions:
nextPageCursor:
type: string
description: Next cursor for pagination.
example: { datasets: ["subdirA/", "subdirB/", "dataset01"], nextPageCursor: "abc1234" }
example: { datasets: ["folderA/", "folderB/", "dataset01"], nextPageCursor: "abc1234" }
# ===========================================================================
# Endpoints Security Section
......
......@@ -236,7 +236,7 @@ paths:
patch:
summary: "Patch the dataset metadata"
description: "<ul><li>Update the dataset meta information in seismic store or close(unlock) the dataset. If the endpoint is used without the close parameter, at least one body field is required or the endpoint will return an error.</li><li>Required roles: subproject.admin, subproject.editor</li><li>Patchable fields: <ul><li><b>dataset_new_name:</b> new name to use for the dataset (rename)</li><li><b>filemetadata:</b> this is a seistore specific field and describe how the physical data are stored in the cloud storage system (GCS/AzureContainer etc etc). This metadata is mainly used by client libraries to correctly reconstruct the dataset. For example you can store a dataset as truncated in multiple objects of 64MB each, name them from 0 to N and save the filemetadata = “{nOboject: N, totalSize: 1024, objsize: 64, sizeUnit: MB }”.</li><li><b>last_modified_date:</b> mark this field as true to update the dataset last modified date</li><li><b>gtags:</b> upsert tags to an existing dataset metadata. If the dataset metadata already has gtags, then new gtags are appended to this list.</li><li><b>ltag:</b> update the existing legalTag value</b></li><li><b>readonly:</b> update the dataset mode to readonly(true) or to read/write(false)</li><li><b>seismicmeta:</b> update the DataEcosystem storage metadata (refer to the DataEcosystem storage service tutorial for more help)</b></li></ul></li></ul>"
description: "<ul><li>Update the dataset meta information in seismic store or close(unlock) the dataset. If the endpoint is used without the close parameter, at least one body field is required or the endpoint will return an error.</li><li>Required roles: subproject.admin, subproject.editor</li><li>Patchable fields: <ul><li><b>dataset_new_name:</b> new name to use for the dataset (rename)</li><li><b>filemetadata:</b> this is a seistore specific field and describe how the physical data are stored in the cloud storage system (GCS/AzureContainer etc etc). This metadata is mainly used by client libraries to correctly reconstruct the dataset. For example you can store a dataset as truncated in multiple objects of 64MB each, name them from 0 to N and save the filemetadata = “{nObject: N, totalSize: 1024, objsize: 64, sizeUnit: MB }”.</li><li><b>last_modified_date:</b> mark this field as true to update the dataset last modified date</li><li><b>gtags:</b> upsert tags to an existing dataset metadata. If the dataset metadata already has gtags, then new gtags are appended to this list.</li><li><b>ltag:</b> update the existing legalTag value</b></li><li><b>readonly:</b> update the dataset mode to readonly(true) or to read/write(false)</li><li><b>seismicmeta:</b> update the DataEcosystem storage metadata (refer to the DataEcosystem storage service tutorial for more help)</b></li></ul></li></ul>"
operationId: dataset-patch
tags:
- Dataset
......@@ -836,7 +836,7 @@ paths:
description: "<ul><li>Generate an impersonation credential token of a user for a set of subproject resources.</li><li>Required roles: app.trusted</li></ul>"
operationId: imp-token
tags:
- Impersonation Token
- Impersonation Token (Obsolete)
parameters:
- description: "Request body"
in: body
......@@ -848,7 +848,7 @@ paths:
200:
description: "Generated a impersonation credentials token successfully"
schema:
$ref: "#/definitions/ImpToken"
$ref: "#/definitions/ImpersonationToken"
400:
description: "Bad request"
401:
......@@ -865,7 +865,7 @@ paths:
- api-key: []
operationId: imp-token-refresh
tags:
- Impersonation Token
- Impersonation Token (Obsolete)
parameters:
- description: "Request body"
in: body
......@@ -877,7 +877,7 @@ paths:
200:
description: "Refreshed impersonation credential token successfully"
schema:
$ref: "#/definitions/ImpToken"
$ref: "#/definitions/ImpersonationToken"
400:
description: "Bad request"
401:
......@@ -892,7 +892,7 @@ paths:
description: "<ul><li>Patch an impersonation credential token's refresh url and generate a new impersonation token.</li><li>Required roles: none</li></ul>"
operationId: imp-token-patch
tags:
- Impersonation Token
- Impersonation Token (Obsolete)
parameters:
- description: "Request body"
in: body
......@@ -904,7 +904,41 @@ paths:
200:
description: "Generated impersonation token successfully and its refresh url is updated"
schema:
$ref: "#/definitions/ImpToken"
$ref: "#/definitions/ImpersonationToken"
400:
description: "Bad request"
401:
description: "Unauthorized"
403:
description: "Forbidden"
404:
description: "Not found"
/api/v3/impersonation-token:
post:
summary: "Create an impersonation token credential."
description: "<ul><li>Generate a credential token to impersonate user access for a set of subproject resources.</li><li>Required roles: app.trusted</li></ul>"
operationId: impersonation-token-generate
tags:
- Impersonation Token
parameters:
- description: "The credential of the user to impersonate."
in: header
name: user-token
type: string
required: true
default: ""
- description: "Request body."
in: body
name: request body
required: true
schema:
$ref: "#/definitions/ImpersonationTokenRequest"
responses:
200:
description: "The impersonation token has been successfully created."
schema:
$ref: "#/definitions/ImpersonationToken"
400:
description: "Bad request"
401:
......@@ -913,6 +947,104 @@ paths:
description: "Forbidden"
404:
description: "Not found"
put:
summary: "Refresh the impersonation credential token."
description: "<ul><li>Refresh an impersonation credential token.</li><li>Required roles: app.trusted</li></ul>"
operationId: impersonation-token-refresh
tags:
- Impersonation Token
parameters:
- description: "The impersonation token to refresh."
in: header
name: impersonation-token
type: string
required: true
default: ""
- description: "The name of the tenant/data-partition."
in: query
name: tenant-name
type: string
required: true
default: ""
responses:
200:
description: "Refreshed impersonation credential token successfully."
schema:
$ref: "#/definitions/ImpersonationToken"
400:
description: "Bad request"
401: