Merge branch 'main' into move-websocket-to-workspace
This commit is contained in:
commit
bca55ff775
39 changed files with 372 additions and 98 deletions
2
.github/ISSUE_TEMPLATE/BUG_REPORT.md
vendored
2
.github/ISSUE_TEMPLATE/BUG_REPORT.md
vendored
|
@ -9,6 +9,8 @@ assignees: ''
|
|||
|
||||
Found a bug? Please fill out the sections below. 👍
|
||||
|
||||
For front end issues, use [lemmy-ui](https://github.com/LemmyNet/lemmy-ui)
|
||||
|
||||
### Issue Summary
|
||||
|
||||
A summary of the bug.
|
||||
|
|
2
.github/ISSUE_TEMPLATE/FEATURE_REQUEST.md
vendored
2
.github/ISSUE_TEMPLATE/FEATURE_REQUEST.md
vendored
|
@ -7,6 +7,8 @@ assignees: ''
|
|||
|
||||
---
|
||||
|
||||
For front end issues, use [lemmy-ui](https://github.com/LemmyNet/lemmy-ui)
|
||||
|
||||
### Is your proposal related to a problem?
|
||||
|
||||
<!--
|
||||
|
|
|
@ -20,7 +20,7 @@ before_install:
|
|||
# Change dir
|
||||
- cd docker/travis
|
||||
script:
|
||||
- "./run-tests.sh"
|
||||
- "./run-tests.bash"
|
||||
deploy:
|
||||
provider: script
|
||||
script: bash docker_push.sh
|
||||
|
|
98
Cargo.lock
generated
98
Cargo.lock
generated
|
@ -81,8 +81,11 @@ dependencies = [
|
|||
"futures-util",
|
||||
"http",
|
||||
"log",
|
||||
"rustls",
|
||||
"tokio-rustls",
|
||||
"trust-dns-proto",
|
||||
"trust-dns-resolver",
|
||||
"webpki",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -117,6 +120,7 @@ dependencies = [
|
|||
"actix-rt",
|
||||
"actix-service",
|
||||
"actix-threadpool",
|
||||
"actix-tls",
|
||||
"actix-utils",
|
||||
"base64 0.12.3",
|
||||
"bitflags 1.2.1",
|
||||
|
@ -150,7 +154,7 @@ dependencies = [
|
|||
"serde_urlencoded",
|
||||
"sha-1 0.9.1",
|
||||
"slab",
|
||||
"time 0.2.19",
|
||||
"time 0.2.20",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -260,6 +264,10 @@ dependencies = [
|
|||
"actix-service",
|
||||
"actix-utils",
|
||||
"futures-util",
|
||||
"rustls",
|
||||
"tokio-rustls",
|
||||
"webpki",
|
||||
"webpki-roots",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -312,11 +320,12 @@ dependencies = [
|
|||
"mime",
|
||||
"pin-project",
|
||||
"regex",
|
||||
"rustls",
|
||||
"serde 1.0.116",
|
||||
"serde_json",
|
||||
"serde_urlencoded",
|
||||
"socket2",
|
||||
"time 0.2.19",
|
||||
"time 0.2.20",
|
||||
"tinyvec",
|
||||
"url",
|
||||
]
|
||||
|
@ -483,6 +492,7 @@ dependencies = [
|
|||
"mime",
|
||||
"percent-encoding",
|
||||
"rand 0.7.3",
|
||||
"rustls",
|
||||
"serde 1.0.116",
|
||||
"serde_json",
|
||||
"serde_urlencoded",
|
||||
|
@ -769,9 +779,9 @@ checksum = "7b02b629252fe8ef6460461409564e2c21d0c8e77e0944f3d189ff06c4e932ad"
|
|||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.0.59"
|
||||
version = "1.0.60"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "66120af515773fb005778dc07c261bd201ec8ce50bd6e7144c927753fe013381"
|
||||
checksum = "ef611cc68ff783f18535d77ddd080185275713d852c4f5cbb6122c462a7a825c"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
|
@ -874,7 +884,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "1373a16a4937bc34efec7b391f9c1500c30b8478a701a4f44c9165cc0475a6e0"
|
||||
dependencies = [
|
||||
"percent-encoding",
|
||||
"time 0.2.19",
|
||||
"time 0.2.20",
|
||||
"version_check 0.9.2",
|
||||
]
|
||||
|
||||
|
@ -1111,9 +1121,9 @@ checksum = "134951f4028bdadb9b84baf4232681efbf277da25144b9b0ad65df75946c422b"
|
|||
|
||||
[[package]]
|
||||
name = "either"
|
||||
version = "1.6.0"
|
||||
version = "1.6.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cd56b59865bce947ac5958779cfa508f6c3b9497cc762b7e24a12d11ccde2c4f"
|
||||
checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457"
|
||||
|
||||
[[package]]
|
||||
name = "email"
|
||||
|
@ -1588,6 +1598,12 @@ version = "1.3.4"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cd179ae861f0c2e53da70d892f5f3029f9594be0c41dc5269cd371691b1dc2f9"
|
||||
|
||||
[[package]]
|
||||
name = "httpdate"
|
||||
version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "494b4d60369511e7dea41cf646832512a94e542f68bb9c49e54518e0f468eb47"
|
||||
|
||||
[[package]]
|
||||
name = "humantime"
|
||||
version = "1.3.0"
|
||||
|
@ -1599,9 +1615,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "hyper"
|
||||
version = "0.13.7"
|
||||
version = "0.13.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3e68a8dd9716185d9e64ea473ea6ef63529252e3e27623295a0378a19665d5eb"
|
||||
checksum = "2f3afcfae8af5ad0576a31e768415edb627824129e8e5a29b8bfccb2f234e835"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"futures-channel",
|
||||
|
@ -1611,10 +1627,10 @@ dependencies = [
|
|||
"http",
|
||||
"http-body",
|
||||
"httparse",
|
||||
"httpdate",
|
||||
"itoa",
|
||||
"pin-project",
|
||||
"socket2",
|
||||
"time 0.1.44",
|
||||
"tokio",
|
||||
"tower-service",
|
||||
"tracing",
|
||||
|
@ -2825,9 +2841,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "rayon-core"
|
||||
version = "1.8.0"
|
||||
version = "1.8.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "91739a34c4355b5434ce54c9086c5895604a9c278586d1f1aa95e04f66b525a0"
|
||||
checksum = "e8c4fec834fb6e6d2dd5eece3c7b432a52f0ba887cf40e595190c4107edc08bf"
|
||||
dependencies = [
|
||||
"crossbeam-channel",
|
||||
"crossbeam-deque",
|
||||
|
@ -2973,6 +2989,19 @@ dependencies = [
|
|||
"semver",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustls"
|
||||
version = "0.18.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5d1126dcf58e93cee7d098dbda643b5f92ed724f1f6a63007c1116eed6700c81"
|
||||
dependencies = [
|
||||
"base64 0.12.3",
|
||||
"log",
|
||||
"ring",
|
||||
"sct",
|
||||
"webpki",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ryu"
|
||||
version = "1.0.5"
|
||||
|
@ -3016,6 +3045,16 @@ version = "1.1.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
|
||||
|
||||
[[package]]
|
||||
name = "sct"
|
||||
version = "0.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e3042af939fca8c3453b7af0f1c66e533a15a86169e39de2657310ade8f98d3c"
|
||||
dependencies = [
|
||||
"ring",
|
||||
"untrusted",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "security-framework"
|
||||
version = "0.4.4"
|
||||
|
@ -3415,9 +3454,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "time"
|
||||
version = "0.2.19"
|
||||
version = "0.2.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "80c1a1fd93112fc50b11c43a1def21f926be3c18884fad676ea879572da070a1"
|
||||
checksum = "0d4953c513c9bf1b97e9cdd83f11d60c4b0a83462880a360d80d96953a953fee"
|
||||
dependencies = [
|
||||
"const_fn",
|
||||
"libc",
|
||||
|
@ -3478,6 +3517,18 @@ dependencies = [
|
|||
"winapi 0.3.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio-rustls"
|
||||
version = "0.14.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e12831b255bcfa39dc0436b01e19fea231a37db570686c06ee72c423479f889a"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"rustls",
|
||||
"tokio",
|
||||
"webpki",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio-tls"
|
||||
version = "0.3.1"
|
||||
|
@ -3853,6 +3904,25 @@ dependencies = [
|
|||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "webpki"
|
||||
version = "0.21.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ab146130f5f790d45f82aeeb09e55a256573373ec64409fc19a6fb82fb1032ae"
|
||||
dependencies = [
|
||||
"ring",
|
||||
"untrusted",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "webpki-roots"
|
||||
version = "0.20.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0f20dea7535251981a9670857150d571846545088359b28e4951d350bdaf179f"
|
||||
dependencies = [
|
||||
"webpki",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "widestring"
|
||||
version = "0.4.2"
|
||||
|
|
|
@ -32,7 +32,7 @@ chrono = { version = "0.4", features = ["serde"] }
|
|||
serde_json = { version = "1.0", features = ["preserve_order"]}
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
actix = "0.10"
|
||||
actix-web = { version = "3.0", default-features = false }
|
||||
actix-web = { version = "3.0", default-features = false, features = ["rustls"] }
|
||||
actix-files = { version = "0.3", default-features = false }
|
||||
actix-web-actors = { version = "3.0", default-features = false }
|
||||
actix-rt = { version = "1.1", default-features = false }
|
||||
|
|
|
@ -1 +1 @@
|
|||
v0.7.57
|
||||
v0.7.59
|
||||
|
|
|
@ -51,17 +51,27 @@ server {
|
|||
# Upload limit for pictrs
|
||||
client_max_body_size 20M;
|
||||
|
||||
# lemmy api
|
||||
location /api/v1 {
|
||||
proxy_pass http://0.0.0.0:8536/api/v1;
|
||||
# frontend
|
||||
location / {
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
|
||||
# Cuts off the trailing slash on URLs to make them valid
|
||||
rewrite ^(.+)/+$ $1 permanent;
|
||||
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 }}";
|
||||
}
|
||||
if ($request_method = POST) {
|
||||
set $proxpass "http://0.0.0.0:{{ lemmy_port }}";
|
||||
}
|
||||
proxy_pass $proxpass;
|
||||
|
||||
# WebSocket support
|
||||
rewrite ^(.+)/+$ $1 permanent;
|
||||
}
|
||||
|
||||
# backend
|
||||
location ~ ^/(api|docs|pictrs|feeds|nodeinfo|.well-known) {
|
||||
proxy_pass http://0.0.0.0:{{ lemmy_port }};
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "upgrade";
|
||||
|
@ -70,36 +80,12 @@ server {
|
|||
limit_req zone=lemmy_ratelimit burst=30 nodelay;
|
||||
}
|
||||
|
||||
# Docs
|
||||
location /docs {
|
||||
proxy_pass http://0.0.0.0:8536/docs;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
}
|
||||
|
||||
# lemmy-ui
|
||||
location / {
|
||||
proxy_pass http://0.0.0.0:1235;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
}
|
||||
|
||||
|
||||
# Redirect pictshare images to pictrs
|
||||
location ~ /pictshare/(.*)$ {
|
||||
return 301 /pictrs/image/$1;
|
||||
}
|
||||
|
||||
# Separate location block to disable rate limiting for images
|
||||
location /pictrs {
|
||||
proxy_pass http://0.0.0.0:8536/pictrs;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
}
|
||||
|
||||
location /iframely/ {
|
||||
proxy_pass http://0.0.0.0:8061/;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
|
|
|
@ -25,6 +25,7 @@ function assertUserFederation(
|
|||
expect(userOne.actor_id).toBe(userTwo.actor_id);
|
||||
expect(userOne.avatar).toBe(userTwo.avatar);
|
||||
expect(userOne.banner).toBe(userTwo.banner);
|
||||
expect(userOne.published).toBe(userTwo.published);
|
||||
}
|
||||
|
||||
test('Create user', async () => {
|
||||
|
|
|
@ -1,18 +1,14 @@
|
|||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
BRANCH=$1
|
||||
|
||||
git checkout $BRANCH
|
||||
|
||||
export COMPOSE_DOCKER_CLI_BUILD=1
|
||||
export DOCKER_BUILDKIT=1
|
||||
|
||||
# Rebuilding dev docker
|
||||
sudo docker build ../../ -f . -t "dessalines/lemmy:$BRANCH"
|
||||
sudo docker push "dessalines/lemmy:$BRANCH"
|
||||
sudo docker build ../../ -f . -t "dessalines/lemmy:dev"
|
||||
sudo docker push "dessalines/lemmy:dev"
|
||||
|
||||
# Run the playbook
|
||||
pushd ../../../lemmy-ansible
|
||||
ansible-playbook -i test playbooks/site.yml
|
||||
popd
|
||||
# pushd ../../../lemmy-ansible
|
||||
# ansible-playbook -i test playbooks/site.yml
|
||||
# popd
|
||||
|
|
|
@ -2,10 +2,6 @@
|
|||
set -e
|
||||
git checkout main
|
||||
|
||||
# Import translations
|
||||
git fetch weblate
|
||||
git merge weblate/main
|
||||
|
||||
# Creating the new tag
|
||||
new_tag="$1"
|
||||
third_semver=$(echo $new_tag | cut -d "." -f 3)
|
||||
|
|
|
@ -12,7 +12,7 @@ services:
|
|||
restart: always
|
||||
|
||||
lemmy:
|
||||
image: dessalines/lemmy:v0.7.57
|
||||
image: dessalines/lemmy:v0.7.59
|
||||
ports:
|
||||
- "127.0.0.1:8536:8536"
|
||||
restart: always
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#!/bin/sh
|
||||
echo "$DOCKER_PASSWORD" | docker login -u "$DOCKER_USERNAME" --password-stdin
|
||||
docker tag dessalines/lemmy:travis \
|
||||
dessalines/lemmy:v0.7.57
|
||||
docker push dessalines/lemmy:v0.7.57
|
||||
dessalines/lemmy:v0.7.59
|
||||
docker push dessalines/lemmy:v0.7.59
|
||||
|
|
|
@ -1,10 +1,16 @@
|
|||
# Docker Development
|
||||
|
||||
## Dependencies (on Ubuntu)
|
||||
|
||||
```bash
|
||||
sudo apt install git docker-compose
|
||||
sudo systemctl start docker
|
||||
git clone https://github.com/LemmyNet/lemmy
|
||||
```
|
||||
|
||||
## Running
|
||||
|
||||
```bash
|
||||
sudo apt install git docker-compose
|
||||
git clone https://github.com/LemmyNet/lemmy
|
||||
cd lemmy/docker/dev
|
||||
sudo docker-compose up --no-deps --build
|
||||
```
|
||||
|
|
|
@ -1,21 +1,9 @@
|
|||
# Federation Development
|
||||
|
||||
## Setup
|
||||
|
||||
If you don't have a local clone of the Lemmy repo yet, just run the following command:
|
||||
|
||||
```bash
|
||||
git clone https://github.com/LemmyNet/lemmy
|
||||
```
|
||||
|
||||
## Running locally
|
||||
|
||||
You need to have the following packages installed, the Docker service needs to be running.
|
||||
Install the dependencies as described in [Docker development](contributing_docker_development.md). Then run the following
|
||||
|
||||
- docker
|
||||
- docker-compose
|
||||
|
||||
Then run the following
|
||||
```bash
|
||||
cd docker/federation
|
||||
./start-local-instances.bash
|
||||
|
@ -40,15 +28,6 @@ To start federation between instances, visit one of them and search for a user,
|
|||
|
||||
Firefox containers are a good way to test them interacting.
|
||||
|
||||
## Integration tests
|
||||
|
||||
To run a suite of suite of federation integration tests:
|
||||
|
||||
```bash
|
||||
cd docker/federation
|
||||
./run-tests.bash
|
||||
```
|
||||
|
||||
## Running on a server
|
||||
|
||||
Note that federation is currently in alpha. **Only use it for testing**, not on any production server, and be aware that turning on federation may break your instance.
|
||||
|
|
|
@ -12,5 +12,9 @@ psql -U lemmy -c "DROP SCHEMA public CASCADE; CREATE SCHEMA public;"
|
|||
|
||||
### Federation
|
||||
|
||||
Install the [Docker development dependencies](contributing_docker_development.md), and execute
|
||||
`docker/federation-test/run-tests.sh`
|
||||
Install the [Docker development dependencies](contributing_docker_development.md), and execute:
|
||||
|
||||
```
|
||||
cd docker/federation
|
||||
./run-tests.bash
|
||||
```
|
||||
|
|
|
@ -488,15 +488,21 @@ impl Perform for FollowCommunity {
|
|||
return Err(APIError::err("community_follower_already_exists").into());
|
||||
}
|
||||
}
|
||||
// TODO: this needs to return a "pending" state, until Accept is received from the remote server
|
||||
|
||||
let community_id = data.community_id;
|
||||
let user_id = user.id;
|
||||
let community_view = blocking(context.pool(), move |conn| {
|
||||
let mut community_view = blocking(context.pool(), move |conn| {
|
||||
CommunityView::read(conn, community_id, Some(user_id))
|
||||
})
|
||||
.await??;
|
||||
|
||||
// TODO: this needs to return a "pending" state, until Accept is received from the remote server
|
||||
// For now, just assume that remote follows are accepted.
|
||||
// Otherwise, the subscribed will be null
|
||||
if !community.local {
|
||||
community_view.subscribed = Some(data.follow);
|
||||
}
|
||||
|
||||
Ok(CommunityResponse {
|
||||
community: community_view,
|
||||
})
|
||||
|
|
|
@ -167,6 +167,7 @@ impl Perform for Register {
|
|||
banner: None,
|
||||
password_encrypted: data.password.to_owned(),
|
||||
preferred_username: None,
|
||||
published: None,
|
||||
updated: None,
|
||||
admin: data.admin,
|
||||
banned: false,
|
||||
|
@ -401,6 +402,7 @@ impl Perform for SaveUserSettings {
|
|||
banner,
|
||||
password_encrypted,
|
||||
preferred_username,
|
||||
published: Some(read_user.published),
|
||||
updated: Some(naive_now()),
|
||||
admin: read_user.admin,
|
||||
banned: read_user.banned,
|
||||
|
|
|
@ -1 +1 @@
|
|||
pub const VERSION: &str = "v0.7.57";
|
||||
pub const VERSION: &str = "v0.7.59";
|
||||
|
|
|
@ -79,7 +79,6 @@ impl ActixJob for SendActivityTask {
|
|||
.post(to_url.as_str())
|
||||
.header("Content-Type", "application/json");
|
||||
|
||||
// TODO: i believe we have to do the signing in here because it is only valid for a few seconds
|
||||
let signed = sign(
|
||||
request,
|
||||
self.activity.clone(),
|
||||
|
|
|
@ -260,6 +260,7 @@ impl FromApub for UserForm {
|
|||
email: None,
|
||||
avatar,
|
||||
banner,
|
||||
published: person.inner.published().map(|u| u.to_owned().naive_local()),
|
||||
updated: person.updated().map(|u| u.to_owned().naive_local()),
|
||||
show_nsfw: false,
|
||||
theme: "".to_string(),
|
||||
|
|
|
@ -105,6 +105,7 @@ mod tests {
|
|||
banner: None,
|
||||
admin: false,
|
||||
banned: false,
|
||||
published: None,
|
||||
updated: None,
|
||||
show_nsfw: false,
|
||||
theme: "darkly".into(),
|
||||
|
|
|
@ -281,6 +281,7 @@ mod tests {
|
|||
banner: None,
|
||||
admin: false,
|
||||
banned: false,
|
||||
published: None,
|
||||
updated: None,
|
||||
show_nsfw: false,
|
||||
theme: "darkly".into(),
|
||||
|
|
|
@ -520,6 +520,7 @@ mod tests {
|
|||
banner: None,
|
||||
admin: false,
|
||||
banned: false,
|
||||
published: None,
|
||||
updated: None,
|
||||
show_nsfw: false,
|
||||
theme: "darkly".into(),
|
||||
|
|
|
@ -321,6 +321,7 @@ mod tests {
|
|||
banner: None,
|
||||
admin: false,
|
||||
banned: false,
|
||||
published: None,
|
||||
updated: None,
|
||||
show_nsfw: false,
|
||||
theme: "darkly".into(),
|
||||
|
|
|
@ -417,6 +417,7 @@ mod tests {
|
|||
banner: None,
|
||||
admin: false,
|
||||
banned: false,
|
||||
published: None,
|
||||
updated: None,
|
||||
show_nsfw: false,
|
||||
theme: "darkly".into(),
|
||||
|
@ -445,6 +446,7 @@ mod tests {
|
|||
banner: None,
|
||||
admin: false,
|
||||
banned: false,
|
||||
published: None,
|
||||
updated: None,
|
||||
show_nsfw: false,
|
||||
theme: "darkly".into(),
|
||||
|
|
|
@ -101,6 +101,7 @@ mod tests {
|
|||
banner: None,
|
||||
admin: false,
|
||||
banned: false,
|
||||
published: None,
|
||||
updated: None,
|
||||
show_nsfw: false,
|
||||
theme: "darkly".into(),
|
||||
|
|
|
@ -350,6 +350,7 @@ mod tests {
|
|||
banner: None,
|
||||
admin: false,
|
||||
banned: false,
|
||||
published: None,
|
||||
updated: None,
|
||||
show_nsfw: false,
|
||||
theme: "darkly".into(),
|
||||
|
|
|
@ -413,6 +413,7 @@ mod tests {
|
|||
matrix_user_id: None,
|
||||
avatar: None,
|
||||
banner: None,
|
||||
published: None,
|
||||
updated: None,
|
||||
admin: false,
|
||||
banned: false,
|
||||
|
|
|
@ -158,6 +158,7 @@ mod tests {
|
|||
banner: None,
|
||||
admin: false,
|
||||
banned: false,
|
||||
published: None,
|
||||
updated: None,
|
||||
show_nsfw: false,
|
||||
theme: "darkly".into(),
|
||||
|
@ -186,6 +187,7 @@ mod tests {
|
|||
banner: None,
|
||||
admin: false,
|
||||
banned: false,
|
||||
published: None,
|
||||
updated: None,
|
||||
show_nsfw: false,
|
||||
theme: "darkly".into(),
|
||||
|
|
|
@ -48,6 +48,7 @@ pub struct UserForm {
|
|||
pub banned: bool,
|
||||
pub email: Option<Option<String>>,
|
||||
pub avatar: Option<Option<String>>,
|
||||
pub published: Option<chrono::NaiveDateTime>,
|
||||
pub updated: Option<chrono::NaiveDateTime>,
|
||||
pub show_nsfw: bool,
|
||||
pub theme: String,
|
||||
|
@ -181,6 +182,7 @@ mod tests {
|
|||
banner: None,
|
||||
admin: false,
|
||||
banned: false,
|
||||
published: None,
|
||||
updated: None,
|
||||
show_nsfw: false,
|
||||
theme: "darkly".into(),
|
||||
|
|
|
@ -97,6 +97,7 @@ mod tests {
|
|||
banner: None,
|
||||
admin: false,
|
||||
banned: false,
|
||||
published: None,
|
||||
updated: None,
|
||||
show_nsfw: false,
|
||||
theme: "darkly".into(),
|
||||
|
@ -125,6 +126,7 @@ mod tests {
|
|||
banner: None,
|
||||
admin: false,
|
||||
banned: false,
|
||||
published: None,
|
||||
updated: None,
|
||||
show_nsfw: false,
|
||||
theme: "darkly".into(),
|
||||
|
|
|
@ -14,5 +14,5 @@ tokio = "0.2"
|
|||
strum = "0.19"
|
||||
strum_macros = "0.19"
|
||||
futures = "0.3.5"
|
||||
actix-web = { version = "3.0", default-features = false }
|
||||
actix-web = { version = "3.0", default-features = false, features = ["rustls"] }
|
||||
log = "0.4"
|
||||
|
|
|
@ -25,6 +25,6 @@ comrak = "0.8"
|
|||
lazy_static = "1.3"
|
||||
openssl = "0.10"
|
||||
url = { version = "2.1", features = ["serde"] }
|
||||
actix-web = {version = "3.0", default-features = false }
|
||||
actix-web = { version = "3.0", default-features = false, features = ["rustls"] }
|
||||
anyhow = "1.0"
|
||||
reqwest = { version = "0.10", features = ["json"] }
|
||||
|
|
|
@ -47,7 +47,7 @@ impl APIError {
|
|||
|
||||
#[derive(Debug)]
|
||||
pub struct LemmyError {
|
||||
inner: anyhow::Error,
|
||||
pub inner: anyhow::Error,
|
||||
}
|
||||
|
||||
impl<T> From<T> for LemmyError
|
||||
|
|
|
@ -54,6 +54,7 @@ fn user_updates_2020_04_02(conn: &PgConnection) -> Result<(), LemmyError> {
|
|||
banner: Some(cuser.banner.to_owned()),
|
||||
password_encrypted: cuser.password_encrypted.to_owned(),
|
||||
preferred_username: cuser.preferred_username.to_owned(),
|
||||
published: Some(cuser.published),
|
||||
updated: None,
|
||||
admin: cuser.admin,
|
||||
banned: cuser.banned,
|
||||
|
|
208
tests/integration_test.rs
Normal file
208
tests/integration_test.rs
Normal file
|
@ -0,0 +1,208 @@
|
|||
extern crate lemmy_server;
|
||||
|
||||
use activitystreams::{
|
||||
activity::{
|
||||
kind::{CreateType, FollowType},
|
||||
ActorAndObject,
|
||||
},
|
||||
base::{BaseExt, ExtendsExt},
|
||||
object::{Note, ObjectExt},
|
||||
};
|
||||
use actix::prelude::*;
|
||||
use actix_web::{test::TestRequest, web, web::Path, HttpRequest};
|
||||
use chrono::Utc;
|
||||
use diesel::{
|
||||
r2d2::{ConnectionManager, Pool},
|
||||
PgConnection,
|
||||
};
|
||||
use http_signature_normalization_actix::PrepareVerifyError;
|
||||
use lemmy_db::{
|
||||
community::{Community, CommunityForm},
|
||||
user::{User_, *},
|
||||
Crud,
|
||||
ListingType,
|
||||
SortType,
|
||||
};
|
||||
use lemmy_rate_limit::{rate_limiter::RateLimiter, RateLimit};
|
||||
use lemmy_server::{
|
||||
apub::{
|
||||
activity_queue::create_activity_queue,
|
||||
inbox::{
|
||||
community_inbox,
|
||||
community_inbox::community_inbox,
|
||||
shared_inbox,
|
||||
shared_inbox::shared_inbox,
|
||||
user_inbox,
|
||||
user_inbox::user_inbox,
|
||||
},
|
||||
},
|
||||
websocket::chat_server::ChatServer,
|
||||
LemmyContext,
|
||||
};
|
||||
use lemmy_utils::{apub::generate_actor_keypair, settings::Settings};
|
||||
use reqwest::Client;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::sync::Arc;
|
||||
use tokio::sync::Mutex;
|
||||
use url::Url;
|
||||
|
||||
fn create_context() -> LemmyContext {
|
||||
let settings = Settings::get();
|
||||
let db_url = settings.get_database_url();
|
||||
let manager = ConnectionManager::<PgConnection>::new(&db_url);
|
||||
let pool = Pool::builder()
|
||||
.max_size(settings.database.pool_size)
|
||||
.build(manager)
|
||||
.unwrap();
|
||||
let rate_limiter = RateLimit {
|
||||
rate_limiter: Arc::new(Mutex::new(RateLimiter::default())),
|
||||
};
|
||||
let activity_queue = create_activity_queue();
|
||||
let chat_server = ChatServer::startup(
|
||||
pool.clone(),
|
||||
rate_limiter.clone(),
|
||||
Client::default(),
|
||||
activity_queue.clone(),
|
||||
)
|
||||
.start();
|
||||
LemmyContext::new(
|
||||
pool,
|
||||
chat_server,
|
||||
Client::default(),
|
||||
create_activity_queue(),
|
||||
)
|
||||
}
|
||||
|
||||
fn create_user(conn: &PgConnection, name: &str) -> User_ {
|
||||
let user_keypair = generate_actor_keypair().unwrap();
|
||||
let new_user = UserForm {
|
||||
name: name.into(),
|
||||
preferred_username: None,
|
||||
password_encrypted: "nope".into(),
|
||||
email: None,
|
||||
matrix_user_id: None,
|
||||
avatar: None,
|
||||
banner: None,
|
||||
admin: false,
|
||||
banned: false,
|
||||
updated: None,
|
||||
show_nsfw: false,
|
||||
theme: "darkly".into(),
|
||||
default_sort_type: SortType::Hot as i16,
|
||||
default_listing_type: ListingType::Subscribed as i16,
|
||||
lang: "browser".into(),
|
||||
show_avatars: true,
|
||||
send_notifications_to_email: false,
|
||||
actor_id: Some(format!("http://localhost:8536/u/{}", name).to_string()),
|
||||
bio: None,
|
||||
local: true,
|
||||
private_key: Some(user_keypair.private_key),
|
||||
public_key: Some(user_keypair.public_key),
|
||||
last_refreshed_at: None,
|
||||
};
|
||||
|
||||
User_::create(&conn, &new_user).unwrap()
|
||||
}
|
||||
|
||||
fn create_community(conn: &PgConnection, creator_id: i32) -> Community {
|
||||
let new_community = CommunityForm {
|
||||
name: "test_community".into(),
|
||||
creator_id,
|
||||
title: "test_community".to_owned(),
|
||||
description: None,
|
||||
category_id: 1,
|
||||
nsfw: false,
|
||||
removed: None,
|
||||
deleted: None,
|
||||
updated: None,
|
||||
actor_id: None,
|
||||
local: true,
|
||||
private_key: None,
|
||||
public_key: None,
|
||||
last_refreshed_at: None,
|
||||
published: None,
|
||||
icon: None,
|
||||
banner: None,
|
||||
};
|
||||
Community::create(&conn, &new_community).unwrap()
|
||||
}
|
||||
fn create_activity<'a, Activity, Return>(user_id: String) -> web::Json<Return>
|
||||
where
|
||||
for<'de> Return: Deserialize<'de> + 'a,
|
||||
Activity: std::default::Default + Serialize,
|
||||
{
|
||||
let mut activity = ActorAndObject::<Activity>::new(user_id, Note::new().into_any_base().unwrap());
|
||||
activity
|
||||
.set_id(Url::parse("http://localhost:8536/create/1").unwrap())
|
||||
.set_many_ccs(vec![Url::parse("http://localhost:8536/c/main").unwrap()]);
|
||||
let activity = serde_json::to_value(&activity).unwrap();
|
||||
let activity: Return = serde_json::from_value(activity).unwrap();
|
||||
web::Json(activity)
|
||||
}
|
||||
|
||||
fn create_http_request() -> HttpRequest {
|
||||
let time1 = Utc::now().timestamp();
|
||||
let time2 = Utc::now().timestamp();
|
||||
let signature = format!(
|
||||
r#"keyId="my-key-id",algorithm="hs2019",created="{}",expires="{}",headers="(request-target) (created) (expires) date content-type",signature="blah blah blah""#,
|
||||
time1, time2
|
||||
);
|
||||
TestRequest::post()
|
||||
.uri("http://localhost:8536/")
|
||||
.header("Signature", signature)
|
||||
.to_http_request()
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn test_shared_inbox_expired_signature() {
|
||||
let request = create_http_request();
|
||||
let context = create_context();
|
||||
let connection = &context.pool().get().unwrap();
|
||||
let user = create_user(connection, "shared_inbox_rvgfd");
|
||||
let activity =
|
||||
create_activity::<CreateType, ActorAndObject<shared_inbox::ValidTypes>>(user.actor_id);
|
||||
let response = shared_inbox(request, activity, web::Data::new(context)).await;
|
||||
assert_eq!(
|
||||
format!("{}", response.err().unwrap()),
|
||||
format!("{}", PrepareVerifyError::Expired)
|
||||
);
|
||||
User_::delete(connection, user.id).unwrap();
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn test_user_inbox_expired_signature() {
|
||||
let request = create_http_request();
|
||||
let context = create_context();
|
||||
let connection = &context.pool().get().unwrap();
|
||||
let user = create_user(connection, "user_inbox_cgsax");
|
||||
let activity =
|
||||
create_activity::<CreateType, ActorAndObject<user_inbox::ValidTypes>>(user.actor_id);
|
||||
let path = Path::<String> {
|
||||
0: "username".to_string(),
|
||||
};
|
||||
let response = user_inbox(request, activity, path, web::Data::new(context)).await;
|
||||
assert_eq!(
|
||||
format!("{}", response.err().unwrap()),
|
||||
format!("{}", PrepareVerifyError::Expired)
|
||||
);
|
||||
User_::delete(connection, user.id).unwrap();
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn test_community_inbox_expired_signature() {
|
||||
let context = create_context();
|
||||
let connection = &context.pool().get().unwrap();
|
||||
let user = create_user(connection, "community_inbox_hrxa");
|
||||
let community = create_community(connection, user.id);
|
||||
let request = create_http_request();
|
||||
let activity =
|
||||
create_activity::<FollowType, ActorAndObject<community_inbox::ValidTypes>>(user.actor_id);
|
||||
let path = Path::<String> { 0: community.name };
|
||||
let response = community_inbox(request, activity, path, web::Data::new(context)).await;
|
||||
assert_eq!(
|
||||
format!("{}", response.err().unwrap()),
|
||||
format!("{}", PrepareVerifyError::Expired)
|
||||
);
|
||||
User_::delete(connection, user.id).unwrap();
|
||||
Community::delete(connection, community.id).unwrap();
|
||||
}
|
Loading…
Reference in a new issue