Browse Source

Refactor: Appease the pylint rules for the repository

merge-requests/1/head
Drew Short 5 years ago
parent
commit
08165c1f5a
  1. 33
      server/corvus/api/authentication_api.py
  2. 7
      server/corvus/api/health_api.py
  3. 15
      server/corvus/api/user_api.py
  4. 2
      server/corvus/errors.py
  5. 9
      server/corvus/middleware/authentication_middleware.py
  6. 2
      server/corvus/service/role_service.py
  7. 15
      server/corvus/service/user_token_service.py
  8. 1
      server/mypy.ini
  9. 30
      server/run_tests.bat
  10. 30
      server/run_tests.sh

33
server/corvus/api/authentication_api.py

@ -21,7 +21,8 @@ AUTH_BLUEPRINT = Blueprint(
@AUTH_BLUEPRINT.route('/login', methods=['POST']) @AUTH_BLUEPRINT.route('/login', methods=['POST'])
@return_json @return_json
@authentication_middleware.require(required_auth=Auth.BASIC, required_role=Role.USER)
@authentication_middleware.require(
required_auth=Auth.BASIC, required_role=Role.USER)
def login() -> APIResponse: def login() -> APIResponse:
""" """
Get a token for continued authentication. Get a token for continued authentication.
@ -34,7 +35,8 @@ def login() -> APIResponse:
@AUTH_BLUEPRINT.route('/bump', methods=['POST']) @AUTH_BLUEPRINT.route('/bump', methods=['POST'])
@return_json @return_json
@authentication_middleware.require(required_auth=Auth.BASIC, required_role=Role.USER)
@authentication_middleware.require(
required_auth=Auth.BASIC, required_role=Role.USER)
def login_bump() -> APIResponse: def login_bump() -> APIResponse:
""" """
Update the user last seen timestamp. Update the user last seen timestamp.
@ -47,7 +49,8 @@ def login_bump() -> APIResponse:
@AUTH_BLUEPRINT.route('/logout', methods=['POST']) @AUTH_BLUEPRINT.route('/logout', methods=['POST'])
@return_json @return_json
@authentication_middleware.require(required_auth=Auth.BASIC, required_role=Role.USER)
@authentication_middleware.require(
required_auth=Auth.BASIC, required_role=Role.USER)
def logout() -> APIResponse: def logout() -> APIResponse:
""" """
Logout and delete a token. Logout and delete a token.
@ -60,10 +63,11 @@ def logout() -> APIResponse:
@AUTH_BLUEPRINT.route('/token', methods=['GET']) @AUTH_BLUEPRINT.route('/token', methods=['GET'])
@return_json @return_json
@authentication_middleware.require(required_auth=Auth.BASIC, required_role=Role.USER)
@authentication_middleware.require(
required_auth=Auth.BASIC, required_role=Role.USER)
def get_tokens() -> APIResponse: def get_tokens() -> APIResponse:
""" """
Get a list of all tokens for the current user
Get a list of all tokens for the current user.
:return: a paginated list of user tokens :return: a paginated list of user tokens
""" """
@ -76,10 +80,12 @@ def get_tokens() -> APIResponse:
@AUTH_BLUEPRINT.route('/token', methods=['POST']) @AUTH_BLUEPRINT.route('/token', methods=['POST'])
@return_json @return_json
@authentication_middleware.require(required_auth=Auth.BASIC, required_role=Role.USER)
@authentication_middleware.require(
required_auth=Auth.BASIC, required_role=Role.USER)
def create_token(): def create_token():
""" """
Create a new token with optional parameters
Create a new token with optional parameters.
note: String note: String
enabled: Boolean enabled: Boolean
expirationTime: DateTime expirationTime: DateTime
@ -89,16 +95,18 @@ def create_token():
requested_token: UserToken = transformation_service.deserialize_model( requested_token: UserToken = transformation_service.deserialize_model(
UserToken, request.json, options=['note', 'enabled', 'expirationTime']) UserToken, request.json, options=['note', 'enabled', 'expirationTime'])
user_token = user_token_service.create( user_token = user_token_service.create(
g.user, requested_token.note, requested_token.enabled, requested_token.expiration_time)
g.user, requested_token.note,
requested_token.enabled, requested_token.expiration_time)
return APIResponse(user_token, 200) return APIResponse(user_token, 200)
@AUTH_BLUEPRINT.route('/token/<token>', methods=['GET']) @AUTH_BLUEPRINT.route('/token/<token>', methods=['GET'])
@return_json @return_json
@authentication_middleware.require(required_auth=Auth.BASIC, required_role=Role.USER)
@authentication_middleware.require(
required_auth=Auth.BASIC, required_role=Role.USER)
def get_token(token: str): def get_token(token: str):
""" """
Retrieve a specific token for this user
Retrieve a specific token for this user.
:param token: The token to retrieve for this user :param token: The token to retrieve for this user
:return: The token if it exists :return: The token if it exists
@ -111,10 +119,11 @@ def get_token(token: str):
@AUTH_BLUEPRINT.route('/token/<token>', methods=['DELETE']) @AUTH_BLUEPRINT.route('/token/<token>', methods=['DELETE'])
@return_json @return_json
@authentication_middleware.require(required_auth=Auth.BASIC, required_role=Role.USER)
@authentication_middleware.require(
required_auth=Auth.BASIC, required_role=Role.USER)
def delete_token(token: str): def delete_token(token: str):
""" """
Delete a specific token for this user
Delete a specific token for this user.
:param token: The token to delete for this user :param token: The token to delete for this user
:return: Nothing on success :return: Nothing on success

7
server/corvus/api/health_api.py

@ -1,4 +1,4 @@
"""Endpoint to expose the health of the application"""
"""Endpoint to expose the health of the application."""
from flask import Blueprint from flask import Blueprint
from corvus.api.decorators import return_json from corvus.api.decorators import return_json
@ -11,6 +11,11 @@ HEALTH_BLUEPRINT = Blueprint(
@HEALTH_BLUEPRINT.route('', methods=['GET']) @HEALTH_BLUEPRINT.route('', methods=['GET'])
@return_json @return_json
def get_health() -> APIResponse: def get_health() -> APIResponse:
"""
Retrieve the health for the service.
:return:
"""
return APIResponse( return APIResponse(
APIMessage(True, 'Service is healthy'), APIMessage(True, 'Service is healthy'),
200 200

15
server/corvus/api/user_api.py

@ -22,7 +22,8 @@ USER_BLUEPRINT = Blueprint(
@USER_BLUEPRINT.route('', methods=['GET']) @USER_BLUEPRINT.route('', methods=['GET'])
@return_json @return_json
@authentication_middleware.require(required_auth=Auth.TOKEN, required_role=Role.USER)
@authentication_middleware.require(
required_auth=Auth.TOKEN, required_role=Role.USER)
def get_users() -> APIResponse: def get_users() -> APIResponse:
""" """
Get a list of users. Get a list of users.
@ -38,7 +39,8 @@ def get_users() -> APIResponse:
@USER_BLUEPRINT.route('/<name>', methods=['GET']) @USER_BLUEPRINT.route('/<name>', methods=['GET'])
@return_json @return_json
@authentication_middleware.require(required_auth=Auth.TOKEN, required_role=Role.USER)
@authentication_middleware.require(
required_auth=Auth.TOKEN, required_role=Role.USER)
def get_user(name: str) -> APIResponse: def get_user(name: str) -> APIResponse:
""" """
Get a user. Get a user.
@ -53,7 +55,8 @@ def get_user(name: str) -> APIResponse:
@USER_BLUEPRINT.route('/<name>', methods=['PATCH']) @USER_BLUEPRINT.route('/<name>', methods=['PATCH'])
@return_json @return_json
@authentication_middleware.require(required_auth=Auth.TOKEN, required_role=Role.USER)
@authentication_middleware.require(
required_auth=Auth.TOKEN, required_role=Role.USER)
def patch_user(name: str) -> APIResponse: def patch_user(name: str) -> APIResponse:
""" """
Patch a user. Patch a user.
@ -72,7 +75,8 @@ def patch_user(name: str) -> APIResponse:
@USER_BLUEPRINT.route('', methods=['POST']) @USER_BLUEPRINT.route('', methods=['POST'])
@return_json @return_json
@authentication_middleware.require(required_auth=Auth.TOKEN, required_role=Role.ADMIN)
@authentication_middleware.require(
required_auth=Auth.TOKEN, required_role=Role.ADMIN)
def register_user() -> APIResponse: def register_user() -> APIResponse:
""" """
Register a user with the service. Register a user with the service.
@ -96,7 +100,8 @@ def register_user() -> APIResponse:
@USER_BLUEPRINT.route('/<name>', methods=['DELETE']) @USER_BLUEPRINT.route('/<name>', methods=['DELETE'])
@return_json @return_json
@authentication_middleware.require(required_auth=Auth.TOKEN, required_role=Role.ADMIN)
@authentication_middleware.require(
required_auth=Auth.TOKEN, required_role=Role.ADMIN)
def delete_user(name: str) -> APIResponse: def delete_user(name: str) -> APIResponse:
""" """
Delete a user with the service. Delete a user with the service.

2
server/corvus/errors.py

@ -43,8 +43,6 @@ class ClientError(BaseError):
class ValidationError(ClientError): class ValidationError(ClientError):
"""Corvus Validation Error.""" """Corvus Validation Error."""
pass
@return_json @return_json
def handle_corvus_404_error(exception: HTTPException) -> APIResponse: def handle_corvus_404_error(exception: HTTPException) -> APIResponse:

9
server/corvus/middleware/authentication_middleware.py

@ -103,7 +103,6 @@ def parse_token_header(
return None return None
return Authorization('token', {'username': bytes_to_wsgi(username), return Authorization('token', {'username': bytes_to_wsgi(username),
'password': bytes_to_wsgi(token)}) 'password': bytes_to_wsgi(token)})
return None
def require_basic_auth(func: Callable) -> Callable: def require_basic_auth(func: Callable) -> Callable:
@ -185,11 +184,11 @@ def require(required_auth: Auth, required_role: Role) -> Callable:
def require_decorator(func: Callable) -> Callable: def require_decorator(func: Callable) -> Callable:
@wraps(func) @wraps(func)
def decorate(*args: list, **kwargs: dict) -> Any: def decorate(*args: list, **kwargs: dict) -> Any:
f = require_role(required_role)(func)
decorated = require_role(required_role)(func)
if required_auth == Auth.BASIC: if required_auth == Auth.BASIC:
f = require_basic_auth(f)
decorated = require_basic_auth(decorated)
elif required_auth == Auth.TOKEN: elif required_auth == Auth.TOKEN:
f = require_token_auth(f)
decorated = require_token_auth(decorated)
else: else:
Response( Response(
response=APIMessage( response=APIMessage(
@ -197,6 +196,6 @@ def require(required_auth: Auth, required_role: Role) -> Callable:
success=False success=False
), ),
status=500) status=500)
return f(*args, **kwargs)
return decorated(*args, **kwargs)
return decorate return decorate
return require_decorator return require_decorator

2
server/corvus/service/role_service.py

@ -56,7 +56,7 @@ class RoleTree(defaultdict):
def find_role(self, request_role: Role) -> List['RoleTree']: def find_role(self, request_role: Role) -> List['RoleTree']:
"""Identify all instances of a role.""" """Identify all instances of a role."""
try: try:
return [role_tree for role_tree in self.roles[request_role]]
return self.roles[request_role]
except KeyError: except KeyError:
return [] return []

15
server/corvus/service/user_token_service.py

@ -1,7 +1,7 @@
"""Service to handle user_token operations.""" """Service to handle user_token operations."""
import uuid import uuid
from datetime import datetime from datetime import datetime
from typing import Optional, Dict, Callable, Any, List
from typing import Optional, Dict, Callable, Any
from flask_sqlalchemy import Pagination from flask_sqlalchemy import Pagination
from iso8601 import iso8601, ParseError from iso8601 import iso8601, ParseError
@ -85,7 +85,8 @@ class UserTokenTransformer(BaseTransformer):
try: try:
model.expiration_time = iso8601.parse_date(expiration_time) model.expiration_time = iso8601.parse_date(expiration_time)
except ParseError: except ParseError:
raise errors.ValidationError('Cannot parse datetime from %s' % expiration_time)
raise errors.ValidationError(
'Cannot parse datetime from %s' % expiration_time)
def serialize_creation_time(self) -> datetime: def serialize_creation_time(self) -> datetime:
"""User token creation time.""" """User token creation time."""
@ -98,7 +99,8 @@ class UserTokenTransformer(BaseTransformer):
try: try:
model.creation_time = iso8601.parse_date(creation_time) model.creation_time = iso8601.parse_date(creation_time)
except ParseError: except ParseError:
raise errors.ValidationError('Cannot parse datetime from %s' % creation_time)
raise errors.ValidationError(
'Cannot parse datetime from %s' % creation_time)
def serialize_last_usage_time(self) -> datetime: def serialize_last_usage_time(self) -> datetime:
"""User token last usage time.""" """User token last usage time."""
@ -111,6 +113,7 @@ class UserTokenTransformer(BaseTransformer):
model.last_usage_time = iso8601.parse_date(last_usage_time) model.last_usage_time = iso8601.parse_date(last_usage_time)
def serialize_is_valid(self): def serialize_is_valid(self):
"""User token is_valid computed value."""
return is_valid_token(self.model) return is_valid_token(self.model)
def serialize_version(self) -> int: def serialize_version(self) -> int:
@ -211,7 +214,8 @@ def find_by_user_and_token(user: User, token: str) -> Optional[UserToken]:
return UserToken.query.filter_by(user_id=user.id, token=token).first() return UserToken.query.filter_by(user_id=user.id, token=token).first()
def find_by_user(user: User, page: int, per_page: int = 20, max_per_page: int = 100) -> Pagination:
def find_by_user(user: User, page: int, per_page: int = 20,
max_per_page: int = 100) -> Pagination:
""" """
Find all tokens for a user Find all tokens for a user
@ -221,4 +225,5 @@ def find_by_user(user: User, page: int, per_page: int = 20, max_per_page: int =
:param max_per_page: :param max_per_page:
:return: :return:
""" """
return UserToken.query.filter_by(user_id=user.id).paginate(page, per_page, True, max_per_page)
return UserToken.query.filter_by(
user_id=user.id).paginate(page, per_page, True, max_per_page)

1
server/mypy.ini

@ -8,4 +8,3 @@ disallow_subclassing_any = False
warn_redundant_casts = True warn_redundant_casts = True
warn_unused_ignores = True warn_unused_ignores = True
strict_optional = True strict_optional = True
strict_boolean = False

30
server/run_tests.bat

@ -0,0 +1,30 @@
SET PIPENV_VERBOSITY=-1
SET PYTHONPATH=%cd%
pipenv run python3 --version
pipenv run python3 -m pip --version
pipenv run pylint --version
pipenv run mypy --version
pipenv run coverage --version
pipenv run pytest --version
pipenv run pycodestyle --version
pipenv run pydocstyle --version
pipenv run pylint corvus
if %errorlevel% neq 0 exit /b %errorlevel%
pipenv run mypy corvus tests
if %errorlevel% neq 0 exit /b %errorlevel%
pipenv run coverage run --source corvus -m pytest
if %errorlevel% neq 0 exit /b %errorlevel%
pipenv run coverage report --fail-under=85 -m --skip-covered
if %errorlevel% neq 0 exit /b %errorlevel%
pipenv run pycodestyle corvus tests
if %errorlevel% neq 0 exit /b %errorlevel%
pipenv run pydocstyle corvus
if %errorlevel% neq 0 exit /b %errorlevel%

30
server/run_tests.sh

@ -3,20 +3,22 @@
set -e set -e
set -x set -x
# shellcheck disable=SC2034
PIPENV_VERBOSITY=-1
python3 --version
python3 -m pip --version
pipenv run python3 --version
pipenv run python3 -m pip --version
pylint --version
mypy --version
coverage --version
pytest --version
pycodestyle --version
pydocstyle --version
pipenv run pylint --version
pipenv run mypy --version
pipenv run coverage --version
pipenv run pytest --version
pipenv run pycodestyle --version
pipenv run pydocstyle --version
pylint corvus
mypy corvus tests
PYTHONPATH=$(pwd) coverage run --source corvus -m pytest
coverage report --fail-under=85 -m --skip-covered
pycodestyle corvus tests
pydocstyle corvus
pipenv run pylint corvus
pipenv run mypy corvus tests
PYTHONPATH=$(pwd) pipenv run coverage run --source corvus -m pytest
pipenv run coverage report --fail-under=85 -m --skip-covered
pipenv run pycodestyle corvus tests
pipenv run pydocstyle corvus
Loading…
Cancel
Save