def agent_visit(url, request): if request.method != "POST": raise Exception('unexpected method') log.info('agent_visit url {}'.format(url)) body = json.loads(request.body.decode('utf-8')) if body['username'] != 'test-user': raise Exception('unexpected username in body {!r}'.format(request.body)) public_key = bakery.PublicKey.deserialize(body['public_key']) ms = httpbakery.extract_macaroons(request.headers) if len(ms) == 0: b = bakery.Bakery(key=discharge_key) m = b.oven.macaroon( version=bakery.LATEST_VERSION, expiry=datetime.utcnow() + timedelta(days=1), caveats=[bakery.local_third_party_caveat( public_key, version=httpbakery.request_version(request.headers))], ops=[bakery.Op(entity='agent', action='login')]) content, headers = httpbakery.discharge_required_response( m, '/', 'test', 'message') resp = response(status_code=401, content=content, headers=headers) return request.hooks['response'][0](resp) return { 'status_code': 200, 'content': { 'agent_login': True } }
def visit(url, request): if request.headers.get('Accept') == 'application/json': return {'status_code': 200, 'content': {'agent': request.url}} cs = SimpleCookie() cookies = request.headers.get('Cookie') if cookies is not None: cs.load(str(cookies)) public_key = None for c in cs: if c == 'agent-login': json_cookie = json.loads( base64.b64decode(cs[c].value).decode('utf-8')) public_key = bakery.PublicKey.deserialize( json_cookie.get('public_key')) ms = httpbakery.extract_macaroons(request.headers) if len(ms) == 0: b = bakery.Bakery(key=discharge_key) m = b.oven.macaroon( version=bakery.LATEST_VERSION, expiry=datetime.utcnow() + timedelta(days=1), caveats=[ bakery.local_third_party_caveat( public_key, version=httpbakery.request_version( request.headers)) ], ops=[bakery.Op(entity='agent', action='login')]) content, headers = httpbakery.discharge_required_response( m, '/', 'test', 'message') resp = response(status_code=401, content=content, headers=headers) return request.hooks['response'][0](resp) return {'status_code': 200, 'content': {'agent-login': True}}
def _write_discharge_error(self, exc): version = httpbakery.request_version(self.headers) if version < bakery.LATEST_VERSION: self._server_version = version caveats = [] if self._auth_location != '': caveats = [ checkers.Caveat(location=self._auth_location, condition='is-ok') ] if self._caveats is not None: caveats.extend(self._caveats) m = self._bakery.oven.macaroon(version=bakery.LATEST_VERSION, expiry=self._expiry, caveats=caveats, ops=[TEST_OP]) content, headers = httpbakery.discharge_required_response( m, '/', 'test', exc.args[0]) self.send_response(401) for h in headers: self.send_header(h, headers[h]) self.send_header('Connection', 'close') self.end_headers() self.wfile.write(content)
def agent_visit(url, request): if request.method != "POST": raise Exception('unexpected method') log.info('agent_visit url {}'.format(url)) body = json.loads(request.body.decode('utf-8')) if body['username'] != 'test-user': raise Exception('unexpected username in body {!r}'.format( request.body)) public_key = bakery.PublicKey.deserialize(body['public_key']) ms = httpbakery.extract_macaroons(request.headers) if len(ms) == 0: b = bakery.Bakery(key=discharge_key) m = b.oven.macaroon( version=bakery.LATEST_VERSION, expiry=datetime.utcnow() + timedelta(days=1), caveats=[ bakery.local_third_party_caveat( public_key, version=httpbakery.request_version( request.headers)) ], ops=[bakery.Op(entity='agent', action='login')]) content, headers = httpbakery.discharge_required_response( m, '/', 'test', 'message') resp = response(status_code=401, content=content, headers=headers) return request.hooks['response'][0](resp) return {'status_code': 200, 'content': {'agent_login': True}}
def _write_discharge_error(self, exc): version = httpbakery.request_version(self.headers) if version < bakery.LATEST_VERSION: self._server_version = version caveats = [] if self._auth_location != '': caveats = [ checkers.Caveat(location=self._auth_location, condition='is-ok') ] if self._caveats is not None: caveats.extend(self._caveats) m = self._bakery.oven.macaroon( version=bakery.LATEST_VERSION, expiry=self._expiry, caveats=caveats, ops=[TEST_OP]) content, headers = httpbakery.discharge_required_response( m, '/', 'test', exc.args[0]) self.send_response(401) for h in headers: self.send_header(h, headers[h]) self.send_header('Connection', 'close') self.end_headers() self.wfile.write(content)
def login(url, request): b = bakery.Bakery(key=discharge_key) m = b.oven.macaroon( version=bakery.LATEST_VERSION, expiry=datetime.utcnow() + timedelta(days=1), caveats=[ bakery.local_third_party_caveat( key.public_key, version=httpbakery.request_version(request.headers)) ], ops=[bakery.Op(entity='agent', action='login')]) return {'status_code': 200, 'content': {'macaroon': m.to_dict()}}
def check_third_party_caveat(self, ctx, info): InfoStorage.info = info raise InteractionRequiredError( httpbakery.Error( code=httpbakery.ERR_INTERACTION_REQUIRED, version=httpbakery.request_version( request.headers), message='interaction required', info=httpbakery.ErrorInfo( wait_url='http://0.3.2.1/wait?' 'dischargeid=1', visit_url='http://0.3.2.1/visit?' 'dischargeid=1'), ), )
def check_third_party_caveat(self, ctx, info): InfoStorage.info = info raise InteractionRequiredError( httpbakery.Error( code=httpbakery.ERR_INTERACTION_REQUIRED, version=httpbakery.request_version( request.headers), message='interaction required', info=httpbakery.ErrorInfo( wait_url='http://0.3.2.1/wait?' 'dischargeid=1', visit_url='http://0.3.2.1/visit?' 'dischargeid=1' ), ), )
def _authorization_request(self, request, req_headers, bakery, err): """Return a 401 response with a macaroon discharge request.""" expiry_duration = min( MACAROON_LIFESPAN, timedelta(seconds=request.session.get_expiry_age())) expiration = datetime.utcnow() + expiry_duration macaroon = bakery.oven.macaroon( httpbakery.request_version(req_headers), expiration, err.cavs(), err.ops()) content, headers = httpbakery.discharge_required_response( macaroon, '/', 'authz') response = HttpResponse( status=401, reason='Unauthorized', content=content) for key, value in headers.items(): response[key] = value return response
def _authorization_request(bakery, derr=None, auth_endpoint=None, req_headers=None): """Return a 401 response with a macaroon discharge request.""" bakery_version = httpbakery.request_version(req_headers or {}) if derr: caveats, ops = derr.cavs(), derr.ops() else: caveats, ops = _get_macaroon_caveats_ops(auth_endpoint) expiration = datetime.utcnow() + MACAROON_LIFESPAN macaroon = bakery.oven.macaroon(bakery_version, expiration, caveats, ops) content, headers = httpbakery.discharge_required_response( macaroon, '/', 'maas') response = HttpResponse( status=401, reason='Unauthorized', content=content) for key, value in headers.items(): response[key] = value return response
def login(url, request): qs = parse_qs(urlparse(request.url).query) self.assertEqual(request.method, 'GET') self.assertEqual(qs, { 'username': ['test-user'], 'public-key': [PUBLIC_KEY] }) b = bakery.Bakery(key=discharge_key) m = b.oven.macaroon( version=bakery.LATEST_VERSION, expiry=datetime.utcnow() + timedelta(days=1), caveats=[ bakery.local_third_party_caveat( PUBLIC_KEY, version=httpbakery.request_version(request.headers)) ], ops=[bakery.Op(entity='agent', action='login')]) return {'status_code': 200, 'content': {'macaroon': m.to_dict()}}
def login(url, request): qs = parse_qs(urlparse(request.url).query) self.assertEqual(request.method, 'GET') self.assertEqual( qs, {'username': ['test-user'], 'public-key': [PUBLIC_KEY]}) b = bakery.Bakery(key=discharge_key) m = b.oven.macaroon( version=bakery.LATEST_VERSION, expiry=datetime.utcnow() + timedelta(days=1), caveats=[bakery.local_third_party_caveat( PUBLIC_KEY, version=httpbakery.request_version(request.headers))], ops=[bakery.Op(entity='agent', action='login')]) return { 'status_code': 200, 'content': { 'macaroon': m.to_dict() } }