Federate user deletion (#551)
* Federate user deletion - When someone deletes their account - When a local user is banned Fixes #509 * cargo fmt
This commit is contained in:
parent
85aa0883c8
commit
787eb7f399
26
Cargo.lock
generated
26
Cargo.lock
generated
@ -1777,7 +1777,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "plume"
|
||||
version = "0.2.0"
|
||||
version = "0.3.0"
|
||||
dependencies = [
|
||||
"activitypub 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"askama_escape 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -1797,9 +1797,9 @@ dependencies = [
|
||||
"lettre_email 0.9.0 (git+https://github.com/lettre/lettre?rev=c988b1760ad8179d9e7f3fb8594d2b86cf2a0a49)",
|
||||
"multipart 0.16.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"num_cpus 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"plume-api 0.2.0",
|
||||
"plume-common 0.2.0",
|
||||
"plume-models 0.2.0",
|
||||
"plume-api 0.3.0",
|
||||
"plume-common 0.3.0",
|
||||
"plume-models 0.3.0",
|
||||
"rocket 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rocket_contrib 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rocket_csrf 0.1.0 (git+https://github.com/fdb-hiroshima/rocket_csrf?rev=4a72ea2ec716cb0b26188fb00bccf2ef7d1e031c)",
|
||||
@ -1819,7 +1819,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "plume-api"
|
||||
version = "0.2.0"
|
||||
version = "0.3.0"
|
||||
dependencies = [
|
||||
"canapi 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -1828,18 +1828,18 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "plume-cli"
|
||||
version = "0.2.0"
|
||||
version = "0.3.0"
|
||||
dependencies = [
|
||||
"clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"diesel 1.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"dotenv 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"plume-models 0.2.0",
|
||||
"plume-models 0.3.0",
|
||||
"rpassword 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "plume-common"
|
||||
version = "0.2.0"
|
||||
version = "0.3.0"
|
||||
dependencies = [
|
||||
"activitypub 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"activitystreams-derive 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -1861,7 +1861,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "plume-front"
|
||||
version = "0.1.0"
|
||||
version = "0.3.0"
|
||||
dependencies = [
|
||||
"gettext 0.3.0 (git+https://github.com/Plume-org/gettext/?rev=294c54d74c699fbc66502b480a37cc66c1daa7f3)",
|
||||
"gettext-macros 0.4.0 (git+https://github.com/Plume-org/gettext-macros/?rev=a7c605f7edd6bfbfbfe7778026bfefd88d82db10)",
|
||||
@ -1872,7 +1872,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "plume-models"
|
||||
version = "0.2.0"
|
||||
version = "0.3.0"
|
||||
dependencies = [
|
||||
"activitypub 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ammonia 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -1885,10 +1885,10 @@ dependencies = [
|
||||
"guid-create 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"openssl 0.10.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"plume-api 0.2.0",
|
||||
"plume-common 0.2.0",
|
||||
"plume-api 0.3.0",
|
||||
"plume-common 0.3.0",
|
||||
"reqwest 0.9.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rocket 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rocket_i18n 0.4.0 (git+https://github.com/Plume-org/rocket_i18n?rev=e922afa7c366038b3433278c03b1456b346074f2)",
|
||||
|
@ -53,6 +53,7 @@ pub fn inbox(ctx: &PlumeRocket, act: serde_json::Value) -> Result<InboxResult, E
|
||||
.with::<User, Create, Post>()
|
||||
.with::<User, Delete, Comment>()
|
||||
.with::<User, Delete, Post>()
|
||||
.with::<User, Delete, User>()
|
||||
.with::<User, Follow, User>()
|
||||
.with::<User, Like, Post>()
|
||||
.with::<User, Undo, Reshare>()
|
||||
@ -286,6 +287,34 @@ pub(crate) mod tests {
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn delete_user() {
|
||||
let r = rockets();
|
||||
let conn = &*r.conn;
|
||||
conn.test_transaction::<_, (), _>(|| {
|
||||
let (_, users, _) = fill_database(&r);
|
||||
|
||||
let fail_act = json!({
|
||||
"id": "https://plu.me/@/Admin#delete",
|
||||
"actor": users[1].ap_url, // Not the same account
|
||||
"object": users[0].ap_url,
|
||||
"type": "Delete",
|
||||
});
|
||||
assert!(super::inbox(&r, fail_act).is_err());
|
||||
|
||||
let ok_act = json!({
|
||||
"id": "https://plu.me/@/Admin#delete",
|
||||
"actor": users[0].ap_url,
|
||||
"object": users[0].ap_url,
|
||||
"type": "Delete",
|
||||
});
|
||||
assert!(super::inbox(&r, ok_act).is_ok());
|
||||
assert!(crate::users::User::get(conn, users[0].id).is_err());
|
||||
|
||||
Ok(())
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn follow() {
|
||||
let r = rockets();
|
||||
|
@ -1,5 +1,9 @@
|
||||
use activitypub::{
|
||||
actor::Person, collection::OrderedCollection, object::Image, Activity, CustomObject, Endpoint,
|
||||
activity::Delete,
|
||||
actor::Person,
|
||||
collection::OrderedCollection,
|
||||
object::{Image, Tombstone},
|
||||
Activity, CustomObject, Endpoint,
|
||||
};
|
||||
use bcrypt;
|
||||
use chrono::{NaiveDateTime, Utc};
|
||||
@ -12,9 +16,9 @@ use openssl::{
|
||||
};
|
||||
use plume_common::activity_pub::{
|
||||
ap_accept_header,
|
||||
inbox::{AsActor, FromId},
|
||||
inbox::{AsActor, AsObject, FromId},
|
||||
sign::{gen_keypair, Signer},
|
||||
ActivityStream, ApSignature, Id, IntoId, PublicKey,
|
||||
ActivityStream, ApSignature, Id, IntoId, PublicKey, PUBLIC_VISIBILITY,
|
||||
};
|
||||
use plume_common::utils;
|
||||
use reqwest::{
|
||||
@ -632,6 +636,29 @@ impl User {
|
||||
Ok(CustomPerson::new(actor, ap_signature))
|
||||
}
|
||||
|
||||
pub fn delete_activity(&self, conn: &Connection) -> Result<Delete> {
|
||||
let mut del = Delete::default();
|
||||
|
||||
let mut tombstone = Tombstone::default();
|
||||
tombstone.object_props.set_id_string(self.ap_url.clone())?;
|
||||
|
||||
del.delete_props
|
||||
.set_actor_link(Id::new(self.ap_url.clone()))?;
|
||||
del.delete_props.set_object_object(tombstone)?;
|
||||
del.object_props
|
||||
.set_id_string(format!("{}#delete", self.ap_url))?;
|
||||
del.object_props
|
||||
.set_to_link_vec(vec![Id::new(PUBLIC_VISIBILITY)])?;
|
||||
del.object_props.set_cc_link_vec(
|
||||
self.get_followers(conn)?
|
||||
.into_iter()
|
||||
.map(|f| Id::new(f.ap_url))
|
||||
.collect(),
|
||||
)?;
|
||||
|
||||
Ok(del)
|
||||
}
|
||||
|
||||
pub fn avatar_url(&self, conn: &Connection) -> String {
|
||||
self.avatar_id
|
||||
.and_then(|id| Media::get(conn, id).and_then(|m| m.url(conn)).ok())
|
||||
@ -832,6 +859,19 @@ impl AsActor<&PlumeRocket> for User {
|
||||
}
|
||||
}
|
||||
|
||||
impl AsObject<User, Delete, &PlumeRocket> for User {
|
||||
type Error = Error;
|
||||
type Output = ();
|
||||
|
||||
fn activity(self, c: &PlumeRocket, actor: User, _id: &str) -> Result<()> {
|
||||
if self.id == actor.id {
|
||||
self.delete(&c.conn, &c.searcher).map(|_| ())
|
||||
} else {
|
||||
Err(Error::Unauthorized)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Signer for User {
|
||||
type Error = Error;
|
||||
|
||||
|
@ -265,10 +265,10 @@ msgid "Follow {}"
|
||||
msgstr "اتبع"
|
||||
|
||||
#, fuzzy
|
||||
msgid "Login to follow"
|
||||
msgid "Log in to follow"
|
||||
msgstr "قم بتسجيل الدخول قصد مشاركته"
|
||||
|
||||
msgid "Enter your full username to follow"
|
||||
msgid "Enter your full username handle to follow"
|
||||
msgstr ""
|
||||
|
||||
msgid "Edit your account"
|
||||
|
@ -262,10 +262,10 @@ msgstr "Писти Pluma {0}"
|
||||
msgid "Follow {}"
|
||||
msgstr ""
|
||||
|
||||
msgid "Login to follow"
|
||||
msgid "Log in to follow"
|
||||
msgstr ""
|
||||
|
||||
msgid "Enter your full username to follow"
|
||||
msgid "Enter your full username handle to follow"
|
||||
msgstr ""
|
||||
|
||||
msgid "Edit your account"
|
||||
|
@ -262,10 +262,10 @@ msgstr ""
|
||||
msgid "Follow {}"
|
||||
msgstr ""
|
||||
|
||||
msgid "Login to follow"
|
||||
msgid "Log in to follow"
|
||||
msgstr ""
|
||||
|
||||
msgid "Enter your full username to follow"
|
||||
msgid "Enter your full username handle to follow"
|
||||
msgstr ""
|
||||
|
||||
msgid "Edit your account"
|
||||
|
@ -264,10 +264,12 @@ msgstr "Beží na Plume {0}"
|
||||
msgid "Follow {}"
|
||||
msgstr "Následovat {}"
|
||||
|
||||
msgid "Login to follow"
|
||||
#, fuzzy
|
||||
msgid "Log in to follow"
|
||||
msgstr "Pro následování se přihlášte"
|
||||
|
||||
msgid "Enter your full username to follow"
|
||||
#, fuzzy
|
||||
msgid "Enter your full username handle to follow"
|
||||
msgstr "Pro následovaní zadejte své úplné uživatelské jméno"
|
||||
|
||||
msgid "Edit your account"
|
||||
|
@ -264,10 +264,10 @@ msgid "Follow {}"
|
||||
msgstr "Folgen"
|
||||
|
||||
#, fuzzy
|
||||
msgid "Login to follow"
|
||||
msgid "Log in to follow"
|
||||
msgstr "Um zu boosten, musst du eingeloggt sein"
|
||||
|
||||
msgid "Enter your full username to follow"
|
||||
msgid "Enter your full username handle to follow"
|
||||
msgstr ""
|
||||
|
||||
msgid "Edit your account"
|
||||
|
@ -262,10 +262,10 @@ msgstr ""
|
||||
msgid "Follow {}"
|
||||
msgstr ""
|
||||
|
||||
msgid "Login to follow"
|
||||
msgid "Log in to follow"
|
||||
msgstr ""
|
||||
|
||||
msgid "Enter your full username to follow"
|
||||
msgid "Enter your full username handle to follow"
|
||||
msgstr ""
|
||||
|
||||
msgid "Edit your account"
|
||||
|
@ -262,10 +262,10 @@ msgstr ""
|
||||
msgid "Follow {}"
|
||||
msgstr ""
|
||||
|
||||
msgid "Login to follow"
|
||||
msgid "Log in to follow"
|
||||
msgstr ""
|
||||
|
||||
msgid "Enter your full username to follow"
|
||||
msgid "Enter your full username handle to follow"
|
||||
msgstr ""
|
||||
|
||||
msgid "Edit your account"
|
||||
|
@ -264,10 +264,10 @@ msgid "Follow {}"
|
||||
msgstr "Seguir"
|
||||
|
||||
#, fuzzy
|
||||
msgid "Login to follow"
|
||||
msgid "Log in to follow"
|
||||
msgstr "Dejar de seguir"
|
||||
|
||||
msgid "Enter your full username to follow"
|
||||
msgid "Enter your full username handle to follow"
|
||||
msgstr ""
|
||||
|
||||
msgid "Edit your account"
|
||||
|
@ -265,10 +265,10 @@ msgid "Follow {}"
|
||||
msgstr "S’abonner"
|
||||
|
||||
#, fuzzy
|
||||
msgid "Login to follow"
|
||||
msgid "Log in to follow"
|
||||
msgstr "Connectez-vous pour partager"
|
||||
|
||||
msgid "Enter your full username to follow"
|
||||
msgid "Enter your full username handle to follow"
|
||||
msgstr ""
|
||||
|
||||
msgid "Edit your account"
|
||||
|
@ -265,10 +265,10 @@ msgid "Follow {}"
|
||||
msgstr "Seguir"
|
||||
|
||||
#, fuzzy
|
||||
msgid "Login to follow"
|
||||
msgid "Log in to follow"
|
||||
msgstr "Conéctese para promover"
|
||||
|
||||
msgid "Enter your full username to follow"
|
||||
msgid "Enter your full username handle to follow"
|
||||
msgstr ""
|
||||
|
||||
msgid "Edit your account"
|
||||
|
@ -264,10 +264,10 @@ msgstr "Plume {0} का इस्तेमाल कर रहे हैं"
|
||||
msgid "Follow {}"
|
||||
msgstr ""
|
||||
|
||||
msgid "Login to follow"
|
||||
msgid "Log in to follow"
|
||||
msgstr ""
|
||||
|
||||
msgid "Enter your full username to follow"
|
||||
msgid "Enter your full username handle to follow"
|
||||
msgstr ""
|
||||
|
||||
msgid "Edit your account"
|
||||
|
@ -263,10 +263,10 @@ msgstr ""
|
||||
msgid "Follow {}"
|
||||
msgstr ""
|
||||
|
||||
msgid "Login to follow"
|
||||
msgid "Log in to follow"
|
||||
msgstr ""
|
||||
|
||||
msgid "Enter your full username to follow"
|
||||
msgid "Enter your full username handle to follow"
|
||||
msgstr ""
|
||||
|
||||
msgid "Edit your account"
|
||||
|
@ -264,10 +264,10 @@ msgid "Follow {}"
|
||||
msgstr "Segui"
|
||||
|
||||
#, fuzzy
|
||||
msgid "Login to follow"
|
||||
msgid "Log in to follow"
|
||||
msgstr "Accedi per boostare"
|
||||
|
||||
msgid "Enter your full username to follow"
|
||||
msgid "Enter your full username handle to follow"
|
||||
msgstr ""
|
||||
|
||||
msgid "Edit your account"
|
||||
|
@ -267,10 +267,10 @@ msgid "Follow {}"
|
||||
msgstr "フォロー"
|
||||
|
||||
#, fuzzy
|
||||
msgid "Login to follow"
|
||||
msgid "Log in to follow"
|
||||
msgstr "ブーストするにはログインしてください"
|
||||
|
||||
msgid "Enter your full username to follow"
|
||||
msgid "Enter your full username handle to follow"
|
||||
msgstr ""
|
||||
|
||||
msgid "Edit your account"
|
||||
|
@ -274,10 +274,10 @@ msgid "Follow {}"
|
||||
msgstr "Følg"
|
||||
|
||||
#, fuzzy
|
||||
msgid "Login to follow"
|
||||
msgid "Log in to follow"
|
||||
msgstr "Logg inn"
|
||||
|
||||
msgid "Enter your full username to follow"
|
||||
msgid "Enter your full username handle to follow"
|
||||
msgstr ""
|
||||
|
||||
msgid "Edit your account"
|
||||
|
@ -264,10 +264,11 @@ msgstr "Działa na Plume {0}"
|
||||
msgid "Follow {}"
|
||||
msgstr "Obserwuj {}"
|
||||
|
||||
msgid "Login to follow"
|
||||
msgid "Log in to follow"
|
||||
msgstr ""
|
||||
|
||||
msgid "Enter your full username to follow"
|
||||
#, fuzzy
|
||||
msgid "Enter your full username handle to follow"
|
||||
msgstr "Wpisz swoją pełną nazwę użytkownika, do naśladowania"
|
||||
|
||||
msgid "Edit your account"
|
||||
|
@ -256,10 +256,10 @@ msgstr ""
|
||||
msgid "Follow {}"
|
||||
msgstr ""
|
||||
|
||||
msgid "Login to follow"
|
||||
msgid "Log in to follow"
|
||||
msgstr ""
|
||||
|
||||
msgid "Enter your full username to follow"
|
||||
msgid "Enter your full username handle to follow"
|
||||
msgstr ""
|
||||
|
||||
msgid "Edit your account"
|
||||
|
@ -266,10 +266,10 @@ msgid "Follow {}"
|
||||
msgstr "Seguir"
|
||||
|
||||
#, fuzzy
|
||||
msgid "Login to follow"
|
||||
msgid "Log in to follow"
|
||||
msgstr "Entrar para gostar"
|
||||
|
||||
msgid "Enter your full username to follow"
|
||||
msgid "Enter your full username handle to follow"
|
||||
msgstr ""
|
||||
|
||||
msgid "Edit your account"
|
||||
|
@ -263,10 +263,10 @@ msgstr ""
|
||||
msgid "Follow {}"
|
||||
msgstr ""
|
||||
|
||||
msgid "Login to follow"
|
||||
msgid "Log in to follow"
|
||||
msgstr ""
|
||||
|
||||
msgid "Enter your full username to follow"
|
||||
msgid "Enter your full username handle to follow"
|
||||
msgstr ""
|
||||
|
||||
msgid "Edit your account"
|
||||
|
@ -266,10 +266,10 @@ msgid "Follow {}"
|
||||
msgstr "Подписаться"
|
||||
|
||||
#, fuzzy
|
||||
msgid "Login to follow"
|
||||
msgid "Log in to follow"
|
||||
msgstr "Войдите, чтобы продвигать посты"
|
||||
|
||||
msgid "Enter your full username to follow"
|
||||
msgid "Enter your full username handle to follow"
|
||||
msgstr ""
|
||||
|
||||
msgid "Edit your account"
|
||||
|
@ -264,10 +264,12 @@ msgstr "Beží na Plume {0}"
|
||||
msgid "Follow {}"
|
||||
msgstr "Následuj {}"
|
||||
|
||||
msgid "Login to follow"
|
||||
#, fuzzy
|
||||
msgid "Log in to follow"
|
||||
msgstr "Pre následovanie sa prihlás"
|
||||
|
||||
msgid "Enter your full username to follow"
|
||||
#, fuzzy
|
||||
msgid "Enter your full username handle to follow"
|
||||
msgstr "Zadaj svoju prezývku v úplnosti, aby si následoval/a"
|
||||
|
||||
msgid "Edit your account"
|
||||
|
@ -263,10 +263,10 @@ msgstr ""
|
||||
msgid "Follow {}"
|
||||
msgstr ""
|
||||
|
||||
msgid "Login to follow"
|
||||
msgid "Log in to follow"
|
||||
msgstr ""
|
||||
|
||||
msgid "Enter your full username to follow"
|
||||
msgid "Enter your full username handle to follow"
|
||||
msgstr ""
|
||||
|
||||
msgid "Edit your account"
|
||||
|
@ -262,10 +262,10 @@ msgstr ""
|
||||
msgid "Follow {}"
|
||||
msgstr ""
|
||||
|
||||
msgid "Login to follow"
|
||||
msgid "Log in to follow"
|
||||
msgstr ""
|
||||
|
||||
msgid "Enter your full username to follow"
|
||||
msgid "Enter your full username handle to follow"
|
||||
msgstr ""
|
||||
|
||||
msgid "Edit your account"
|
||||
|
@ -8,14 +8,13 @@ use serde_json;
|
||||
use validator::{Validate, ValidationErrors};
|
||||
|
||||
use inbox;
|
||||
use plume_common::activity_pub::inbox::FromId;
|
||||
use plume_common::activity_pub::{broadcast, inbox::FromId};
|
||||
use plume_models::{
|
||||
admin::Admin, comments::Comment, db_conn::DbConn, headers::Headers, instance::*, posts::Post,
|
||||
safe_string::SafeString, users::User, Error, PlumeRocket, CONFIG,
|
||||
};
|
||||
use routes::{errors::ErrorPage, rocket_uri_macro_static_files, Page};
|
||||
use template_utils::Ructe;
|
||||
use Searcher;
|
||||
|
||||
#[get("/")]
|
||||
pub fn index(conn: DbConn, user: Option<User>, intl: I18n) -> Result<Ructe, ErrorPage> {
|
||||
@ -197,14 +196,20 @@ pub fn admin_users(
|
||||
}
|
||||
|
||||
#[post("/admin/users/<id>/ban")]
|
||||
pub fn ban(
|
||||
_admin: Admin,
|
||||
conn: DbConn,
|
||||
id: i32,
|
||||
searcher: Searcher,
|
||||
) -> Result<Redirect, ErrorPage> {
|
||||
if let Ok(u) = User::get(&*conn, id) {
|
||||
u.delete(&*conn, &searcher)?;
|
||||
pub fn ban(_admin: Admin, id: i32, rockets: PlumeRocket) -> Result<Redirect, ErrorPage> {
|
||||
if let Ok(u) = User::get(&*rockets.conn, id) {
|
||||
u.delete(&*rockets.conn, &rockets.searcher)?;
|
||||
|
||||
if Instance::get_local(&*rockets.conn)
|
||||
.map(|i| u.instance_id == i.id)
|
||||
.unwrap_or(false)
|
||||
{
|
||||
let target = User::one_by_instance(&*rockets.conn)?;
|
||||
let delete_act = u.delete_activity(&*rockets.conn)?;
|
||||
rockets
|
||||
.worker
|
||||
.execute(move || broadcast(&u, delete_act, target));
|
||||
}
|
||||
}
|
||||
Ok(Redirect::to(uri!(admin_users: page = _)))
|
||||
}
|
||||
|
@ -394,6 +394,12 @@ pub fn delete(
|
||||
if user.id == account.id {
|
||||
account.delete(&*rockets.conn, &rockets.searcher)?;
|
||||
|
||||
let target = User::one_by_instance(&*rockets.conn)?;
|
||||
let delete_act = account.delete_activity(&*rockets.conn)?;
|
||||
rockets
|
||||
.worker
|
||||
.execute(move || broadcast(&account, delete_act, target));
|
||||
|
||||
if let Some(cookie) = cookies.get_private(AUTH_COOKIE) {
|
||||
cookies.remove_private(cookie);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user