import random import wsgiref.simple_server from pyramid.config import Configurator from pyramid.interfaces import IAuthenticationPolicy from pyramid.response import Response from pyramid.security import authenticated_userid from pyramid.exceptions import Forbidden from pyramid_macauth import MACAuthenticationPolicy TEMPLATE = """ Hello {userid}! Your lucky number for today is {number}. """ def lucky_number(request): """Pyramid view to generate a lucky number.""" # Check that the user is authenticated. userid = authenticated_userid(request) if userid is None: raise Forbidden() # Generate and return the lucky number. number = random.randint(1,100) return Response(TEMPLATE.format(**locals()), content_type="text/plain") def provision_creds(request): """Pyramid view to provision MACAuth credentials.""" # Check that the user is authenticated. userid = authenticated_userid(request) if userid is None: raise Forbidden() # Get a reference to the MACAuthenticationPolicy plugin. policy = request.registry.getUtility(IAuthenticationPolicy) policy = policy.get_policy(MACAuthenticationPolicy) # Generate a new id and secret key for the current user. id, key = policy.encode_mac_id(request, userid) return {"id": id, "key": key} def main(): """Construct and return a WSGI app for the luckynumber service.""" settings = { # The pyramid_persona plugin needs a master secret to use for # signing login cookies, and the expected hostname of your website # to prevent fradulent login attempts. "persona.secret": "TED KOPPEL IS A ROBOT", "persona.audiences": "localhost:8080", # The pyramid_macauth plugin needs a master secret to use for signing # its access tokens. We could use the same secret as above, but it's # generally a good idea to use different secrets for different things. "macauth.master_secret": "V8 JUICE IS 1/8TH GASOLINE", # The pyramid_multiauth plugin needs to be told what sub-policies to # load, and the order in which they should be tried. "multiauth.policies": "pyramid_persona pyramid_macauth", } config = Configurator(settings=settings) config.add_route("number", "/") config.add_view(lucky_number, route_name="number") # Including pyramid_multiauth magically enables authentication, loading # both of the policies we specified in the settings. config.include("pyramid_multiauth") # Both of our chosen policies configure a "forbidden view" to handle # unauthenticated access. We have to resolve this conflict by explicitly # picking which one we want to use. config.add_forbidden_view("pyramid_persona.views.forbidden") config.add_route("provision", "/provision") config.add_view(provision_creds, route_name="provision", renderer="json") return config.make_wsgi_app() if __name__ == "__main__": app = main() server = wsgiref.simple_server.make_server("", 8081, app) server.serve_forever()