Commit 6e7e3dc8 authored by dmitry.mashoshin's avatar dmitry.mashoshin Committed by Viacheslav Sukhovieiev
Browse files

Merge branch '10/slava/Add_warning_logs_if_auth_check_fails' into 'master'

feat: add warning log if ip has no access

See merge request !44
parents 18f3e7be 8e5b793c
......@@ -45,6 +45,8 @@ spec:
value: {{ .Values.domain }}
- name: SWAGGER_DOC
value: "{{.Values.swaggerDoc}}"
- name: AUTH_IP_BLOCK_STRICT
value: {{ .Values.authApiBlockStrict }}
ports:
- name: http
containerPort: 80
......
......@@ -38,4 +38,5 @@ affinity: {}
auction_url: http://auction-prozorro-sale.raccoongang.com
domain: localhost
swaggerDoc: '1'
\ No newline at end of file
swaggerDoc: '1'
authApiBlockStrict: '0'
\ No newline at end of file
from dataclasses import dataclass
from typing import List, Dict, Optional, Callable
import os
from aiohttp import web
import yaml
import ipaddress
from prozorro_sale import tools
from prozorro_sale.auth.encryption import hash_token
AUTH_IP_BLOCK_STRICT = os.environ.get('AUTH_IP_BLOCK_STRICT', '1').lower() not in ('false', '0', 'f')
LOG = tools.logging.get_custom_logger(__name__)
@dataclass
class BrokerInfo:
......@@ -118,8 +123,12 @@ def check_access(func: Callable) -> Callable:
async def handler(request: web.Request, *args, **kwargs) -> web.Response:
remote = request.headers.get('X-Forwarded-For', request.remote)
user = request._context.user
if not user or not user.has_access_by_ip(remote):
if not user:
return forbidden_response()
if not user.has_access_by_ip(remote):
LOG.warning(f"User {user.name} forbidden access by ip {remote}")
if AUTH_IP_BLOCK_STRICT:
return forbidden_response()
return await func(request, *args, **kwargs)
return handler
......
......@@ -13,6 +13,7 @@ from prozorro_sale.auth import errors, utils
LOG = tools.logging.get_custom_logger(__name__)
SWAGGER_DOC_AVAILABLE = os.getenv('SWAGGER_DOC', False)
AUTH_FILE = os.environ.get('AUTH_FILE', '/secrets/auth.yml')
AUTH_IP_BLOCK_STRICT = os.environ.get('AUTH_IP_BLOCK_STRICT', '1').lower() not in ('false', '0', 'f')
async def version(request):
......@@ -55,7 +56,9 @@ async def check_auth(request):
remote = request.headers.get('X-FORWARDED-FOR', '')
if user := request._context.user:
if not user.has_access_by_ip(remote):
return auth.forbidden_response()
LOG.warning(f"User {user.name} forbidden access by ip {remote}")
if AUTH_IP_BLOCK_STRICT:
return auth.forbidden_response()
return web.json_response({'owner': owner, 'ip': remote, 'procedures': procedures})
......
import pytest
from prozorro_sale.auth import User
import ipaddress
from unittest import mock
@pytest.mark.usefixtures('create_auth_token', 'build_redirect_url', 'get_token')
......@@ -15,3 +18,36 @@ class TestApi:
resp = await client.get('api/auth/auction?token=token', allow_redirects=False)
assert resp.status == 303
assert resp.cookies.get('auth_token-TIE001-UA-20200915-16563').value == 'auth-token'
@pytest.mark.parametrize("_ip, auth_block, status", [
pytest.param(
'0.255.255.255',
True,
403,
id='non included ip with auth ip blocked'
),
pytest.param(
'0.255.255.255',
False,
200,
id='non included ip with no blocked auth ip'
),
pytest.param(
'0.0.0.0',
True,
200,
id='include ip with auth ip blocked'
),
pytest.param(
'0.0.0.0',
False,
200,
id='include ip with auth no blocked auth ip'
),
])
async def test_check_auth(self, client, _ip, auth_block, status):
User.ips = [ipaddress.ip_network(v) for v in ['255.255.255.255', '0.0.0.0/24']]
with mock.patch('prozorro_sale.auth.AUTH_IP_BLOCK_STRICT', return_value=auth_block):
resp = await client.get('api/auth', headers={"Authorization": "test_broker_1_token",
"X-FORWARDED-FOR": _ip})
assert resp.status == status
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment