Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bookwyrm groups #1490

Merged
merged 133 commits into from Oct 17, 2021
Merged

Bookwyrm groups #1490

merged 133 commits into from Oct 17, 2021

Conversation

hughrun
Copy link
Contributor

@hughrun hughrun commented Oct 3, 2021

Wow, this turned out to be bigger than I expected. Apologies, if I make any in future I'll try to break the changes up a bit.

This PR relates to:

#1318
#170

This PR creates:

  1. Groups that a user can join via a GroupMembership
  2. A group curation option for Book Lists
  3. A group value for lists, so that lists can be associated with a group for curation purposes

Groups do not currently interact with ActivityPub, but could. I am not confident to implement this functionality at this stage, hence not including it, but that's the only reason. I'd be happy to look into this for a later PR. Hopefully I haven't accidentally inluded any AP functionality where it shouldn't be.

Outstanding problems/questions to resolve/things to note

  1. I can't work out how to adjust privacy_filter so that Group members can see groups they wouldn't otherwise see (i.e. groups with privacy levels of direct, or of followers when the viewer isn't a follower), whilst ensuring that the privacy filter nevertheless works in all other cases (e.g. when a user is blocked). Currently therefore privacy_filter is NOT applied to group list display on group pages (however raise_visible_to_user will still prevent anyone from seeing a list they shouldn't have access to)

  2. I re-used some of the user suggestions code for new users, for searching for potential group members. I have, however, created a new filter function to exlude non-local users, for use until groups are AP compliant.

  3. I am assuming that I should not commit anything in the migrations directory, and that maintainers will run makemigrations where appropriate: let me know if this assumption is wrong.

  4. I am not sure what to do about group members who block each other. Currently:

    1. If the group.user has blocked a user, the second user cannot access the group page but can access any lists assigned to the group if they are owned by someone else, and can add & delete items on those lists;
    2. If a member of a group who is not group.user creates a list, other members who are blocked by that user cannot see the list (but can see it listed on the group page)
    3. Users who are blocked cannot invite the blocker to join a group because they won't appear in the user-inviting search results.

    The second case could be fixed if privacy_filter worked for groups and group lists. The first case may not matter much because a group owner can simply remove any member from the group, but it is a bit weird and not really ideal.

  5. I get a Object of type LocalStream is not JSON serializable error when attempting to unblock a user in my development environment. I'm not sure whether this is an actual bug in Bookwyrm, a problem with my setup, or if I somehow broke something in the codebase. This may need to be checked!

  6. I'm guessing you probably want some tests - I created some new classes and filters. What are the expectations/requirements around this?

Groups

  1. any user may create a Group.
  2. this group.user may send a GroupMemberInvitation to any other user as long as they are not blocked either way
  3. the invitee must accept the GroupMemberInvitation to create a GroupMembership.
  4. members (users with a GroupMembership connecting them to a Group) can:
    1. create a List with a curation value of group and assign the List to this group
    2. See all Lists associated with the group, on the group home page
    3. see the list page for any List associated with the group, regardless of its privacy value (unless the list.user has blocked them)
    4. add books to and remove books from any List associated with the group (unless the list.user has blocked them)
  5. Groups have their own page visible to all users, at /group/{id}

Lists

  1. Lists now have a new curation value of group
  2. Group-curated lists must be associated with one (and only one) Group
  3. Any member of the group can add and remove books to/from the list, unless blocked by the list.user.
  4. Lists can have their curation value changed at any point: either by changing it to a non-group curation (closed, curated, open), or by changing the group it is associated with.
  5. If a list's curation value is changed, group members no longer have access (unless curation is "public")
  6. If a user is removed from the group, their group-curated lists will be changed to closed curation with a group of None.

Notifications

Group members are notified when:

  • a new member joins
  • a member leaves
  • a member is removed
  • a book is added to a group-curated list

group.users (group owners) are notified when:

  • a user accepts their invitation to join

Users are notified when:

  • a group.user invites them to join a group

Abuse and privacy

I have attempted to think about the potential for abuse and mitigate it, however I've probably missed something, and as noted above there are some outstanding problems to resolve.

  1. Users must be invited to join a group: you cannot simply make someone a member of a group without them opting in
  2. Group curated lists are removed from a group when the list.user leaves the group and given curation=private
  3. Users can leave voluntarily or be removed by the group.owner
  4. The same privacy levels apply to groups and group-curated lists as for any other object. This means if I group-curate a list with privacy level direct, only group members will be able to access it.
  5. privacy_filter needs to be adjusted, or an alternative created for groups, so that the ability to see the existence of a list is also determined by privacy levels (e.g. direct lists don't appear on a group's list of Lists)

Design

As much as possible all changes are based on existing code and attempt to integrate seamlessly. I'm open to presenting any of the new options differently.

group_list_creation

user_groups

group_homepage

add_book_to_shared_list

notifications

adds a group creation form to user dashboard
- add list cards to groups page based on lists page
- add sort to members on group page
you probably want this otherwise nothing previously added for group creation will work :-)
- creates groups/user_groups template for listing a user's groups on their user page
- search for users to add to a group
- display suggested users on search results screen

TODO: actaully enable users to be added!
TODO: groups/suggested_users probably could be replaced with some logic in snippets/suggested_users.html
- this will also enable members to be removed easily by managers in a future commit.
- remove GroupList model
- add a group foreign key value  to List model
- remove reference to lists in Group model
Allows 'group' to be blank when saving a list.
Removes the 'group' field when saving a list with curation other than 'group' - this stops the list "sticking" to a group after it is changed from group curation to something else.
When creating or editing a list, the group selection dropdown will only appear if the user selects "group" as the curation option (or it is already selected).

- fix typo in bookwyrm.js comments
- add data-hides trigger for hiding elements after they have been unhidden, where simple toggles are not the right approach
This will allow privacy management to use existing code.
Some template updates also are for rationalising how
groups are created and edited.
@hughrun
Copy link
Contributor Author

hughrun commented Oct 14, 2021

Thanks for these suggestions :-)

Re 1 and 2, this was definitely there at some point, so I must have accidentally broken both of those when I was refactoring. If there are no groups it should invite you to make a group with a link that takes you to your Groups page (which has the button to create a group)

Re 3 - makes sense, I think moving the searchbox into the main panel is the better solution.

Re 4 and 5 I agree but managing state is something I always find tricky so if it can be a follow up PR that would be preferable so I can look into how best to do it and any examples of ways you've handled anything similar.

Re 6 - absolutely!

Re 7 - sounds straightforward, will add it to the list of other fixes.

You should expect a (hopefully) final load of fixes this weekend!

- don't unnecessarily query DB in List views
- use more efficient query in remove_from_group List class method
This reverts commit 41f27a4.

I forgot that update() can only be done on a query result, not on an object, so we will need to go back to querying in order to update rather than saving.
Use .save() twice, but with broadcast=False on the second update. This is more efficient than doing a query and update() and avoids the duplicate AP broadcast.
- fix form details not appearing in group member search view
- fix query term appearing in main search box when searching for new members
- direct request user back to the group rather than the user when adding a user to a group
- require confirmation before removing a member
- require confirmation before removing self
- make button text less verbose
- use more standardised formatting for group editing form
- improve button colours
- add missing trans tags
- reload group page when removing member
Whoops, forgot to add this functionality earlier.

- allow owner to delete a group
- change all group lists to closed curation with group=False when group deleted
@hughrun
Copy link
Contributor Author

hughrun commented Oct 16, 2021

@mouse-reeve LOL so clearly I need some help with tests, I've managed to break ALL of them.

Other than that:

  • all suggestions from your code review have been resolved
  • all suggestions in your comment above have been resolved
  • users can now delete their groups (whoops, we both missed that one) and any group lists are changed to closed curation with the group removed

Looking forward to seeing this in production once we've sorted out the tests.

@mouse-reeve
Copy link
Member

All tests failing is so much better than just some tests failing. It looks like the migrations need to be updated - if you merge in main and then run ./bw-dev makemigrations --merge, that should create a new migration file that resolves the conflicts and you'll be good to go.

Copy link
Member

@mouse-reeve mouse-reeve left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Once the tests are passing I think this is good to go :)

There are database migrations in main ahead of this branch so they need to be merged in to the branch before we can merge back into main.
bookwyrm/tests/models/test_group.py Outdated Show resolved Hide resolved
bookwyrm/tests/views/test_group.py Outdated Show resolved Hide resolved
@marek-lach
Copy link

Some fediverse applications implement the URL for a group as "https://tavern.town/`groups`/sneakerheads". Bookwyrm could probably accept both /group, and also /groups as a valid group URL, to be compatible in this regard with as many fediverse software as possible?

Awesome feature tho,

@mouse-reeve
Copy link
Member

Thank you! Right now, groups aren't federated (see #1548). In terms of compatibility, the url shouldn't make a difference, since the applications should be providing those in the activitypub serializations

@hughrun hughrun deleted the bookwyrm-groups branch October 18, 2021 02:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants