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'])
@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:
"""
Get a token for continued authentication.
@ -34,7 +35,8 @@ def login() -> APIResponse:
@AUTH_BLUEPRINT.route('/bump', methods=['POST'])
@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:
"""
Update the user last seen timestamp.
@ -47,7 +49,8 @@ def login_bump() -> APIResponse:
@AUTH_BLUEPRINT.route('/logout', methods=['POST'])
@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:
"""
Logout and delete a token.
@ -60,10 +63,11 @@ def logout() -> APIResponse:
@AUTH_BLUEPRINT.route('/token', methods=['GET'])
@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:
"""
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
"""
@ -76,10 +80,12 @@ def get_tokens() -> APIResponse:
@AUTH_BLUEPRINT.route('/token', methods=['POST'])
@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():
"""
Create a new token with optional parameters
Create a new token with optional parameters.
note: String
enabled: Boolean
expirationTime: DateTime
@ -89,16 +95,18 @@ def create_token():
requested_token: UserToken = transformation_service.deserialize_model(
UserToken, request.json, options=['note', 'enabled', 'expirationTime'])
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)
@AUTH_BLUEPRINT.route('/token/<token>', methods=['GET'])
@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):
"""
Retrieve a specific token for this user
Retrieve a specific token for this user.
:param token: The token to retrieve for this user
:return: The token if it exists
@ -111,10 +119,11 @@ def get_token(token: str):
@AUTH_BLUEPRINT.route('/token/<token>', methods=['DELETE'])
@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):
"""
Delete a specific token for this user
Delete a specific token for this user.
:param token: The token to delete for this user
: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 corvus.api.decorators import return_json
@ -11,6 +11,11 @@ HEALTH_BLUEPRINT = Blueprint(
@HEALTH_BLUEPRINT.route('', methods=['GET'])
@return_json
def get_health() -> APIResponse:
"""
Retrieve the health for the service.
:return:
"""
return APIResponse(
APIMessage(True, 'Service is healthy'),
200

15
server/corvus/api/user_api.py

@ -22,7 +22,8 @@ USER_BLUEPRINT = Blueprint(
@USER_BLUEPRINT.route('', methods=['GET'])
@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:
"""
Get a list of users.
@ -38,7 +39,8 @@ def get_users() -> APIResponse:
@USER_BLUEPRINT.route('/<name>', methods=['GET'])
@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:
"""
Get a user.
@ -53,7 +55,8 @@ def get_user(name: str) -> APIResponse:
@USER_BLUEPRINT.route('/<name>', methods=['PATCH'])
@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:
"""
Patch a user.
@ -72,7 +75,8 @@ def patch_user(name: str) -> APIResponse:
@USER_BLUEPRINT.route('', methods=['POST'])
@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:
"""
Register a user with the service.
@ -96,7 +100,8 @@ def register_user() -> APIResponse:
@USER_BLUEPRINT.route('/<name>', methods=['DELETE'])
@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:
"""
Delete a user with the service.

2
server/corvus/errors.py

@ -43,8 +43,6 @@ class ClientError(BaseError):
class ValidationError(ClientError):
"""Corvus Validation Error."""
pass
@return_json
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 Authorization('token', {'username': bytes_to_wsgi(username),
'password': bytes_to_wsgi(token)})
return None
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:
@wraps(func)
def decorate(*args: list, **kwargs: dict) -> Any:
f = require_role(required_role)(func)
decorated = require_role(required_role)(func)
if required_auth == Auth.BASIC:
f = require_basic_auth(f)
decorated = require_basic_auth(decorated)
elif required_auth == Auth.TOKEN:
f = require_token_auth(f)
decorated = require_token_auth(decorated)
else:
Response(
response=APIMessage(
@ -197,6 +196,6 @@ def require(required_auth: Auth, required_role: Role) -> Callable:
success=False
),
status=500)
return f(*args, **kwargs)
return decorated(*args, **kwargs)
return decorate
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']:
"""Identify all instances of a role."""
try:
return [role_tree for role_tree in self.roles[request_role]]
return self.roles[request_role]
except KeyError:
return []

15
server/corvus/service/user_token_service.py

@ -1,7 +1,7 @@
"""Service to handle user_token operations."""
import uuid
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 iso8601 import iso8601, ParseError
@ -85,7 +85,8 @@ class UserTokenTransformer(BaseTransformer):
try:
model.expiration_time = iso8601.parse_date(expiration_time)
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:
"""User token creation time."""
@ -98,7 +99,8 @@ class UserTokenTransformer(BaseTransformer):
try:
model.creation_time = iso8601.parse_date(creation_time)
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:
"""User token last usage time."""
@ -111,6 +113,7 @@ class UserTokenTransformer(BaseTransformer):
model.last_usage_time = iso8601.parse_date(last_usage_time)
def serialize_is_valid(self):
"""User token is_valid computed value."""
return is_valid_token(self.model)
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()
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
@ -221,4 +225,5 @@ def find_by_user(user: User, page: int, per_page: int = 20, max_per_page: int =
:param max_per_page:
: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_unused_ignores = 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 -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