• Sean Hammond's avatar
    Enable publishing annotations to a group · 95512b68
    Sean Hammond authored
    Features
    ========
    
    1. If you have a group selected in the groups dropdown when you create
       an annotation, the annotation will be created in that group.
    
    2. Only users who are members of the group can see the group's
       annotations.
    
    3. An annotation can be separately set to public or private, whether it
       is in a group or not, using the separate visibility dropdown on the
       annotation card when creating or editing an annotation.
    
       Private means viewable by the user only, public means viewable by the
       group or by everyone if the annotation has no group. When in a group
       the group's name appears instead of "Public" in the user interface
       (and with a group icon instead of the public icon). So for example if
       I make an annotation in group Foobar I can set its visibility to Only
       Me or to Foobar.
    
    4. New icons and styles for all the group-related parts of the UI,
       should look the same as in Jake's mockups now.
    
    Implementation Notes
    ====================
    
    Auth
    ----
    
    - We add `"group:<hashid>"` principals to `request.effective_principals`
      for each group the user is a member of.
    
    - The existing `"group:admin"` and `"group:staff"` principals are
      renamed to `"group:__admin__"` and `"group:__staff__"` so that they
      never clash with group hashids (hashids never contain _'s).
    
    - A user may only create an annotation in group "x" if they are
      themselves a member of group "x". This is enforced by an ACL
      in `h.api.resources`.
    
    - Users may only view annotations in groups of which they are members.
      This is enforced by a query filter in search: `h.api.groups.search`.
    
    - In `h.api.groups.logic`: A reply's group is always set to that of its
      parent, server-side. It doesn't matter what the client sends.
    
    Search Filtering
    ----------------
    
    - Whether an annotation belongs to a group is recorded in a top-level
      `group` field in the annotation. The value of this field is the
      group's hashid.
    
      For example, it is currently possible to have a private annotation
      (visible only to the user who created it) within a group. This allows
      users to use the privacy controls for "drafting" group annotations and
      replies, only sharing them with the group when they're ready. It also
      allows users to keep private replies to group annotations.
    
      When the sidebar is focused on a group (not yet implemented), the
      search will filter the annotations to those that have the group's
      hashid in the group field, regardless of whether the annotation's
      permissions are private to the user or shared with the group.
    
    - The groups search filtering (`h.api.groups.search`) uses the top-level
      groups field to filter out annotations that belong to groups that the
      user isn't a member of.
    
    - Annotations that are public simply have a group field containing
      `__world__`.
    
    Client-Side
    -----------
    
    - `annotation.coffee` sets the group field on the annotation before
      saving it.
    
    - There's a new group-list-controller to handle the now more interactive
      groups dropdown.
    
    - And a group-service to share state about which group is currently
      focused with different parts of the code.
    
    Misc
    ----
    
    - `h.streamer`: Infinite scroll and live updates filter out annotations
      from groups the user isn't a member of, as well.
    
    - `h.api.search.transform`: the API adds group: '__world__' to any
      annotations without a group field before returning them to the
      client.
    95512b68
permissions.coffee 2.72 KB