Skip to content

Commit 41b20eb

Browse files
committed
Merge remote-tracking branch 'upstream/master' into feat/s3-delete-files
2 parents acfe08f + 234638e commit 41b20eb

File tree

83 files changed

+4175
-1840
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

83 files changed

+4175
-1840
lines changed

.github/workflows/buildpipeline.yaml renamed to .github/workflows/ci.yaml

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,27 @@
11
name: CI
2-
32
on:
4-
push:
5-
pull_request:
6-
types: [opened, reopened]
7-
3+
push:
4+
pull_request:
5+
types: [opened, reopened]
86
concurrency:
97
group: '${{ github.workflow }} @ ${{ github.event.pull_request.head.label || github.head_ref || github.ref }}'
108
cancel-in-progress: true
11-
12-
139
jobs:
1410
Security:
1511
name: Security Pipeline
1612
uses: uc-cdis/.github/.github/workflows/securitypipeline.yaml@master
1713
secrets: inherit
1814

15+
UnitTest:
16+
name: Python Unit Test with Postgres
17+
uses: uc-cdis/.github/.github/workflows/python_unit_test.yaml@master
18+
with:
19+
python-version: '3.9'
20+
test-script: 'tests/ci_commands_script.sh'
21+
run-coveralls: true
1922
ci:
2023
name: Build Image and Push
21-
# TODO Add this line back once we update to Python 3.9 from 3.6
24+
# TODO Uncomment after PXP-9212
2225
# needs: Security
2326
uses: uc-cdis/.github/.github/workflows/image_build_push.yaml@master
2427
secrets:

.secrets.baseline

Lines changed: 34 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -115,13 +115,13 @@
115115
}
116116
],
117117
"results": {
118-
".github/workflows/buildpipeline.yaml": [
118+
".github/workflows/ci.yaml": [
119119
{
120120
"type": "Secret Keyword",
121-
"filename": ".github/workflows/buildpipeline.yaml",
121+
"filename": ".github/workflows/ci.yaml",
122122
"hashed_secret": "3e26d6750975d678acb8fa35a0f69237881576b0",
123123
"is_verified": false,
124-
"line_number": 17
124+
"line_number": 13
125125
}
126126
],
127127
"deployment/scripts/postgresql/postgresql_init.sql": [
@@ -210,13 +210,22 @@
210210
"line_number": 137
211211
}
212212
],
213+
"fence/resources/storage/storageclient/cleversafe.py": [
214+
{
215+
"type": "Secret Keyword",
216+
"filename": "fence/resources/storage/storageclient/cleversafe.py",
217+
"hashed_secret": "7cb6efb98ba5972a9b5090dc2e517fe14d12cb04",
218+
"is_verified": false,
219+
"line_number": 274
220+
}
221+
],
213222
"fence/utils.py": [
214223
{
215224
"type": "Secret Keyword",
216225
"filename": "fence/utils.py",
217226
"hashed_secret": "8318df9ecda039deac9868adf1944a29a95c7114",
218227
"is_verified": false,
219-
"line_number": 128
228+
"line_number": 129
220229
}
221230
],
222231
"migrations/versions/a04a70296688_non_unique_client_name.py": [
@@ -259,14 +268,14 @@
259268
"filename": "tests/conftest.py",
260269
"hashed_secret": "1348b145fa1a555461c1b790a2f66614781091e9",
261270
"is_verified": false,
262-
"line_number": 1559
271+
"line_number": 1561
263272
},
264273
{
265274
"type": "Base64 High Entropy String",
266275
"filename": "tests/conftest.py",
267276
"hashed_secret": "227dea087477346785aefd575f91dd13ab86c108",
268277
"is_verified": false,
269-
"line_number": 1582
278+
"line_number": 1583
270279
}
271280
],
272281
"tests/credentials/google/test_credentials.py": [
@@ -385,6 +394,24 @@
385394
"line_number": 300
386395
}
387396
],
397+
"tests/storageclient/storage_client_mock.py": [
398+
{
399+
"type": "Secret Keyword",
400+
"filename": "tests/storageclient/storage_client_mock.py",
401+
"hashed_secret": "37bbea9557f9efd1eeadb25dda9ab6514f08fde9",
402+
"is_verified": false,
403+
"line_number": 158
404+
}
405+
],
406+
"tests/storageclient/test_cleversafe_api_client.py": [
407+
{
408+
"type": "Secret Keyword",
409+
"filename": "tests/storageclient/test_cleversafe_api_client.py",
410+
"hashed_secret": "f683c485d521c2e45830146dd570111770baea29",
411+
"is_verified": false,
412+
"line_number": 130
413+
}
414+
],
388415
"tests/test-fence-config.yaml": [
389416
{
390417
"type": "Basic Auth Credentials",
@@ -395,5 +422,5 @@
395422
}
396423
]
397424
},
398-
"generated_at": "2023-11-16T21:15:57Z"
425+
"generated_at": "2024-03-16T00:09:27Z"
399426
}

.travis.yml

Lines changed: 0 additions & 51 deletions
This file was deleted.

bin/fence_create.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,9 @@ def parse_arguments():
329329
help='scopes to include in the token (e.g. "user" or "data")',
330330
)
331331
token_create.add_argument("--exp", help="time in seconds until token expiration")
332+
token_create.add_argument(
333+
"--client_id", help="Client Id, required to generate refresh token"
334+
)
332335

333336
force_link_google = subparsers.add_parser("force-link-google")
334337
force_link_google.add_argument(
@@ -581,6 +584,7 @@ def main():
581584
username=args.username,
582585
scopes=args.scopes,
583586
expires_in=args.exp,
587+
client_id=args.client_id,
584588
)
585589
token_type = str(args.type).strip().lower()
586590
if token_type == "access_token" or token_type == "access":

docs/base_user.yaml

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -78,14 +78,16 @@ authz:
7878
- /programs
7979
- id: open_data_reader
8080
role_ids:
81-
- reader
82-
- storage_reader
81+
- peregrine_reader
82+
- guppy_reader
83+
- fence_storage_reader
8384
resource_paths:
8485
- /open
8586
- id: all_programs_reader
8687
role_ids:
87-
- reader
88-
- storage_reader
88+
- peregrine_reader
89+
- guppy_reader
90+
- fence_storage_reader
8991
resource_paths:
9092
- /programs
9193
- id: MyFirstProject_submitter
@@ -168,6 +170,24 @@ authz:
168170
action:
169171
service: '*'
170172
method: read-storage
173+
- id: peregrine_reader
174+
permissions:
175+
- id: peregrine_reader
176+
action:
177+
method: read
178+
service: peregrine
179+
- id: guppy_reader
180+
permissions:
181+
- id: guppy_reader
182+
action:
183+
method: read
184+
service: guppy
185+
- id: fence_storage_reader
186+
permissions:
187+
- id: fence_storage_reader
188+
action:
189+
method: read-storage
190+
service: fence
171191

172192
clients:
173193
wts:

docs/google_architecture.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ We'll talk about each one of those in-depth here (and even delve into the intern
1717

1818
### Fence -> cirrus -> Google: A library wrapping Google's API
1919

20-
We have a library that wraps Google's public API called [cirrus](https://github.com/uc-cdis/cirrus). Our design is such that fence does not hit Google's API directly, but goes through cirrus. For all of cirrus's features to work, a very specific setup is required, which is detailed in cirrus's README.
20+
We have a library that wraps Google's public API called [cirrus](https://github.com/uc-cdis/cirrus). Our design is such that fence does not hit Google's API directly, but goes through gen3cirrus. For all of cirrus's features to work, a very specific setup is required, which is detailed in cirrus's README.
2121

2222
Essentially, cirrus requires a Google Cloud Identity account (for group management) and
2323
Google Cloud Platform project(s). In order to automate group management in Google Cloud Identity with cirrus, you must go through a manual process of allowing API access and delegating a specific service account from a Google Cloud Platform project to have group management authority. Details can be found in cirrus's README.

fence/__init__.py

Lines changed: 5 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
import flask
66
from flask_cors import CORS
77
from sqlalchemy.orm import scoped_session
8-
from flask import _app_ctx_stack, current_app
8+
from flask import current_app
99
from werkzeug.local import LocalProxy
1010

1111
from authutils.oauth2.client import OAuthClient
@@ -364,7 +364,6 @@ def app_config(
364364
_setup_audit_service_client(app)
365365
_setup_data_endpoint_and_boto(app)
366366
_load_keys(app, root_dir)
367-
_set_authlib_cfgs(app)
368367

369368
app.prometheus_counters = {}
370369
if config["ENABLE_PROMETHEUS_METRICS"]:
@@ -407,24 +406,6 @@ def _load_keys(app, root_dir):
407406
}
408407

409408

410-
def _set_authlib_cfgs(app):
411-
# authlib OIDC settings
412-
# key will need to be added
413-
settings = {"OAUTH2_JWT_KEY": keys.default_private_key(app)}
414-
app.config.update(settings)
415-
config.update(settings)
416-
417-
# only add the following if not already provided
418-
config.setdefault("OAUTH2_JWT_ENABLED", True)
419-
config.setdefault("OAUTH2_JWT_ALG", "RS256")
420-
config.setdefault("OAUTH2_JWT_ISS", app.config["BASE_URL"])
421-
config.setdefault("OAUTH2_PROVIDER_ERROR_URI", "/api/oauth2/errors")
422-
app.config.setdefault("OAUTH2_JWT_ENABLED", True)
423-
app.config.setdefault("OAUTH2_JWT_ALG", "RS256")
424-
app.config.setdefault("OAUTH2_JWT_ISS", app.config["BASE_URL"])
425-
app.config.setdefault("OAUTH2_PROVIDER_ERROR_URI", "/api/oauth2/errors")
426-
427-
428409
def _setup_oidc_clients(app):
429410
configured_idps = config.get("OPENID_CONNECT", {})
430411

@@ -482,7 +463,10 @@ def _setup_oidc_clients(app):
482463
logger=logger,
483464
)
484465
elif idp == "fence":
485-
app.fence_client = OAuthClient(**settings)
466+
# https://docs.authlib.org/en/latest/client/flask.html#flask-client
467+
app.fence_client = OAuthClient(app)
468+
# https://docs.authlib.org/en/latest/client/frameworks.html
469+
app.fence_client.register(**settings)
486470
else: # generic OIDC implementation
487471
client = Oauth2ClientBase(
488472
settings=settings,

fence/auth.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,10 @@ def get_jwt():
3535
try:
3636
bearer, token = header.split(" ")
3737
except ValueError:
38-
raise Unauthorized("authorization header not in expected format")
38+
msg = "authorization header not in expected format"
39+
logger.debug(f"{msg}. Received header: {header}")
40+
logger.error(f"{msg}.")
41+
raise Unauthorized(msg)
3942
if bearer.lower() != "bearer":
4043
raise Unauthorized("expected bearer token in auth header")
4144
return token

0 commit comments

Comments
 (0)