__init__.py
2.11 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
import os
from base64 import b64decode
from pyramid.config import Configurator
from pyramid.authentication import IAuthenticationPolicy
from pyramid.authorization import ACLAuthorizationPolicy
from zope.interface import implementer
from winpay.encrypt import verify_without_salt
from winpay.signature import create_data
def create_sign_data(request):
return create_data(
request.json_body, request.headers.get('X-Timestamp'),
request.method, request.path)
@implementer(IAuthenticationPolicy)
class AuthenticationPolicy:
def authenticated_userid(self, request):
partner_id = request.headers.get('X-Partner-Id')
settings = request.registry.settings
if partner_id not in settings['public_keys']:
return None
user_id, public_key = settings['public_keys'][partner_id]
signature_b64 = request.headers.get('X-Signature')
signature_b64 = signature_b64.encode('utf-8')
signature = b64decode(signature_b64)
sign_data = create_sign_data(request)
verify_without_salt(public_key, signature, sign_data)
return user_id
# Di production public key disimpan di database
def user_public_keys(settings):
base_dir, _ = os.path.split(settings['config_file'])
d = {}
for user in settings['users'].strip().splitlines():
user_id, partner_id, public_file = user.split(',')
if not os.path.exists(public_file):
public_file = os.path.join(base_dir, public_file)
with open(public_file, 'rb') as f:
public_bytes = f.read()
d[partner_id] = (user_id, public_bytes)
return d
def main(global_config, **settings):
settings['config_file'] = global_config['__file__']
settings['public_keys'] = user_public_keys(settings)
with Configurator(settings=settings) as config:
authn_policy = AuthenticationPolicy()
authz_policy = ACLAuthorizationPolicy()
config.set_authentication_policy(authn_policy)
config.set_authorization_policy(authz_policy)
config.include('pyramid_snap')
config.scan('.views')
return config.make_wsgi_app()