]> Untitled Git - lemmy.git/commitdiff
Merge pull request 'Update lemmy-ui version in docker-compose files on release (fixes...
authordessalines <dessalines@noreply.yerbamate.dev>
Mon, 5 Oct 2020 16:49:51 +0000 (16:49 +0000)
committerdessalines <dessalines@noreply.yerbamate.dev>
Mon, 5 Oct 2020 16:49:51 +0000 (16:49 +0000)
Reviewed-on: https://yerbamate.dev/LemmyNet/lemmy/pulls/111

12 files changed:
README.md
ansible/lemmy.yml
ansible/templates/nginx.conf
docs/src/SUMMARY.md
docs/src/contributing.md
docs/src/contributing_apub_api_outline.md
docs/src/contributing_federation_overview.md [new file with mode: 0644]
lemmy_apub/src/comment.rs
lemmy_apub/src/inbox/community_inbox.rs
lemmy_apub/src/post.rs
lemmy_db/src/community.rs
lemmy_db/src/user.rs

index 0c534d54ec8ef29ca0e7798cdcd5bc96a4188d13..53a477353b8661ccb48521a54b742451639d4f1f 100644 (file)
--- a/README.md
+++ b/README.md
@@ -36,7 +36,7 @@ Front Page|Post
 ---|---
 ![main screen](https://raw.githubusercontent.com/LemmyNet/lemmy/main/docs/img/main_screen.png)|![chat screen](https://raw.githubusercontent.com/LemmyNet/lemmy/main/docs/img/chat_screen.png)
 
-[Lemmy](https://github.com/LemmyNet/lemmy) is similar to sites like [Reddit](https://reddit.com), [Lobste.rs](https://lobste.rs), [Raddle](https://raddle.me), or [Hacker News](https://news.ycombinator.com/): you subscribe to forums you're interested in, post links and discussions, then vote, and comment on them. Behind the scenes, it is very different; anyone can easily run a server, and all these servers are federated (think email), and connected to the same universe, called the [Fediverse](https://en.wikipedia.org/wiki/Fediverse).
+[Lemmy](https://github.com/LemmyNet/lemmy) is similar to sites like [Reddit](https://reddit.com), [Lobste.rs](https://lobste.rs), or [Hacker News](https://news.ycombinator.com/): you subscribe to forums you're interested in, post links and discussions, then vote, and comment on them. Behind the scenes, it is very different; anyone can easily run a server, and all these servers are federated (think email), and connected to the same universe, called the [Fediverse](https://en.wikipedia.org/wiki/Fediverse).
 
 For a link aggregator, this means a user registered on one server can subscribe to forums on any other server, and can have discussions with users registered elsewhere.
 
@@ -152,7 +152,7 @@ If you want to help with translating, take a look at [Weblate](https://weblate.y
 
 - [GitHub](https://github.com/LemmyNet/lemmy)
 - [Gitea](https://yerbamate.dev/LemmyNet/lemmy)
-- [GitLab](https://gitlab.com/dessalines/lemmy)
+- [Codeberg](https://codeberg.org/LemmyNet/lemmy)
 
 ## Credits
 
index b4187158fa4e84b1e169cd8ca4a967e8ccc16455..28179ba418034d8f6cc8e8ff3585dafe364081b5 100644 (file)
@@ -79,6 +79,7 @@
         lemmy_docker_image: "dessalines/lemmy:{{ lookup('file', 'VERSION') }}"
         lemmy_docker_ui_image: "dessalines/lemmy-ui:{{ lookup('file', 'VERSION') }}"
         lemmy_port: "8536"
+        lemmy_ui_port: "1235"
         pictshare_port: "8537"
         iframely_port: "8538"
 
index 7f13259ad3fcc3e5ee4892a641f4389121aa1ec9..03b139bb0563547e1adc0d7b6ab4165894ca842e 100644 (file)
@@ -57,6 +57,10 @@ server {
       proxy_set_header Host $host;
       proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
 
+      # The default ports:
+      # lemmy_ui_port: 1235
+      # lemmy_port: 8536
+
       set $proxpass "http://0.0.0.0:{{ lemmy_ui_port }}";
       if ($http_accept = "application/activity+json") {
         set $proxpass "http://0.0.0.0:{{ lemmy_port }}";
index a2bf585697c264195e8e8c4e44287ca264babea5..020a9dc1b8aa4a9e8176c5d484ea784d19958d05 100644 (file)
@@ -17,6 +17,7 @@
   - [Tests](contributing_tests.md)
   - [Federation Development](contributing_federation_development.md)
   - [Websocket/HTTP API](contributing_websocket_http_api.md)
+  - [Federation Overview](contributing_federation_overview.md)
   - [ActivityPub API Outline](contributing_apub_api_outline.md)
   - [Theming Guide](contributing_theming.md)
 - [Lemmy Council](lemmy_council.md)
index 02eb9177441ea61df45f822f8a88e80a56c7cb16..e9c7b9ea19307d0a2e0fd9621c19723caea40b18 100644 (file)
@@ -6,7 +6,7 @@ Information about contributing to Lemmy, whether it is translating, testing, des
 
 - [GitHub (for issues and pull requests)](https://github.com/LemmyNet/lemmy)
 - [Gitea (only for pull requests)](https://yerbamate.dev/LemmyNet/lemmy)
-- [GitLab (only code-mirror)](https://gitlab.com/dessalines/lemmy)
+- [Codeberg](https://codeberg.org/LemmyNet/lemmy)
 
 ## Translating
 
index e2776308f2662dbbebadcd5c410eca856e26b019..4ee2636eda43ea8043a9fc1092006968cd38d3f7 100644 (file)
@@ -1,5 +1,7 @@
 # Activitypub API outline
 
+**This document is completely outdated and doesn't reflect the current state of Lemmy at all**
+
 - Start with the [reddit API](https://www.reddit.com/dev/api), and find [Activitypub vocab](https://www.w3.org/TR/activitystreams-vocabulary/) to match it.
 
 <!-- toc -->
diff --git a/docs/src/contributing_federation_overview.md b/docs/src/contributing_federation_overview.md
new file mode 100644 (file)
index 0000000..8ed5442
--- /dev/null
@@ -0,0 +1,127 @@
+# Federation
+
+
+This document is targeted at people that are more or less familiar with ActivityStreams and ActivityPub protocols. It is meant provide a high-level overview of ActivityPub federation in Lemmy. If you are implementing ActivityPub yourself and want to be compatible with Lemmy, read our [ActivityPub API outline](contributing_apub_api_outline.md).
+
+## Documentation conventions
+
+To keep things simple, sometimes you will see things formatted like `Create/Note` or `Delete/Event` or `Undo/Follow`. The thing before the slash is the Activity, and the thing after the slash is the Object inside the Activity, in an `object` property. So these are to be read as follows:
+
+* `Create/Note`: a `Create` activity containing a `Note` in the `object` field 
+* `Delete/Event`: a `Delete` activity containing an `Event` in the `object` field
+* `Undo/Follow`: an `Undo` activity containing a `Follow` in the `object` field
+
+In Lemmy we use some specific terms to refer to ActivityPub items. They are essentially our specific implementations of well-known ActivityPub concepts:
+
+- Community: `Group`
+- User: `Person`
+- Post: `Page`
+- Comment: `Note`
+
+This document has three main sections:
+
+* __Federation philosophy__ lays out the general model of how this is intended to federate
+* __User Activities__ describes which actions that a User can take to interact
+* __Community Activities__ describes what the Community does in response to certain User actions
+
+## Federation philosophy
+
+The primary Actor in Lemmy is the Community. Each community resides on a single instance, and consists of a list of Posts and a list of followers. The primary interaction is that of a User sending a Post or Comment related activity to the Community inbox, which then announces it to all its followers. 
+
+Each Community has a specific creator User, who is responsible for setting rules, appointing moderators, and removing content that violates the rules.
+
+Besides moderation on the community level, each instance has a set of administrator Users, who have the power to do site-wide removals and bans.
+
+Users follow Communities that they are interested in, in order to receive Posts and Comments. They also vote on Posts and Comments, as well as creating new ones. Comments are organised in a tree structure and commonly sorted by number of votes. Direct messages between Users are also supported.
+
+Users can not follow each other, and neither can Communities follow anything.
+
+Our federation implementation is already feature complete, but so far we haven't focused at all on complying with the ActivityPub spec. As such, Lemmy is likely not compatible with implementations which expect to send and receive valid activities. This is something we plan to fix in the near future. Check out [#698](https://github.com/LemmyNet/lemmy/issues/698) for an overview of our deviations.
+
+## User Activities
+
+### Follow a Community
+
+Each Community page has a "Follow" button. Clicking this triggers a `Follow` activity to be sent from the user to the Community inbox. The Community will automatically respond with an `Accept/Follow` activity to the user inbox. It will also add the user to its list of followers, and deliver any activities about Posts/Comments in the Community to the user.
+
+### Unfollow a Community
+
+After following a Community, the "Follow" button is replaced by "Unfollow". Clicking this sends an `Undo/Follow` activity to the Community inbox. The Community removes the User from its followers list and doesn't send any activities to it anymore.
+
+### Create a Post
+
+When a user creates a new Post in a given Community, it is sent as `Create/Page` to the  Community
+inbox. 
+
+### Create a Comment
+
+When a new Comment is created for a Post, both the Post ID and the parent Comment ID (if it exists)
+are written to the `in_reply_to` field. This allows assigning it to the correct Post, and building
+the Comment tree. It is then sent to the Community inbox as `Create/Note`
+
+The origin instance also scans the Comment for any User mentions, and sends the `Create/Note` to
+those Users as well.
+
+### Edit a Post
+
+Changes the content of an existing Post. Can only be done by the creating User.
+
+### Edit a Comment
+
+Changes the content of an existing Comment. Can only be done by the creating User.
+
+### Likes and Dislikes
+
+Users can like or dislike any Post or Comment. These are sent as `Like/Page`, `Dislike/Note` etc to the Community inbox.
+
+### Deletions
+
+The creator of a Post, Comment or Community can delete it. It is then sent to the Community followers. The item is then hidden from all users.
+
+### Removals
+
+Mods can remove Posts and Comments from their Communities. Admins can remove any Posts or Comments on the entire site. Communities can also be removed by admins. The item is then hidden from all users.
+
+Removals are sent to all followers of the Community, so that they also take effect there. The exception is if an admin removes an item from a Community which is hosted on a different instance. In this case, the removal only takes effect locally.
+
+### Revert a previous Action
+
+We don't delete anything from our database, just hide it from users. Deleted or removed Communities/Posts/Comments have a "restore" button. This button generates an `Undo` activity which sets the original delete/remove activity as object, such as `Undo/Remove/Post` or `Undo/Delete/Community`.
+
+Clicking on the upvote button of an already upvoted post/comment (or the downvote button of an already downvoted post/comment) also generates an `Undo`. In this case and `Undo/Like/Post` or `Undo/Dislike/Comment`.
+
+### Create private message
+
+User profiles have a "Send Message" button, which opens a dialog permitting to send a private message to this user. It is sent as a `Create/Note` to the user inbox. Private messages can only be directed at a single User.
+
+### Edit private message
+
+`Update/Note` changes the text of a previously sent message
+
+### Delete private message
+
+`Delete/Note` deletes a private message.
+
+### Restore private message
+
+`Undo/Delete/Note` reverts the deletion of a private message.
+
+## Community Activities
+
+The Community is essentially a bot, which will only do anything in reaction to actions from Users. The User who first created the Community becomes the first moderator, and can add additional moderators. In general, whenever the Community receives a valid activity in its inbox, that activity is forwarded to all its followers.
+
+### Accept follow
+
+If the Community receives a `Follow` activity, it automatically responds with `Accept/Follow`. It also adds the User to its list of followers. 
+
+### Unfollow
+
+Upon receiving an `Undo/Follow`, the Community removes the User from its followers list.
+### Announce
+
+If the Community receives any Post or Comment related activity (Create, Update, Like, Dislike, Remove, Delete, Undo), it will Announce this to its followers. For this, an Announce is created with the Community as actor, and the received activity as object. Following instances thus stay updated about any actions in Communities they follow.
+
+### Delete Community
+
+If the creator or an admin deletes the Community, it sends a `Delete/Group` to all its followers.
index 4e5c173f892c8b3d4df55e1f9ba25c5f4881a574..459d0796cda86244a595650c9b197cf6222c83d1 100644 (file)
@@ -35,6 +35,7 @@ use activitystreams::{
 };
 use actix_web::{body::Body, web, web::Path, HttpResponse};
 use anyhow::Context;
+use diesel::result::Error::NotFound;
 use itertools::Itertools;
 use lemmy_db::{
   comment::{Comment, CommentForm},
@@ -68,6 +69,9 @@ pub async fn get_apub_comment(
 ) -> Result<HttpResponse<Body>, LemmyError> {
   let id = info.comment_id.parse::<i32>()?;
   let comment = blocking(context.pool(), move |conn| Comment::read(conn, id)).await??;
+  if !comment.local {
+    return Err(NotFound.into());
+  }
 
   if !comment.deleted {
     Ok(create_apub_response(
index ee75fa005fa758cf75e3ed1e7f1a56dad2373054..6f5f1854ee066397dab03f87517e80e93d2901d3 100644 (file)
@@ -11,7 +11,7 @@ use activitystreams::{
   prelude::*,
 };
 use actix_web::{web, HttpRequest, HttpResponse};
-use anyhow::{anyhow, Context};
+use anyhow::Context;
 use lemmy_db::{
   community::{Community, CommunityFollower, CommunityFollowerForm},
   user::User_,
@@ -48,15 +48,6 @@ pub async fn community_inbox(
   })
   .await??;
 
-  if !community.local {
-    return Err(
-      anyhow!(
-        "Received activity is addressed to remote community {}",
-        &community.actor_id
-      )
-      .into(),
-    );
-  }
   debug!(
     "Community {} received activity {:?}",
     &community.name, &activity
index 8f5ffbcb8f4310fd481b256ee4e5a36b68232552..efdfcfd6cbed990e92ffbe787b65c174cb521400 100644 (file)
@@ -31,6 +31,7 @@ use activitystreams::{
 use activitystreams_ext::Ext1;
 use actix_web::{body::Body, web, HttpResponse};
 use anyhow::Context;
+use diesel::result::Error::NotFound;
 use lemmy_db::{
   community::Community,
   post::{Post, PostForm},
@@ -61,6 +62,9 @@ pub async fn get_apub_post(
 ) -> Result<HttpResponse<Body>, LemmyError> {
   let id = info.post_id.parse::<i32>()?;
   let post = blocking(context.pool(), move |conn| Post::read(conn, id)).await??;
+  if !post.local {
+    return Err(NotFound.into());
+  }
 
   if !post.deleted {
     Ok(create_apub_response(&post.to_apub(context.pool()).await?))
index 24cf7e32fd0129fdf6cabd1224cbd5dc2b8923c9..b4fa424a7f311a2929e0e55a294a9970a69fbe4a 100644 (file)
@@ -87,6 +87,7 @@ impl Community {
   pub fn read_from_name(conn: &PgConnection, community_name: &str) -> Result<Self, Error> {
     use crate::schema::community::dsl::*;
     community
+      .filter(local)
       .filter(name.eq(community_name))
       .first::<Self>(conn)
   }
index 83f0559abe2906e3c8c300df89d4c1e367703199..4e368aa2fd1f7ec69f9990ae895a7e5d6454ec10 100644 (file)
@@ -144,11 +144,17 @@ impl User_ {
   }
 
   pub fn find_by_username(conn: &PgConnection, username: &str) -> Result<User_, Error> {
-    user_.filter(name.ilike(username)).first::<User_>(conn)
+    user_
+      .filter(local)
+      .filter(name.ilike(username))
+      .first::<User_>(conn)
   }
 
   pub fn find_by_email(conn: &PgConnection, from_email: &str) -> Result<User_, Error> {
-    user_.filter(email.eq(from_email)).first::<User_>(conn)
+    user_
+      .filter(local)
+      .filter(email.eq(from_email))
+      .first::<User_>(conn)
   }
 
   pub fn get_profile_url(&self, hostname: &str) -> String {