• Randall Leeds's avatar
    Refactor and isolate identity, auth, and session · 4cf39590
    Randall Leeds authored
    Introduce a new module on the frontend called `h.identity` which
    abstracts the interaction between the main application and the
    authentication system using the `navigator.id` API introduced by
    Mozilla as part of Persona / BrowserID. In our case, the we submit
    the authentication assertion as a query parameter in our token
    URL. This is designed to flexibly accommodate different auth needs
    by intepreting the assertion differently and using a different
    identity module to return whatever type of grant is needed depending
    on the authentication mechanisms in place on the back end.
    
    On the back end:
    
    - Introduce a dependency on a brand new library, pyramid-oauthlib, to
      make this code cleaner and more modular.
    - Simplify our session by removing multiple signin code that was not
      ever fully realized; personas are no longer explicitly maintained in
      the session by application code.
    - The Pyramid SessionAuthenticationPolicy is put into place as part of
      h.auth.local. A SessionGrant is configured as the default grant type
      for integration via pyramid-oauthlib. This is what interprets the
      assertion sent in our token request. For other use cases, this might
      be a real BrowserID assertion or a session or refresh token of some
      other kind. This assertion is just the CSRF token our forms have been
      returning already.
    - `h#includeme` and `h#create_app` got some superficial simplification.
    - `h.api#authorize` handler for annotator-store authorizations now uses
      `request.effective_principals` instead of the session, so it doesn't
      care how the user is authenticated
      - Headers are now passed through on `Store` sub-requests so that both
      the annotator auth token and the session work for store authorizations
      which gets us close to cookie-less API auth!
      - `Consumer` class is moved into `h.auth.local`, removing the SQL
      requirement for core `h` and replacing it with just the requirement to
      register an `IConsumer` implementer.
    
    On the front end:
    
    - Break hypothesis.js into hypothesis.js and hypothesis-auth.js
    - Move session and auth modules into this auth package
    - Clean up the module dependency imports
    - Add an identity module to the auth package with `navigator.id` API
    - Significantly refactor `AppController`
      - Use the `identity.watch()` API to listen to login/logout from the
      active identity module
      - Clean up the login/logout state management a bit
        - Resolve a promise when the API service discovery happens
        - Stop using 'session', which becomes a detail of hypothesis-auth
      - Put much less on the scope from the controller
        - `scope.initUpdater` -> `initUpdater`
        - `scope.reloadAnnotations` -> `initStore`
        - `scope.session` -> replaced by `id`
        - Sorts and views are set in the markup
        - `AuthController` no longers needs to know about `model`, `sheet`,
        `sorts` or `views`
      - Isolate the form models
        - The auth directive now creates an isolate scope so that we're not
        leaking the form models all over the place
        - Stop using the inherited `$scope.model` means prevents submitting
        `persona` as a form parameter by accident
    - blocks.pt#auth-tabs becomes auth.html
      - Easy to override with `config.override_asset()` in Pyramid
      - Keeps the forms inside the isolate scope of the auth directive
    - The content of the sheet moves inside blocks.pt#auth
      - Nothing outside this knows or cares anymore that the sheet has tabs
      - Places where we want to request login use `identity.request()`
      rather than having to get at the root scope. The `authorize` event
      that this broadcasts is an internal detail of the auth pacakage.
    4cf39590
identity.coffee 1.73 KB