Compare commits

..

2 Commits

Author SHA1 Message Date
eb287050dc
ci: add docker build
All checks were successful
continuous-integration/drone/push Build is passing
ci: update docker registry

ci: update creds

ci: update repo

ci: (fix) repo
2021-11-04 11:51:09 +03:00
63c4922f08
add: docker and test files 2021-10-27 10:06:23 +03:00
12 changed files with 23 additions and 112 deletions

16
.drone.yml Normal file
View File

@ -0,0 +1,16 @@
kind: pipeline
name: default
steps:
- name: docker
image: plugins/docker
environment:
DOCKER_BUILDKIT: 1
settings:
username:
from_secret: docker_username
password:
from_secret: docker_password
repo: docker.grassecon.net/cic-auth-helper-gitea
registry: docker.grassecon.net
tags: latest

View File

@ -1,7 +0,0 @@
set -a
CICTEST_PGP_TRUSTED_PUBLICKEY_FINGERPRINT=CCE2E1D2D0E36ADE0405E2D0995BB21816313BD5
CICTEST_PGP_IMPORT_DIR=tests/testdata/pgp/dev
CICTEST_HTTP_HOBA_CIPHER_ID=969
CICTEST_HTTP_AUTH_ORIGIN=http://127.0.0.1:5000
CICTEST_HTTP_CORS_ORIGIN=http://localhost:4200
set +a

View File

@ -1,6 +0,0 @@
- 0.0.2
* Optional reverse proxy
* Header merge with reverse proxy, with option to selectively exclude which headers get overwritten
- 0.0.1
* Implement HOBA PGP and bearer token issuance
* Return 200 OK and bearer token on successful authentication

View File

@ -1 +0,0 @@
0.2.0

View File

@ -1,5 +1,4 @@
[http]
auth_origin =
cors_origin =
auth_realm = "ge"
hoba_cipher_id = 00

View File

@ -1,61 +0,0 @@
# standard imports
import re
import urllib.request
import os
import logging
logg = logging.getLogger(__name__)
re_x = r'^HTTP_(X_.+)$'
def add_x_headers(env, header_f):
for x in env:
m = re.match(re_x, x)
if m != None:
header_orig = m[1].replace('_', '-')
header_f(header_orig, env[x])
class ReverseProxy:
def __init__(self, base_url, ignore_proxy_headers=[]):
self.base_url = base_url
if not isinstance(ignore_proxy_headers, list):
raise ValueError('ignore_proxy_headers parameter must be a list of header keys')
self.ignore_proxy_headers = []
for h in ignore_proxy_headers:
self.ignore_proxy_headers.append(h.lower())
def proxy_pass(self, env, headers=[]):
url = os.path.join(self.base_url, env['REQUEST_URI'][1:])
logg.debug('access ok -> {}'.format(url))
req = urllib.request.Request(url, method=env['REQUEST_METHOD'])
add_x_headers(env, req.add_header)
req.add_header('Content-Type', env.get('CONTENT_TYPE', 'application/octet-stream'))
req.data = env.get('wsgi.input')
res = urllib.request.urlopen(req)
logg.debug('headers before reverse proxy {}'.format(headers))
header_keys = {}
for i, pair in enumerate(headers):
header_keys[pair[0].lower()] = i
for h in res.getheaders():
k = h[0].lower()
if k in self.ignore_proxy_headers:
continue
try:
i = header_keys[k]
headers[i] = h
except KeyError:
headers.append(h)
logg.debug('headers after reverse proxy {}'.format(headers))
status = '{} {}'.format(res.status, res.reason)
content = res.read()
return (status, headers, content)

View File

@ -5,12 +5,13 @@ import datetime
import base64
import sys
import argparse
import urllib.parse
# external imports
from http_hoba_auth import hoba_auth_request_string
from http_token_auth import SessionStore
import confini
# local imports
from usumbufu.challenge import Challenger
#from usumbufu.filter.sha256 import SHA256Filter
from usumbufu.filter.hoba import HobaFilter
@ -31,9 +32,7 @@ data_dir = os.path.join(script_dir, '..', 'data')
config_dir = os.path.join(data_dir, 'config')
argparser = argparse.ArgumentParser('Authentication helper for ingress routers')
argparser.add_argument('--forward-to', type=str, dest='forward_to', help='server to forward request to')
argparser.add_argument('-c', type=str, help='configuration override directory')
argparser.add_argument('--env-prefix', default=os.environ.get('CONFINI_ENV_PREFIX'), dest='env_prefix', type=str, help='environment prefix for variables to overwrite configuration')
argparser.add_argument('-v', action='store_true', help='be verbose')
argparser.add_argument('-vv', action='store_true', help='be more verbose')
args = argparser.parse_args(sys.argv[1:])
@ -43,21 +42,10 @@ if args.vv:
elif args.v:
logg.setLevel(logging.INFO)
config = confini.Config(config_dir, args.env_prefix, override_dirs=args.c)
config = confini.Config(config_dir, override_dirs=args.c)
config.process()
logg.debug('config loaded:\n' + str(config))
reverse_proxy = None
if args.forward_to:
from cic_auth_helper.proxy import ReverseProxy
forward_to = urllib.parse.urlsplit(args.forward_to)
forward_to = urllib.parse.urlunsplit(forward_to)
reverse_proxy = ReverseProxy(forward_to, ignore_proxy_headers=[
'access-control-allow-origin',
])
logg.info('will forward requests to {}'.format(forward_to))
# The Retriever is at the heart of the setup.
# It will run all the decoding steps from all the filters, ultimately resolving to a auth resource (typically ACL) and an identity
challenger = Challenger()
@ -110,23 +98,11 @@ def do_auth(env):
logg.debug('not a http hoba request: {}'.format(e))
return authenticator.check()
# And to conclude, vanilla UWSGI stuff
def application(env, start_response):
headers = []
# fetch control headers
headers.append(('Access-Control-Allow-Origin', config.get('HTTP_CORS_ORIGIN'),))
headers.append(('Access-Control-Expose-Headers', 'WWW-Authenticate, Token',))
headers.append(('Access-Control-Allow-Headers', '*',))
headers.append(('Access-Control-Allow-Credentials', 'true',))
# to appease fetch pre-flights
if env['REQUEST_METHOD'] == 'OPTIONS':
start_response('200 OK', headers)
return [b'']
print('env {}'.format(env))
result = do_auth(env)
if result == None:
@ -153,12 +129,5 @@ def application(env, start_response):
elif session.auth != auth_string:
headers.append(('Token', base64.b64encode(session.auth).decode('utf-8'),))
response_status = '200 OK'
content = b''
if reverse_proxy != None:
(response_status, headers, content) = reverse_proxy.proxy_pass(env, headers)
else:
content = str(auth_resource).encode('utf-8')
start_response('200 OK', headers)
return [content]
return [str(auth_resource).encode('utf-8')]

2
tests/.env Normal file
View File

@ -0,0 +1,2 @@
export PGP_TRUSTED_PUBLICKEY_FINGERPRINT=CCE2E1D2D0E36ADE0405E2D0995BB21816313BD5
export PGP_IMPORT_DIR=tests/pgp/dev