Skip to content

Commit

Permalink
fix code style
Browse files Browse the repository at this point in the history
  • Loading branch information
ogolovatyi authored and ogolovatyi committed Feb 20, 2019
1 parent add48be commit 696dd6c
Show file tree
Hide file tree
Showing 3 changed files with 91 additions and 60 deletions.
19 changes: 19 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,3 +88,22 @@ Access-Control-Allow-Methods = GET, OPTIONS, POST
- Open `misc/TabPy.yml` in Swagger editor.
- In case your TabPy server runs not on `localhost:9004` update
`host` value in `TabPy.yml` accordingly.

## Code styling

On github repo for merge request `pycodestyle` is used to check Python code against our
style conventions. You can run install it and run locally for file where modifications
were made:

```sh
pip install pycodestyle
pycodestyle <file.py>
```

For reported errors and warnings either fix them manually or auto-format files with
`autopep8`:

```sh
pip install autopep8
autopep8 -i <file.py>
```
99 changes: 52 additions & 47 deletions tabpy-server/server_tests/test_validate_credentials.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,46 +7,50 @@
from argparse import Namespace
from tempfile import NamedTemporaryFile

from tabpy_server.handlers.util import(validate_basic_auth_credentials,
handle_authentication, check_and_validate_basic_auth_credentials)
from tabpy_server.handlers.util import (
validate_basic_auth_credentials,
handle_authentication,
check_and_validate_basic_auth_credentials)

from unittest.mock import patch, call


class TestValidateBasicAuthCredentials(unittest.TestCase):
def setUp(self):
self.credentials = {
# SHA3('password')
'user1': 'c0067d4af4e87f00dbac63b6156828237059172d1bbeac67427345d6a9fda484'
'user1':
'c0067d4af4e87f00dbac63b6156828237059172d1bbeac67427345d6a9fda484'
}


def test_given_unknown_username_expect_validation_fails(self):
self.assertFalse(validate_basic_auth_credentials('user2', 'pwd@2', self.credentials))

def test_given_unknown_username_expect_validation_fails(self):
self.assertFalse(validate_basic_auth_credentials(
'user2', 'pwd@2', self.credentials))

def test_given_wrong_password_expect_validation_fails(self):
self.assertFalse(validate_basic_auth_credentials('user1', 'password#1', self.credentials))

self.assertFalse(validate_basic_auth_credentials(
'user1', 'password#1', self.credentials))

def test_given_valid_creds_expect_validation_passes(self):
self.assertTrue(validate_basic_auth_credentials('user1', 'password', self.credentials))

self.assertTrue(validate_basic_auth_credentials(
'user1', 'password', self.credentials))

def test_given_valid_creds_uppercase_username_expect_validation_passes(self):
self.assertTrue(validate_basic_auth_credentials('UsEr1', 'password', self.credentials))
def test_given_valid_creds_mixcase_login_expect_validation_passes(self):
self.assertTrue(validate_basic_auth_credentials(
'UsEr1', 'password', self.credentials))


class TestCheckAndValidateBasicAuthCredentials(unittest.TestCase):
def setUp(self):
self.credentials = {
# SHA3('password')
'user1': 'c0067d4af4e87f00dbac63b6156828237059172d1bbeac67427345d6a9fda484'
'user1':
'c0067d4af4e87f00dbac63b6156828237059172d1bbeac67427345d6a9fda484'
}


def test_given_no_headers_expect_validation_fails(self):
self.assertFalse(check_and_validate_basic_auth_credentials({}, self.credentials))

self.assertFalse(
check_and_validate_basic_auth_credentials({}, self.credentials))

def test_given_bad_auth_header_expect_validation_fails(self):
self.assertFalse(check_and_validate_basic_auth_credentials(
Expand All @@ -60,30 +64,31 @@ def test_given_bad_encoded_credentials_expect_validation_fails(self):
'Authorization': 'Basic abc'
}, self.credentials))


def test_given_malformed_credentials_expect_validation_fails(self):
self.assertFalse(check_and_validate_basic_auth_credentials(
{
'Authorization': 'Basic {}'.format(base64.b64encode('user1-password'.encode('utf-8')).decode('utf-8'))
'Authorization': 'Basic {}'.format(
base64.b64encode('user1-password'.encode('utf-8')).
decode('utf-8'))
}, self.credentials))


def test_given_unknown_username_expect_validation_fails(self):
self.assertFalse(check_and_validate_basic_auth_credentials(
{
'Authorization': 'Basic {}'.format(base64.b64encode('unknown_user:password'.encode('utf-8')))
'Authorization': 'Basic {}'.format(
base64.b64encode('unknown_user:password'.encode('utf-8')))
}, self.credentials))


def test_given_wrong_pwd_expect_validation_fails(self):
self.assertFalse(check_and_validate_basic_auth_credentials(
{
'Authorization': 'Basic {}'.format(base64.b64encode('user1:p@ssw0rd'.encode('utf-8')))
'Authorization': 'Basic {}'.format(
base64.b64encode('user1:p@ssw0rd'.encode('utf-8')))
}, self.credentials))


def test_given_valid_creds_expect_validation_passes(self):
b64_username_pwd = base64.b64encode('user1:password'.encode('utf-8')).decode('utf-8')
b64_username_pwd = base64.b64encode(
'user1:password'.encode('utf-8')).decode('utf-8')
self.assertTrue(check_and_validate_basic_auth_credentials(
{
'Authorization': 'Basic {}'.format(b64_username_pwd)
Expand All @@ -94,17 +99,18 @@ class TestHandleAuthentication(unittest.TestCase):
def setUp(self):
self.credentials = {
# SHA3('password')
'user1': 'c0067d4af4e87f00dbac63b6156828237059172d1bbeac67427345d6a9fda484'
'user1':
'c0067d4af4e87f00dbac63b6156828237059172d1bbeac67427345d6a9fda484'
}

self.settings = {
'versions':
'versions':
{
'v0.1a':
{
'features': {}
},
'v0.2beta':
'v0.2beta':
{
'features':
{
Expand All @@ -114,7 +120,7 @@ def setUp(self):
}
}
},
'v0.3gamma':
'v0.3gamma':
{
'features':
{
Expand All @@ -129,7 +135,7 @@ def setUp(self):
}
},
'v0.4yota': {},
'v1':
'v1':
{
'features':
{
Expand All @@ -146,42 +152,41 @@ def setUp(self):
}
}


def test_given_no_api_version_expect_failure(self):
self.assertFalse(handle_authentication({}, '', self.settings, self.credentials))
self.assertFalse(handle_authentication(
{}, '', self.settings, self.credentials))


def test_given_unknown_api_version_expect_failure(self):
self.assertFalse(handle_authentication({}, 'v0.314p', self.settings, self.credentials))
self.assertFalse(handle_authentication(
{}, 'v0.314p', self.settings, self.credentials))


def test_given_auth_is_not_configured_expect_success(self):
self.assertTrue(handle_authentication({}, 'v0.1a', self.settings, self.credentials))

self.assertTrue(handle_authentication(
{}, 'v0.1a', self.settings, self.credentials))

def test_given_auth_method_not_provided_expect_failure(self):
self.assertFalse(handle_authentication({}, 'v0.2beta', self.settings, self.credentials))

self.assertFalse(handle_authentication(
{}, 'v0.2beta', self.settings, self.credentials))

def test_given_auth_method_is_unknown_expect_failure(self):
self.assertFalse(handle_authentication({}, 'v0.3gamma', self.settings, self.credentials))

self.assertFalse(handle_authentication(
{}, 'v0.3gamma', self.settings, self.credentials))

def test_given_features_not_configured_expect_success(self):
self.assertTrue(handle_authentication({}, 'v0.4yota', self.settings, self.credentials))

self.assertTrue(handle_authentication(
{}, 'v0.4yota', self.settings, self.credentials))

def test_given_headers_not_provided_expect_failure(self):
self.assertFalse(handle_authentication({}, 'v1', self.settings, self.credentials))
self.assertFalse(handle_authentication(
{}, 'v1', self.settings, self.credentials))


def test_given_valid_creds_expect_success(self):
b64_username_pwd = base64.b64encode('user1:password'.encode('utf-8')).decode('utf-8')
b64_username_pwd = base64.b64encode(
'user1:password'.encode('utf-8')).decode('utf-8')
self.assertTrue(handle_authentication(
{
'Authorization': 'Basic {}'.format(b64_username_pwd)
},
'v1',
self.settings,
self.credentials))

33 changes: 20 additions & 13 deletions tabpy-server/tabpy_server/handlers/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@

logger = logging.getLogger(__name__)


def validate_basic_auth_credentials(username, pwd, credentials):
'''
Validates username:pwd if they are the same as
Validates username:pwd if they are the same as
stored credentials.
Parameters
Expand All @@ -17,7 +18,7 @@ def validate_basic_auth_credentials(username, pwd, credentials):
pwd : str
Password in plain text. The function will hash
the password with SHA3 to compare with hashed
the password with SHA3 to compare with hashed
passwords in stored credentials.
credentials: dict
Expand All @@ -27,7 +28,7 @@ def validate_basic_auth_credentials(username, pwd, credentials):
Returns
-------
bool
True if credentials has key login and
True if credentials has key login and
credentials[login] equal SHA3(pwd), False
otherwise.
'''
Expand All @@ -41,13 +42,13 @@ def validate_basic_auth_credentials(username, pwd, credentials):
if credentials[login].lower() != hashed_pwd.lower():
logger.error('Wrong password for user name "{}"'.format(username))
return False

return True


def check_and_validate_basic_auth_credentials(headers, credentials):
'''
Checks if credentials are provided in headers and
Checks if credentials are provided in headers and
if they are valid.
Parameters
Expand All @@ -73,7 +74,7 @@ def check_and_validate_basic_auth_credentials(headers, credentials):
auth_header = headers['Authorization']
auth_header_list = headers['Authorization'].split(' ')
if len(auth_header_list) != 2 or\
auth_header_list[0] != 'Basic':
auth_header_list[0] != 'Basic':
logger.error('Uknown authentication method "{}"'.format(auth_header))
return False

Expand All @@ -88,7 +89,9 @@ def check_and_validate_basic_auth_credentials(headers, credentials):
logger.error('Invalid string in encoded credentials')
return False

return validate_basic_auth_credentials(login_pwd[0], login_pwd[1], credentials)
return validate_basic_auth_credentials(login_pwd[0],
login_pwd[1],
credentials)


def handle_authentication(headers, api_version, settings, credentials):
Expand Down Expand Up @@ -117,7 +120,7 @@ def handle_authentication(headers, api_version, settings, credentials):
If for the specified API version authentication is
not turned on returns True.
Otherwise checks what authentication type is used
and if it is supported type validates provided
and if it is supported type validates provided
credentials.
If authentication type is supported and credentials
are valid returns True, otherwise False.
Expand All @@ -134,14 +137,18 @@ def handle_authentication(headers, api_version, settings, credentials):

features = version_settings['features']
if 'authentication' not in features or\
features['authentication']['required'] != True:
logger.info('Authentication is not a required feature for API {}'.format(api_version))
not features['authentication']['required']:
logger.info(
'Authentication is not a required feature for API '
'{}'.format(api_version))
return True

auth_feature = features['authentication']
if 'methods' not in auth_feature or\
'basic-auth' not in auth_feature['methods']:
logger.critical('Basic authentication access method is not configured for API {}'.format(api_version))
'basic-auth' not in auth_feature['methods']:
logger.critical(
'Basic authentication access method is not configured '
'for API {}'.format(api_version))
return False

return check_and_validate_basic_auth_credentials(headers, credentials)
return check_and_validate_basic_auth_credentials(headers, credentials)

0 comments on commit 696dd6c

Please sign in to comment.