Skip to content

Commit

Permalink
access control for all APIs
Browse files Browse the repository at this point in the history
  • Loading branch information
ericpassmore committed Apr 19, 2024
1 parent 217d6c7 commit 2c49e59
Show file tree
Hide file tree
Showing 5 changed files with 193 additions and 62 deletions.
49 changes: 40 additions & 9 deletions orchestration-service/github_oauth.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ def assemble_oauth_url(state, properties):
+ f"&allow_signup=false"

@staticmethod
def get_access_token(code, properties):
def get_oauth_access_token(code, properties):
"""build url for the get token request"""
# construct http call to exchange tempory code for access token
params = {
Expand All @@ -41,10 +41,10 @@ def get_access_token(code, properties):
return None

@staticmethod
def get_public_profile(bearer_token, properties):
def create_auth_string(bearer_token, user_info_url):
"""get public profile information using token"""
# https request to get public profile data, login and avatar_url
user_avatar_response = requests.get(properties.get('user_info_url'),
user_avatar_response = requests.get(user_info_url,
timeout=3,
headers={
'Accept': 'application/vnd.github+json',
Expand All @@ -53,11 +53,11 @@ def get_public_profile(bearer_token, properties):
})
if user_avatar_response.status_code == 200:
user_data = json.loads(user_avatar_response.content.decode('utf-8'))
return GitHubOauth.profile_to_str(user_data['login'],user_data['avatar_url'])
return GitHubOauth.credentials_to_str(user_data['login'],user_data['avatar_url'],bearer_token)
return None

@staticmethod
def is_authorized(bearer_token, login, team_string):
def check_membership(bearer_token, login, team_string):
"""Check for team membership"""
if not login:
return False
Expand All @@ -79,13 +79,44 @@ def is_authorized(bearer_token, login, team_string):
return False

@staticmethod
def profile_to_str(login, avatar_url):
def is_authorized(cookies, header_token, user_info_url, team_string):
"""check for authorized token or cookie"""

token = None
if 'replay_auth' in cookies and cookies['replay_auth']:
token = GitHubOauth.extract_token(cookies['replay_auth'])
if header_token:
token = header_token
if not token:
return False

auth_string = GitHubOauth.create_auth_string(token, user_info_url)
login = GitHubOauth.extract_login(auth_string)
return GitHubOauth.check_membership(token, login, team_string)

@staticmethod
def credentials_to_str(login, avatar_url, token):
"""converts profile data to string sep by :"""
return login + ":" + avatar_url
return token + ":" + login + ":" + avatar_url

@staticmethod
def str_to_profile(data):
def str_to_public_profile(data):
"""converts str to array of profile data"""
if not data:
return []
return data.split(':', 1)
# return public profile data leaving off bearer token
return data.split(':', 2)[1:]

@staticmethod
def extract_token(data):
"""grabs the bearer token from string"""
if not data:
return []
return data.split(':', 2)[0]

@staticmethod
def extract_login(data):
"""grabs the bearer token from string"""
if not data:
return []
return data.split(':', 2)[1]
28 changes: 25 additions & 3 deletions orchestration-service/test/run-pytest.sh
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,11 @@ fi
rm ../../meta-data/test-modify-jobs.json

cp ../../meta-data/test-simple-jobs.json ../../meta-data/test-modify-jobs.json
# integration tests start up service
{ python3 ../web_service.py --config "../../meta-data/test-modify-jobs.json" --host 127.0.0.1 --html-dir "../../webcontent/" > /dev/null 2>&1 & }
# make client calls to web service with access control diabled
{ python3 ../web_service.py --config "../../meta-data/test-modify-jobs.json" --host 127.0.0.1 --html-dir "../../webcontent/" --disable-auth > /dev/null 2>&1 & }
WEB_SERVICE_PID=$!
# prevent tests running before service is up
sleep 3
sleep 1

# now test web service
pytest test_web_service.py
Expand All @@ -41,6 +41,28 @@ if [ "$DIFF_CNT" -lt 1 ]; then
exit 1
fi

# shutdown and cleanup
kill "$WEB_SERVICE_PID"
rm ../../meta-data/test-modify-jobs.json

cp ../../meta-data/test-simple-jobs.json ../../meta-data/test-modify-jobs.json
# test access control, all web calls should fail with 403
{ python3 ../web_service.py --config "../../meta-data/test-modify-jobs.json" --host 127.0.0.1 --html-dir "../../webcontent/" > /dev/null 2>&1 & }
WEB_SERVICE_PID=$!
# prevent tests running before service is up
sleep 1

# now test web service
pytest test_no_auth_api.py

sleep 1

DIFF_CNT=$(diff ../../meta-data/test-simple-jobs.json ../../meta-data/test-modify-jobs.json | grep "^>" | wc -l)
if [ "$DIFF_CNT" -ne 0 ]; then
echo "ERROR meta-data modified during auth check expected no changes"
exit 1
fi

# shutdown service clean up file
kill "$WEB_SERVICE_PID"
rm ../../meta-data/test-modify-jobs.json
Expand Down
41 changes: 41 additions & 0 deletions orchestration-service/test/test_no_auth_api.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
"""Module tests web API expecting 403 auth failure"""
import requests
import pytest
import re
import json

@pytest.fixture(scope="module")
def setup_module():
"""setting some constants to avoid mis-spellings"""
setup = {}
setup['base_url']='http://127.0.0.1:4000'

setup['plain_text_headers'] = {
'Accept': 'text/plain; charset=utf-8',
'Content-Type': 'text/plain; charset=utf-8',
}

setup['json_headers'] = {
'Accept': 'application/json',
'Content-Type': 'application/json; charset=utf-8',
}

setup['html_headers'] = {
'Accept': 'text/html, application/xhtml+xml',
'Content-Type': 'text/html; charset=utf-8',
}

return setup

def test_api_calls(setup_module):
"""Run through all API calls and make sure they fail with 403"""
cntx = setup_module

params = { 'nextjob': 1, 'sliceid': 3 }
api_calls = ['/job', '/status', '/config', '/summary', '/progress', '/grid', '/control', '/detail', '/logout']
for path in api_calls:
response = requests.get(cntx['base_url'] + '/job',
params=params,
timeout=3,
headers=cntx['json_headers'])
assert response.status_code == 403
Loading

0 comments on commit 2c49e59

Please sign in to comment.