| 
          from wsgiref.simple_server import make_server | 
        
        
           | 
          
 | 
        
        
           | 
          from pyramid.config import Configurator | 
        
        
           | 
          from pyramid.decorator import reify | 
        
        
           | 
          from pyramid.authorization import ACLAuthorizationPolicy | 
        
        
           | 
          from pyramid.authentication import CallbackAuthenticationPolicy | 
        
        
           | 
          from pyramid.view import view_config, view_defaults | 
        
        
           | 
          from pyramid.security import ( | 
        
        
           | 
              ALL_PERMISSIONS, | 
        
        
           | 
              Allow, | 
        
        
           | 
              unauthenticated_userid, | 
        
        
           | 
              Everyone, | 
        
        
           | 
              ) | 
        
        
           | 
          from pyramid.traversal import find_interface | 
        
        
           | 
          
 | 
        
        
           | 
          
 | 
        
        
           | 
          def main(global_config, **settings): | 
        
        
           | 
              config = Configurator(settings=settings) | 
        
        
           | 
              config.include(__name__) | 
        
        
           | 
              return config.make_wsgi_app() | 
        
        
           | 
          
 | 
        
        
           | 
          
 | 
        
        
           | 
          def includeme(config): | 
        
        
           | 
              config.set_root_factory(Root) | 
        
        
           | 
              config.set_authentication_policy(AuthenticationPolicy()) | 
        
        
           | 
              config.set_authorization_policy(ACLAuthorizationPolicy()) | 
        
        
           | 
              config.scan() | 
        
        
           | 
          
 | 
        
        
           | 
          
 | 
        
        
           | 
          class AuthenticationPolicy(CallbackAuthenticationPolicy): | 
        
        
           | 
          
 | 
        
        
           | 
              def __init__(self): | 
        
        
           | 
                  super(CallbackAuthenticationPolicy, self).__init__() | 
        
        
           | 
          
 | 
        
        
           | 
              def unauthenticated_userid(self, request): | 
        
        
           | 
                  userid = None | 
        
        
           | 
                  if 'X-DUMMY-AUTH-USERID' in request.headers: | 
        
        
           | 
                      userid = request.headers.get('X-DUMMY-AUTH-USERID') | 
        
        
           | 
                  return userid | 
        
        
           | 
          
 | 
        
        
           | 
              def callback(self, userid, request): | 
        
        
           | 
                  principals = [] | 
        
        
           | 
                  context = request.context | 
        
        
           | 
          
 | 
        
        
           | 
                  if hasattr(context, 'group_finder'): | 
        
        
           | 
                      principals.extend(context.group_finder(request)) | 
        
        
           | 
          
 | 
        
        
           | 
                  return principals | 
        
        
           | 
          
 | 
        
        
           | 
          
 | 
        
        
           | 
          # / | 
        
        
           | 
          class Root(object): | 
        
        
           | 
          
 | 
        
        
           | 
              def __init__(self, request): | 
        
        
           | 
                  self.request = request | 
        
        
           | 
                  self.__name__ = '' | 
        
        
           | 
                  self.__parent__ = None | 
        
        
           | 
          
 | 
        
        
           | 
              def __getitem__(self, key): | 
        
        
           | 
                  return UsersCollection(key, self) | 
        
        
           | 
          
 | 
        
        
           | 
          
 | 
        
        
           | 
          # /users | 
        
        
           | 
          class UsersCollection(object): | 
        
        
           | 
          
 | 
        
        
           | 
              def __init__(self, name, parent): | 
        
        
           | 
                  self.__name__ = name | 
        
        
           | 
                  self.__parent__ = parent | 
        
        
           | 
          
 | 
        
        
           | 
              def __getitem__(self, key): | 
        
        
           | 
                  return User(key, self) | 
        
        
           | 
          
 | 
        
        
           | 
          
 | 
        
        
           | 
          # /users/bob_marley/ | 
        
        
           | 
          class User(object): | 
        
        
           | 
          
 | 
        
        
           | 
              def __init__(self, name, parent): | 
        
        
           | 
                  self.__name__ = name | 
        
        
           | 
                  self.__parent__ = parent | 
        
        
           | 
          
 | 
        
        
           | 
              def __getitem__(self, key): | 
        
        
           | 
                  return NotesCollection(key, self) | 
        
        
           | 
          
 | 
        
        
           | 
          
 | 
        
        
           | 
          # /users/bob_marley/notes/ | 
        
        
           | 
          class NotesCollection(object): | 
        
        
           | 
          
 | 
        
        
           | 
              __acl__ = [ | 
        
        
           | 
                  (Allow, Everyone, 'show'), | 
        
        
           | 
                  (Allow, 'group:owner', ALL_PERMISSIONS), | 
        
        
           | 
              ] | 
        
        
           | 
          
 | 
        
        
           | 
              def __init__(self, name, parent): | 
        
        
           | 
                  self.__name__ = name | 
        
        
           | 
                  self.__parent__ = parent | 
        
        
           | 
          
 | 
        
        
           | 
              def __getitem__(self, key): | 
        
        
           | 
                  return Note(key, self) | 
        
        
           | 
          
 | 
        
        
           | 
          
 | 
        
        
           | 
          # /users/bob_marley/notes/456 | 
        
        
           | 
          class Note(object): | 
        
        
           | 
          
 | 
        
        
           | 
              def __init__(self, name, parent): | 
        
        
           | 
                  self.__name__ = name | 
        
        
           | 
                  self.__parent__ = parent | 
        
        
           | 
          
 | 
        
        
           | 
              @reify | 
        
        
           | 
              def user(self): | 
        
        
           | 
                  return find_interface(self, User) | 
        
        
           | 
          
 | 
        
        
           | 
              @property | 
        
        
           | 
              def userid(self): | 
        
        
           | 
                  # /users/123/notes/456 will return 123 | 
        
        
           | 
                  return self.user.__name__ | 
        
        
           | 
          
 | 
        
        
           | 
              def group_finder(self, request): | 
        
        
           | 
                  principals = [] | 
        
        
           | 
                  if unauthenticated_userid(request) == self.user.__name__: | 
        
        
           | 
                      principals.append('group:owner') | 
        
        
           | 
                  return principals | 
        
        
           | 
          
 | 
        
        
           | 
              def replace(self, params): | 
        
        
           | 
                  "save in db... Only owners can" | 
        
        
           | 
                  return {'status': '200'} | 
        
        
           | 
          
 | 
        
        
           | 
              def show(self): | 
        
        
           | 
                  "get from db" | 
        
        
           | 
                  return { | 
        
        
           | 
                      'id': self.__name__, | 
        
        
           | 
                      'content': 'A dummy note', | 
        
        
           | 
                  } | 
        
        
           | 
          
 | 
        
        
           | 
          
 | 
        
        
           | 
          @view_defaults(context=Note) | 
        
        
           | 
          class View(object): | 
        
        
           | 
          
 | 
        
        
           | 
              def __init__(self, context, request): | 
        
        
           | 
                  self.request = request | 
        
        
           | 
                  self.context = context | 
        
        
           | 
          
 | 
        
        
           | 
              @view_config(request_method='GET', permission='show', renderer='json') | 
        
        
           | 
              def show(self): | 
        
        
           | 
                  return self.context.show() | 
        
        
           | 
          
 | 
        
        
           | 
              @view_config(request_method='PUT', permission='replace', renderer='json') | 
        
        
           | 
              def replace(self): | 
        
        
           | 
                  return self.context.replace(self.request.POST) | 
        
        
           | 
          
 | 
        
        
           | 
          
 | 
        
        
           | 
          if __name__ == '__main__': | 
        
        
           | 
              server = make_server('0.0.0.0', 8080, main({})) | 
        
        
           | 
              server.serve_forever() |