Run cargo clippy on whole project (#322)

* Run cargo clippy on plume-common

Run clippy on plume-common and adjuste code accordingly

* Run cargo clippy on plume-model

Run clippy on plume-model and adjuste code accordingly

* Reduce need for allocation in plume-common

* Reduce need for allocation in plume-model

add a quick compilation failure if no database backend is enabled

* Run cargo clippy on plume-cli

* Run cargo clippy on plume
This commit is contained in:
fdb-hiroshima
2018-11-26 10:21:52 +01:00
committed by GitHub
parent 8a4702df92
commit 74c398d60c
36 changed files with 577 additions and 810 deletions
+4 -4
View File
@@ -20,10 +20,10 @@ struct OAuthRequest {
#[get("/oauth2?<query>")]
fn oauth(query: OAuthRequest, conn: DbConn) -> Json<serde_json::Value> {
let app = App::find_by_client_id(&*conn, query.client_id).expect("OAuth request from unknown client");
let app = App::find_by_client_id(&*conn, &query.client_id).expect("OAuth request from unknown client");
if app.client_secret == query.client_secret {
if let Some(user) = User::find_local(&*conn, query.username) {
if user.auth(query.password) {
if let Some(user) = User::find_local(&*conn, &query.username) {
if user.auth(&query.password) {
let token = ApiToken::insert(&*conn, NewApiToken {
app_id: app.id,
user_id: user.id,
@@ -42,7 +42,7 @@ fn oauth(query: OAuthRequest, conn: DbConn) -> Json<serde_json::Value> {
// Making fake password verification to avoid different
// response times that would make it possible to know
// if a username is registered or not.
User::get(&*conn, 1).unwrap().auth(query.password);
User::get(&*conn, 1).unwrap().auth(&query.password);
Json(json!({
"error": "Invalid credentials"
}))
+9 -9
View File
@@ -48,11 +48,11 @@ pub trait Inbox {
"Delete" => {
let act: Delete = serde_json::from_value(act.clone())?;
Post::delete_id(
act.delete_props
&act.delete_props
.object_object::<Tombstone>()?
.object_props
.id_string()?,
actor_id.into(),
actor_id.as_ref(),
conn,
);
Ok(())
@@ -77,33 +77,33 @@ pub trait Inbox {
{
"Like" => {
likes::Like::delete_id(
act.undo_props
&act.undo_props
.object_object::<Like>()?
.object_props
.id_string()?,
actor_id.into(),
actor_id.as_ref(),
conn,
);
Ok(())
}
"Announce" => {
Reshare::delete_id(
act.undo_props
&act.undo_props
.object_object::<Announce>()?
.object_props
.id_string()?,
actor_id.into(),
actor_id.as_ref(),
conn,
);
Ok(())
}
"Follow" => {
Follow::delete_id(
act.undo_props
&act.undo_props
.object_object::<FollowAct>()?
.object_props
.id_string()?,
actor_id.into(),
actor_id.as_ref(),
conn,
);
Ok(())
@@ -113,7 +113,7 @@ pub trait Inbox {
}
"Update" => {
let act: Update = serde_json::from_value(act.clone())?;
Post::handle_update(conn, act.update_props.object_object()?);
Post::handle_update(conn, &act.update_props.object_object()?);
Ok(())
}
_ => Err(InboxError::InvalidType)?,
+14 -14
View File
@@ -24,7 +24,7 @@ use routes::Page;
#[get("/~/<name>?<page>", rank = 2)]
fn paginated_details(name: String, conn: DbConn, user: Option<User>, page: Page) -> Template {
may_fail!(user.map(|u| u.to_json(&*conn)), Blog::find_by_fqn(&*conn, name), "Requested blog couldn't be found", |blog| {
may_fail!(user.map(|u| u.to_json(&*conn)), Blog::find_by_fqn(&*conn, &name), "Requested blog couldn't be found", |blog| {
let posts = Post::blog_page(&*conn, &blog, page.limits());
let articles = Post::get_for_blog(&*conn, &blog);
let authors = &blog.list_authors(&*conn);
@@ -32,7 +32,7 @@ fn paginated_details(name: String, conn: DbConn, user: Option<User>, page: Page)
Template::render("blogs/details", json!({
"blog": &blog.to_json(&*conn),
"account": user.clone().map(|u| u.to_json(&*conn)),
"is_author": user.map(|x| x.is_author_in(&*conn, blog.clone())),
"is_author": user.map(|x| x.is_author_in(&*conn, &blog)),
"posts": posts.into_iter().map(|p| p.to_json(&*conn)).collect::<Vec<serde_json::Value>>(),
"authors": authors.into_iter().map(|u| u.to_json(&*conn)).collect::<Vec<serde_json::Value>>(),
"n_authors": authors.len(),
@@ -50,8 +50,8 @@ fn details(name: String, conn: DbConn, user: Option<User>) -> Template {
#[get("/~/<name>", rank = 1)]
fn activity_details(name: String, conn: DbConn, _ap: ApRequest) -> Option<ActivityStream<CustomGroup>> {
let blog = Blog::find_local(&*conn, name)?;
Some(ActivityStream::new(blog.into_activity(&*conn)))
let blog = Blog::find_local(&*conn, &name)?;
Some(ActivityStream::new(blog.to_activity(&*conn)))
}
#[get("/blogs/new")]
@@ -67,7 +67,7 @@ fn new(user: User, conn: DbConn) -> Template {
fn new_auth() -> Flash<Redirect>{
utils::requires_login(
"You need to be logged in order to create a new blog",
uri!(new).into()
uri!(new)
)
}
@@ -78,8 +78,8 @@ struct NewBlogForm {
}
fn valid_slug(title: &str) -> Result<(), ValidationError> {
let slug = utils::make_actor_id(title.to_string());
if slug.len() == 0 {
let slug = utils::make_actor_id(title);
if slug.is_empty() {
Err(ValidationError::new("empty_slug"))
} else {
Ok(())
@@ -89,13 +89,13 @@ fn valid_slug(title: &str) -> Result<(), ValidationError> {
#[post("/blogs/new", data = "<data>")]
fn create(conn: DbConn, data: LenientForm<NewBlogForm>, user: User) -> Result<Redirect, Template> {
let form = data.get();
let slug = utils::make_actor_id(form.title.to_string());
let slug = utils::make_actor_id(&form.title);
let mut errors = match form.validate() {
Ok(_) => ValidationErrors::new(),
Err(e) => e
};
if let Some(_) = Blog::find_local(&*conn, slug.clone()) {
if Blog::find_local(&*conn, &slug).is_some() {
errors.add("title", ValidationError {
code: Cow::from("existing_slug"),
message: Some(Cow::from("A blog with the same name already exists.")),
@@ -131,8 +131,8 @@ fn create(conn: DbConn, data: LenientForm<NewBlogForm>, user: User) -> Result<Re
#[post("/~/<name>/delete")]
fn delete(conn: DbConn, name: String, user: Option<User>) -> Result<Redirect, Option<Template>>{
let blog = Blog::find_local(&*conn, name).ok_or(None)?;
if user.map(|u| u.is_author_in(&*conn, blog.clone())).unwrap_or(false) {
let blog = Blog::find_local(&*conn, &name).ok_or(None)?;
if user.map(|u| u.is_author_in(&*conn, &blog)).unwrap_or(false) {
blog.delete(&conn);
Ok(Redirect::to(uri!(super::instance::index)))
} else {
@@ -144,17 +144,17 @@ fn delete(conn: DbConn, name: String, user: Option<User>) -> Result<Redirect, Op
#[get("/~/<name>/outbox")]
fn outbox(name: String, conn: DbConn) -> Option<ActivityStream<OrderedCollection>> {
let blog = Blog::find_local(&*conn, name)?;
let blog = Blog::find_local(&*conn, &name)?;
Some(blog.outbox(&*conn))
}
#[get("/~/<name>/atom.xml")]
fn atom_feed(name: String, conn: DbConn) -> Option<Content<String>> {
let blog = Blog::find_by_fqn(&*conn, name.clone())?;
let blog = Blog::find_by_fqn(&*conn, &name)?;
let feed = FeedBuilder::default()
.title(blog.title.clone())
.id(Instance::get_local(&*conn).expect("blogs::atom_feed: local instance not found error")
.compute_box("~", name, "atom.xml"))
.compute_box("~", &name, "atom.xml"))
.entries(Post::get_recents_for_blog(&*conn, &blog, 15)
.into_iter()
.map(|p| super::post_to_atom(p, &*conn))
+7 -7
View File
@@ -31,26 +31,26 @@ struct NewCommentForm {
#[post("/~/<blog_name>/<slug>/comment", data = "<data>")]
fn create(blog_name: String, slug: String, data: LenientForm<NewCommentForm>, user: User, conn: DbConn, worker: State<Pool<ThunkWorker<()>>>)
-> Result<Redirect, Option<Template>> {
let blog = Blog::find_by_fqn(&*conn, blog_name.clone()).ok_or(None)?;
let post = Post::find_by_slug(&*conn, slug.clone(), blog.id).ok_or(None)?;
let blog = Blog::find_by_fqn(&*conn, &blog_name).ok_or(None)?;
let post = Post::find_by_slug(&*conn, &slug, blog.id).ok_or(None)?;
let form = data.get();
form.validate()
.map(|_| {
let (html, mentions, _hashtags) = utils::md_to_html(form.content.as_ref());
let comm = Comment::insert(&*conn, NewComment {
content: SafeString::new(html.as_ref()),
in_response_to_id: form.responding_to.clone(),
in_response_to_id: form.responding_to,
post_id: post.id,
author_id: user.id,
ap_url: None,
sensitive: form.warning.len() > 0,
sensitive: !form.warning.is_empty(),
spoiler_text: form.warning.clone()
}).update_ap_url(&*conn);
let new_comment = comm.create_activity(&*conn);
// save mentions
for ment in mentions {
Mention::from_activity(&*conn, Mention::build_activity(&*conn, ment), post.id, true, true);
Mention::from_activity(&*conn, &Mention::build_activity(&*conn, &ment), post.id, true, true);
}
// federate
@@ -76,7 +76,7 @@ fn create(blog_name: String, slug: String, data: LenientForm<NewCommentForm>, us
"has_reshared": user.has_reshared(&*conn, &post),
"account": user.to_json(&*conn),
"date": &post.creation_date.timestamp(),
"previous": form.responding_to.and_then(|r| Comment::get(&*conn, r)).map(|r| r.to_json(&*conn, &vec![])),
"previous": form.responding_to.and_then(|r| Comment::get(&*conn, r)).map(|r| r.to_json(&*conn, &[])),
"user_fqn": user.get_fqn(&*conn),
"comment_form": form,
"comment_errors": errors,
@@ -86,5 +86,5 @@ fn create(blog_name: String, slug: String, data: LenientForm<NewCommentForm>, us
#[get("/~/<_blog>/<_slug>/comment/<id>")]
fn activity_pub(_blog: String, _slug: String, id: i32, _ap: ApRequest, conn: DbConn) -> Option<ActivityStream<Note>> {
Comment::get(&*conn, id).map(|c| ActivityStream::new(c.into_activity(&*conn)))
Comment::get(&*conn, id).map(|c| ActivityStream::new(c.to_activity(&*conn)))
}
+6 -4
View File
@@ -191,7 +191,9 @@ fn admin_users_paginated(admin: Admin, conn: DbConn, page: Page) -> Template {
#[post("/admin/users/<id>/ban")]
fn ban(_admin: Admin, conn: DbConn, id: i32) -> Redirect {
User::get(&*conn, id).map(|u| u.delete(&*conn));
if let Some(u) = User::get(&*conn, id) {
u.delete(&*conn);
}
Redirect::to(uri!(admin_users))
}
@@ -203,14 +205,14 @@ fn shared_inbox(conn: DbConn, data: String, headers: Headers) -> Result<String,
let actor_id = activity["actor"].as_str()
.or_else(|| activity["actor"]["id"].as_str()).ok_or(status::BadRequest(Some("Missing actor id for activity")))?;
let actor = User::from_url(&conn, actor_id.to_owned()).expect("instance::shared_inbox: user error");
if !verify_http_headers(&actor, headers.0.clone(), data).is_secure() &&
let actor = User::from_url(&conn, actor_id).expect("instance::shared_inbox: user error");
if !verify_http_headers(&actor, &headers.0, &data).is_secure() &&
!act.clone().verify(&actor) {
println!("Rejected invalid activity supposedly from {}, with headers {:?}", actor.username, headers.0);
return Err(status::BadRequest(Some("Invalid signature")));
}
if Instance::is_blocked(&*conn, actor_id.to_string()) {
if Instance::is_blocked(&*conn, actor_id) {
return Ok(String::new());
}
let instance = Instance::get_local(&*conn).expect("instance::shared_inbox: local instance not found error");
+4 -4
View File
@@ -13,8 +13,8 @@ use plume_models::{
#[post("/~/<blog>/<slug>/like")]
fn create(blog: String, slug: String, user: User, conn: DbConn, worker: State<Pool<ThunkWorker<()>>>) -> Option<Redirect> {
let b = Blog::find_by_fqn(&*conn, blog.clone())?;
let post = Post::find_by_slug(&*conn, slug.clone(), b.id)?;
let b = Blog::find_by_fqn(&*conn, &blog)?;
let post = Post::find_by_slug(&*conn, &slug, b.id)?;
if !user.has_liked(&*conn, &post) {
let like = likes::Like::insert(&*conn, likes::NewLike {
@@ -26,7 +26,7 @@ fn create(blog: String, slug: String, user: User, conn: DbConn, worker: State<Po
like.notify(&*conn);
let dest = User::one_by_instance(&*conn);
let act = like.into_activity(&*conn);
let act = like.to_activity(&*conn);
worker.execute(Thunk::of(move || broadcast(&user, act, dest)));
} else {
let like = likes::Like::find_by_user_on_post(&*conn, user.id, post.id).expect("likes::create: like exist but not found error");
@@ -42,6 +42,6 @@ fn create(blog: String, slug: String, user: User, conn: DbConn, worker: State<Po
fn create_auth(blog: String, slug: String) -> Flash<Redirect>{
utils::requires_login(
"You need to be logged in order to like a post",
uri!(create: blog = blog, slug = slug).into()
uri!(create: blog = blog, slug = slug)
)
}
+2 -2
View File
@@ -37,7 +37,7 @@ fn upload(user: User, data: Data, ct: &ContentType, conn: DbConn) -> Result<Redi
.ok_or_else(|| status::BadRequest(Some("No file uploaded")))?.headers
.filename.clone();
let ext = filename.and_then(|f| f.rsplit('.').next().map(|ext| ext.to_owned()))
.unwrap_or("png".to_owned());
.unwrap_or_else(|| "png".to_owned());
let dest = format!("static/media/{}.{}", GUID::rand().to_string(), ext);
match fields[&"file".to_string()][0].data {
@@ -49,7 +49,7 @@ fn upload(user: User, data: Data, ct: &ContentType, conn: DbConn) -> Result<Redi
}
}
let has_cw = read(&fields[&"cw".to_string()][0].data).len() > 0;
let has_cw = !read(&fields[&"cw".to_string()][0].data).is_empty();
let media = Media::insert(&*conn, NewMedia {
file_path: dest,
alt_text: read(&fields[&"alt".to_string()][0].data),
+1 -1
View File
@@ -24,6 +24,6 @@ fn notifications(conn: DbConn, user: User) -> Template {
fn notifications_auth() -> Flash<Redirect>{
utils::requires_login(
"You need to be logged in order to see your notifications",
uri!(notifications).into()
uri!(notifications)
)
}
+42 -41
View File
@@ -38,14 +38,14 @@ fn details(blog: String, slug: String, conn: DbConn, user: Option<User>) -> Temp
#[get("/~/<blog>/<slug>?<query>")]
fn details_response(blog: String, slug: String, conn: DbConn, user: Option<User>, query: Option<CommentQuery>) -> Template {
may_fail!(user.map(|u| u.to_json(&*conn)), Blog::find_by_fqn(&*conn, blog), "Couldn't find this blog", |blog| {
may_fail!(user.map(|u| u.to_json(&*conn)), Post::find_by_slug(&*conn, slug, blog.id), "Couldn't find this post", |post| {
may_fail!(user.map(|u| u.to_json(&*conn)), Blog::find_by_fqn(&*conn, &blog), "Couldn't find this blog", |blog| {
may_fail!(user.map(|u| u.to_json(&*conn)), Post::find_by_slug(&*conn, &slug, blog.id), "Couldn't find this post", |post| {
if post.published || post.get_authors(&*conn).into_iter().any(|a| a.id == user.clone().map(|u| u.id).unwrap_or(0)) {
let comments = Comment::list_by_post(&*conn, post.id);
let comms = comments.clone();
let previous = query.and_then(|q| q.responding_to.map(|r| Comment::get(&*conn, r)
.expect("posts::details_reponse: Error retrieving previous comment").to_json(&*conn, &vec![])));
.expect("posts::details_reponse: Error retrieving previous comment").to_json(&*conn, &[])));
Template::render("posts/details", json!({
"author": post.get_authors(&*conn)[0].to_json(&*conn),
"article": post.to_json(&*conn),
@@ -65,7 +65,7 @@ fn details_response(blog: String, slug: String, conn: DbConn, user: Option<User>
"default": {
"warning": previous.map(|p| p["spoiler_text"].clone())
},
"user_fqn": user.clone().map(|u| u.get_fqn(&*conn)).unwrap_or(String::new()),
"user_fqn": user.clone().map(|u| u.get_fqn(&*conn)).unwrap_or_default(),
"is_author": user.clone().map(|u| post.get_authors(&*conn).into_iter().any(|a| u.id == a.id)).unwrap_or(false),
"is_following": user.map(|u| u.is_following(&*conn, post.get_authors(&*conn)[0].id)).unwrap_or(false),
"comment_form": null,
@@ -82,10 +82,10 @@ fn details_response(blog: String, slug: String, conn: DbConn, user: Option<User>
#[get("/~/<blog>/<slug>", rank = 3)]
fn activity_details(blog: String, slug: String, conn: DbConn, _ap: ApRequest) -> Result<ActivityStream<Article>, Option<String>> {
let blog = Blog::find_by_fqn(&*conn, blog).ok_or(None)?;
let post = Post::find_by_slug(&*conn, slug, blog.id).ok_or(None)?;
let blog = Blog::find_by_fqn(&*conn, &blog).ok_or(None)?;
let post = Post::find_by_slug(&*conn, &slug, blog.id).ok_or(None)?;
if post.published {
Ok(ActivityStream::new(post.into_activity(&*conn)))
Ok(ActivityStream::new(post.to_activity(&*conn)))
} else {
Err(Some(String::from("Not published yet.")))
}
@@ -95,15 +95,15 @@ fn activity_details(blog: String, slug: String, conn: DbConn, _ap: ApRequest) ->
fn new_auth(blog: String) -> Flash<Redirect> {
utils::requires_login(
"You need to be logged in order to write a new post",
uri!(new: blog = blog).into()
uri!(new: blog = blog)
)
}
#[get("/~/<blog>/new", rank = 1)]
fn new(blog: String, user: User, conn: DbConn) -> Option<Template> {
let b = Blog::find_by_fqn(&*conn, blog.to_string())?;
let b = Blog::find_by_fqn(&*conn, &blog)?;
if !user.is_author_in(&*conn, b.clone()) {
if !user.is_author_in(&*conn, &b) {
Some(Template::render("errors/403", json!({// TODO actually return 403 error code
"error_message": "You are not author in this blog."
})))
@@ -123,15 +123,15 @@ fn new(blog: String, user: User, conn: DbConn) -> Option<Template> {
#[get("/~/<blog>/<slug>/edit")]
fn edit(blog: String, slug: String, user: User, conn: DbConn) -> Option<Template> {
let b = Blog::find_by_fqn(&*conn, blog.to_string())?;
let post = Post::find_by_slug(&*conn, slug, b.id)?;
let b = Blog::find_by_fqn(&*conn, &blog)?;
let post = Post::find_by_slug(&*conn, &slug, b.id)?;
if !user.is_author_in(&*conn, b) {
if !user.is_author_in(&*conn, &b) {
Some(Template::render("errors/403", json!({// TODO actually return 403 error code
"error_message": "You are not author in this blog."
})))
} else {
let source = if post.source.len() > 0 {
let source = if !post.source.is_empty() {
post.source
} else {
post.content.get().clone() // fallback to HTML if the markdown was not stored
@@ -165,8 +165,8 @@ fn edit(blog: String, slug: String, user: User, conn: DbConn) -> Option<Template
#[post("/~/<blog>/<slug>/edit", data = "<data>")]
fn update(blog: String, slug: String, user: User, conn: DbConn, data: LenientForm<NewPostForm>, worker: State<Pool<ThunkWorker<()>>>)
-> Result<Redirect, Option<Template>> {
let b = Blog::find_by_fqn(&*conn, blog.to_string()).ok_or(None)?;
let mut post = Post::find_by_slug(&*conn, slug.clone(), b.id).ok_or(None)?;
let b = Blog::find_by_fqn(&*conn, &blog).ok_or(None)?;
let mut post = Post::find_by_slug(&*conn, &slug, b.id).ok_or(None)?;
let form = data.get();
let new_slug = if !post.published {
@@ -180,27 +180,25 @@ fn update(blog: String, slug: String, user: User, conn: DbConn, data: LenientFor
Err(e) => e
};
if new_slug != slug {
if let Some(_) = Post::find_by_slug(&*conn, new_slug.clone(), b.id) {
errors.add("title", ValidationError {
code: Cow::from("existing_slug"),
message: Some(Cow::from("A post with the same title already exists.")),
params: HashMap::new()
});
}
if new_slug != slug && Post::find_by_slug(&*conn, &new_slug, b.id).is_some() {
errors.add("title", ValidationError {
code: Cow::from("existing_slug"),
message: Some(Cow::from("A post with the same title already exists.")),
params: HashMap::new()
});
}
if errors.is_empty() {
if !user.is_author_in(&*conn, b) {
if !user.is_author_in(&*conn, &b) {
// actually it's not "Ok"…
Ok(Redirect::to(uri!(super::blogs::details: name = blog)))
} else {
let (content, mentions, hashtags) = utils::md_to_html(form.content.to_string().as_ref());
let license = if form.license.len() > 0 {
let license = if !form.license.is_empty() {
form.license.to_string()
} else {
Instance::get_local(&*conn).map(|i| i.default_license).unwrap_or(String::from("CC-BY-SA"))
Instance::get_local(&*conn).map(|i| i.default_license).unwrap_or_else(|| String::from("CC-BY-SA"))
};
// update publication date if when this article is no longer a draft
@@ -223,10 +221,10 @@ fn update(blog: String, slug: String, user: User, conn: DbConn, data: LenientFor
let post = post.update_ap_url(&*conn);
if post.published {
post.update_mentions(&conn, mentions.into_iter().map(|m| Mention::build_activity(&conn, m)).collect());
post.update_mentions(&conn, mentions.into_iter().map(|m| Mention::build_activity(&conn, &m)).collect());
}
let tags = form.tags.split(",").map(|t| t.trim().to_camel_case()).filter(|t| t.len() > 0)
let tags = form.tags.split(',').map(|t| t.trim().to_camel_case()).filter(|t| !t.is_empty())
.collect::<HashSet<_>>().into_iter().map(|t| Tag::build_activity(&conn, t)).collect::<Vec<_>>();
post.update_tags(&conn, tags);
@@ -276,7 +274,7 @@ struct NewPostForm {
fn valid_slug(title: &str) -> Result<(), ValidationError> {
let slug = title.to_string().to_kebab_case();
if slug.len() == 0 {
if slug.is_empty() {
Err(ValidationError::new("empty_slug"))
} else if slug == "new" {
Err(ValidationError::new("invalid_slug"))
@@ -287,7 +285,7 @@ fn valid_slug(title: &str) -> Result<(), ValidationError> {
#[post("/~/<blog_name>/new", data = "<data>")]
fn create(blog_name: String, data: LenientForm<NewPostForm>, user: User, conn: DbConn, worker: State<Pool<ThunkWorker<()>>>) -> Result<Redirect, Option<Template>> {
let blog = Blog::find_by_fqn(&*conn, blog_name.to_string()).ok_or(None)?;
let blog = Blog::find_by_fqn(&*conn, &blog_name).ok_or(None)?;
let form = data.get();
let slug = form.title.to_string().to_kebab_case();
@@ -295,7 +293,7 @@ fn create(blog_name: String, data: LenientForm<NewPostForm>, user: User, conn: D
Ok(_) => ValidationErrors::new(),
Err(e) => e
};
if let Some(_) = Post::find_by_slug(&*conn, slug.clone(), blog.id) {
if Post::find_by_slug(&*conn, &slug, blog.id).is_some() {
errors.add("title", ValidationError {
code: Cow::from("existing_slug"),
message: Some(Cow::from("A post with the same title already exists.")),
@@ -304,7 +302,7 @@ fn create(blog_name: String, data: LenientForm<NewPostForm>, user: User, conn: D
}
if errors.is_empty() {
if !user.is_author_in(&*conn, blog.clone()) {
if !user.is_author_in(&*conn, &blog) {
// actually it's not "Ok"…
Ok(Redirect::to(uri!(super::blogs::details: name = blog_name)))
} else {
@@ -316,10 +314,10 @@ fn create(blog_name: String, data: LenientForm<NewPostForm>, user: User, conn: D
title: form.title.to_string(),
content: SafeString::new(&content),
published: !form.draft,
license: if form.license.len() > 0 {
license: if !form.license.is_empty() {
form.license.to_string()
} else {
Instance::get_local(&*conn).map(|i| i.default_license).unwrap_or(String::from("CC-BY-SA"))
Instance::get_local(&*conn).map(|i| i.default_license).unwrap_or_else(||String::from("CC-BY-SA"))
},
ap_url: "".to_string(),
creation_date: None,
@@ -333,10 +331,13 @@ fn create(blog_name: String, data: LenientForm<NewPostForm>, user: User, conn: D
author_id: user.id
});
let tags = form.tags.split(",").map(|t| t.trim().to_camel_case()).filter(|t| t.len() > 0).collect::<HashSet<_>>();
let tags = form.tags.split(',')
.map(|t| t.trim().to_camel_case())
.filter(|t| !t.is_empty())
.collect::<HashSet<_>>();
for tag in tags {
Tag::insert(&*conn, NewTag {
tag: tag,
tag,
is_hashtag: false,
post_id: post.id
});
@@ -350,8 +351,8 @@ fn create(blog_name: String, data: LenientForm<NewPostForm>, user: User, conn: D
}
if post.published {
for m in mentions.into_iter() {
Mention::from_activity(&*conn, Mention::build_activity(&*conn, m), post.id, true, true);
for m in mentions {
Mention::from_activity(&*conn, &Mention::build_activity(&*conn, &m), post.id, true, true);
}
let act = post.create_activity(&*conn);
@@ -377,8 +378,8 @@ fn create(blog_name: String, data: LenientForm<NewPostForm>, user: User, conn: D
#[post("/~/<blog_name>/<slug>/delete")]
fn delete(blog_name: String, slug: String, conn: DbConn, user: User, worker: State<Pool<ThunkWorker<()>>>) -> Redirect {
let post = Blog::find_by_fqn(&*conn, blog_name.clone())
.and_then(|blog| Post::find_by_slug(&*conn, slug.clone(), blog.id));
let post = Blog::find_by_fqn(&*conn, &blog_name)
.and_then(|blog| Post::find_by_slug(&*conn, &slug, blog.id));
if let Some(post) = post {
if !post.get_authors(&*conn).into_iter().any(|a| a.id == user.id) {
+4 -4
View File
@@ -13,8 +13,8 @@ use plume_models::{
#[post("/~/<blog>/<slug>/reshare")]
fn create(blog: String, slug: String, user: User, conn: DbConn, worker: State<Pool<ThunkWorker<()>>>) -> Option<Redirect> {
let b = Blog::find_by_fqn(&*conn, blog.clone())?;
let post = Post::find_by_slug(&*conn, slug.clone(), b.id)?;
let b = Blog::find_by_fqn(&*conn, &blog)?;
let post = Post::find_by_slug(&*conn, &slug, b.id)?;
if !user.has_reshared(&*conn, &post) {
let reshare = Reshare::insert(&*conn, NewReshare {
@@ -26,7 +26,7 @@ fn create(blog: String, slug: String, user: User, conn: DbConn, worker: State<Po
reshare.notify(&*conn);
let dest = User::one_by_instance(&*conn);
let act = reshare.into_activity(&*conn);
let act = reshare.to_activity(&*conn);
worker.execute(Thunk::of(move || broadcast(&user, act, dest)));
} else {
let reshare = Reshare::find_by_user_on_post(&*conn, user.id, post.id)
@@ -43,6 +43,6 @@ fn create(blog: String, slug: String, user: User, conn: DbConn, worker: State<Po
fn create_auth(blog: String, slug: String) -> Flash<Redirect> {
utils::requires_login(
"You need to be logged in order to reshare a post",
uri!(create: blog = blog, slug = slug).into()
uri!(create: blog = blog, slug = slug)
)
}
+8 -6
View File
@@ -49,15 +49,15 @@ struct LoginForm {
#[post("/login", data = "<data>")]
fn create(conn: DbConn, data: LenientForm<LoginForm>, flash: Option<FlashMessage>, mut cookies: Cookies) -> Result<Redirect, Template> {
let form = data.get();
let user = User::find_by_email(&*conn, form.email_or_name.to_string())
.or_else(|| User::find_local(&*conn, form.email_or_name.to_string()));
let user = User::find_by_email(&*conn, &form.email_or_name)
.or_else(|| User::find_local(&*conn, &form.email_or_name));
let mut errors = match form.validate() {
Ok(_) => ValidationErrors::new(),
Err(e) => e
};
if let Some(user) = user.clone() {
if !user.auth(form.password.clone()) {
if !user.auth(&form.password) {
let mut err = ValidationError::new("invalid_login");
err.message = Some(Cow::from("Invalid username or password"));
errors.add("email_or_name", err)
@@ -65,7 +65,7 @@ fn create(conn: DbConn, data: LenientForm<LoginForm>, flash: Option<FlashMessage
} else {
// Fake password verification, only to avoid different login times
// that could be used to see if an email adress is registered or not
User::get(&*conn, 1).map(|u| u.auth(form.password.clone()));
User::get(&*conn, 1).map(|u| u.auth(&form.password));
let mut err = ValidationError::new("invalid_login");
err.message = Some(Cow::from("Invalid username or password"));
@@ -83,7 +83,7 @@ fn create(conn: DbConn, data: LenientForm<LoginForm>, flash: Option<FlashMessage
} else {
None
})
.unwrap_or("/".to_owned());
.unwrap_or_else(|| "/".to_owned());
let uri = Uri::parse(&destination)
.map(|x| x.into_owned())
@@ -108,6 +108,8 @@ fn create(conn: DbConn, data: LenientForm<LoginForm>, flash: Option<FlashMessage
#[get("/logout")]
fn delete(mut cookies: Cookies) -> Redirect {
cookies.get_private(AUTH_COOKIE).map(|cookie| cookies.remove_private(cookie));
if let Some(cookie) = cookies.get_private(AUTH_COOKIE) {
cookies.remove_private(cookie);
}
Redirect::to("/")
}
+33 -33
View File
@@ -29,7 +29,7 @@ use Worker;
fn me(user: Option<User>) -> Result<Redirect, Flash<Redirect>> {
match user {
Some(user) => Ok(Redirect::to(uri!(details: name = user.username))),
None => Err(utils::requires_login("", uri!(me).into())),
None => Err(utils::requires_login("", uri!(me))),
}
}
@@ -45,12 +45,12 @@ fn details(
) -> Template {
may_fail!(
account.map(|a| a.to_json(&*conn)),
User::find_by_fqn(&*conn, name),
User::find_by_fqn(&*conn, &name),
"Couldn't find requested user",
|user| {
let recents = Post::get_recents_for_author(&*conn, &user, 6);
let reshares = Reshare::get_recents_for_author(&*conn, &user, 6);
let user_id = user.id.clone();
let user_id = user.id;
let n_followers = user.get_followers(&*conn).len();
if !user.get_instance(&*conn).local {
@@ -79,9 +79,9 @@ fn details(
worker.execute(Thunk::of(move || {
for user_id in user_clone.fetch_followers_ids() {
let follower =
User::find_by_ap_url(&*fecth_followers_conn, user_id.clone())
User::find_by_ap_url(&*fecth_followers_conn, &user_id)
.unwrap_or_else(|| {
User::fetch_from_url(&*fecth_followers_conn, user_id)
User::fetch_from_url(&*fecth_followers_conn, &user_id)
.expect("user::details: Couldn't fetch follower")
});
follows::Follow::insert(
@@ -139,13 +139,13 @@ fn dashboard(user: User, conn: DbConn) -> Template {
fn dashboard_auth() -> Flash<Redirect> {
utils::requires_login(
"You need to be logged in order to access your dashboard",
uri!(dashboard).into(),
uri!(dashboard),
)
}
#[post("/@/<name>/follow")]
fn follow(name: String, conn: DbConn, user: User, worker: Worker) -> Option<Redirect> {
let target = User::find_by_fqn(&*conn, name.clone())?;
let target = User::find_by_fqn(&*conn, &name)?;
if let Some(follow) = follows::Follow::find(&*conn, user.id, target.id) {
let delete_act = follow.delete(&*conn);
worker.execute(Thunk::of(move || {
@@ -162,7 +162,7 @@ fn follow(name: String, conn: DbConn, user: User, worker: Worker) -> Option<Redi
);
f.notify(&*conn);
let act = f.into_activity(&*conn);
let act = f.to_activity(&*conn);
worker.execute(Thunk::of(move || broadcast(&user, act, vec![target])));
}
Some(Redirect::to(uri!(details: name = name)))
@@ -172,7 +172,7 @@ fn follow(name: String, conn: DbConn, user: User, worker: Worker) -> Option<Redi
fn follow_auth(name: String) -> Flash<Redirect> {
utils::requires_login(
"You need to be logged in order to follow someone",
uri!(follow: name = name).into(),
uri!(follow: name = name),
)
}
@@ -180,10 +180,10 @@ fn follow_auth(name: String) -> Flash<Redirect> {
fn followers_paginated(name: String, conn: DbConn, account: Option<User>, page: Page) -> Template {
may_fail!(
account.map(|a| a.to_json(&*conn)),
User::find_by_fqn(&*conn, name.clone()),
User::find_by_fqn(&*conn, &name),
"Couldn't find requested user",
|user| {
let user_id = user.id.clone();
let user_id = user.id;
let followers_count = user.get_followers(&*conn).len();
Template::render(
@@ -216,8 +216,8 @@ fn activity_details(
conn: DbConn,
_ap: ApRequest,
) -> Option<ActivityStream<CustomPerson>> {
let user = User::find_local(&*conn, name)?;
Some(ActivityStream::new(user.into_activity(&*conn)))
let user = User::find_local(&*conn, &name)?;
Some(ActivityStream::new(user.to_activity(&*conn)))
}
#[get("/users/new")]
@@ -235,7 +235,7 @@ fn new(user: Option<User>, conn: DbConn) -> Template {
#[get("/@/<name>/edit")]
fn edit(name: String, user: User, conn: DbConn) -> Option<Template> {
if user.username == name && !name.contains("@") {
if user.username == name && !name.contains('@') {
Some(Template::render(
"users/edit",
json!({
@@ -251,7 +251,7 @@ fn edit(name: String, user: User, conn: DbConn) -> Option<Template> {
fn edit_auth(name: String) -> Flash<Redirect> {
utils::requires_login(
"You need to be logged in order to edit your profile",
uri!(edit: name = name).into(),
uri!(edit: name = name),
)
}
@@ -269,30 +269,30 @@ fn update(_name: String, conn: DbConn, user: User, data: LenientForm<UpdateUserF
data.get()
.display_name
.clone()
.unwrap_or(user.display_name.to_string())
.unwrap_or_else(|| user.display_name.to_string())
.to_string(),
data.get()
.email
.clone()
.unwrap_or(user.email.clone().unwrap())
.unwrap_or_else(|| user.email.clone().unwrap())
.to_string(),
data.get()
.summary
.clone()
.unwrap_or(user.summary.to_string()),
.unwrap_or_else(|| user.summary.to_string()),
);
Redirect::to(uri!(me))
}
#[post("/@/<name>/delete")]
fn delete(name: String, conn: DbConn, user: User, mut cookies: Cookies) -> Option<Redirect> {
let account = User::find_by_fqn(&*conn, name.clone())?;
let account = User::find_by_fqn(&*conn, &name)?;
if user.id == account.id {
account.delete(&*conn);
cookies
.get_private(AUTH_COOKIE)
.map(|cookie| cookies.remove_private(cookie));
if let Some(cookie) = cookies.get_private(AUTH_COOKIE) {
cookies.remove_private(cookie);
}
Some(Redirect::to(uri!(super::instance::index)))
} else {
@@ -354,9 +354,9 @@ fn create(conn: DbConn, data: LenientForm<NewUserForm>) -> Result<Redirect, Temp
form.username.to_string(),
form.username.to_string(),
false,
String::from(""),
"",
form.email.to_string(),
User::hash_pass(form.password.to_string()),
User::hash_pass(&form.password),
).update_boxes(&*conn);
Redirect::to(uri!(super::session::new))
})
@@ -374,7 +374,7 @@ fn create(conn: DbConn, data: LenientForm<NewUserForm>) -> Result<Redirect, Temp
#[get("/@/<name>/outbox")]
fn outbox(name: String, conn: DbConn) -> Option<ActivityStream<OrderedCollection>> {
let user = User::find_local(&*conn, name)?;
let user = User::find_local(&*conn, &name)?;
Some(user.outbox(&*conn))
}
@@ -385,9 +385,9 @@ fn inbox(
data: String,
headers: Headers,
) -> Result<String, Option<status::BadRequest<&'static str>>> {
let user = User::find_local(&*conn, name).ok_or(None)?;
let user = User::find_local(&*conn, &name).ok_or(None)?;
let act: serde_json::Value =
serde_json::from_str(&data[..]).expect("user::inbox: deserialization error");
serde_json::from_str(&data).expect("user::inbox: deserialization error");
let activity = act.clone();
let actor_id = activity["actor"]
@@ -397,8 +397,8 @@ fn inbox(
"Missing actor id for activity",
))))?;
let actor = User::from_url(&conn, actor_id.to_owned()).expect("user::inbox: user error");
if !verify_http_headers(&actor, headers.0.clone(), data).is_secure()
let actor = User::from_url(&conn, actor_id).expect("user::inbox: user error");
if !verify_http_headers(&actor, &headers.0, &data).is_secure()
&& !act.clone().verify(&actor)
{
println!(
@@ -408,7 +408,7 @@ fn inbox(
return Err(Some(status::BadRequest(Some("Invalid signature"))));
}
if Instance::is_blocked(&*conn, actor_id.to_string()) {
if Instance::is_blocked(&*conn, actor_id) {
return Ok(String::new());
}
Ok(match user.received(&*conn, act) {
@@ -426,7 +426,7 @@ fn ap_followers(
conn: DbConn,
_ap: ApRequest,
) -> Option<ActivityStream<OrderedCollection>> {
let user = User::find_local(&*conn, name)?;
let user = User::find_local(&*conn, &name)?;
let followers = user
.get_followers(&*conn)
.into_iter()
@@ -448,12 +448,12 @@ fn ap_followers(
#[get("/@/<name>/atom.xml")]
fn atom_feed(name: String, conn: DbConn) -> Option<Content<String>> {
let author = User::find_by_fqn(&*conn, name.clone())?;
let author = User::find_by_fqn(&*conn, &name)?;
let feed = FeedBuilder::default()
.title(author.display_name.clone())
.id(Instance::get_local(&*conn)
.unwrap()
.compute_box("~", name, "atom.xml"))
.compute_box("~", &name, "atom.xml"))
.entries(
Post::get_recents_for_author(&*conn, &author, 15)
.into_iter()
+4 -4
View File
@@ -11,7 +11,7 @@ fn nodeinfo() -> Content<String> {
"links": [
{
"rel": "http://nodeinfo.diaspora.software/ns/schema/2.0",
"href": ap_url(format!("{domain}/nodeinfo", domain = BASE_URL.as_str()))
"href": ap_url(&format!("{domain}/nodeinfo", domain = BASE_URL.as_str()))
}
]
}).to_string())
@@ -24,7 +24,7 @@ fn host_meta() -> String {
<XRD xmlns="http://docs.oasis-open.org/ns/xri/xrd-1.0">
<Link rel="lrdd" type="application/xrd+xml" template="{url}"/>
</XRD>
"#, url = ap_url(format!("{domain}/.well-known/webfinger?resource={{uri}}", domain = BASE_URL.as_str())))
"#, url = ap_url(&format!("{domain}/.well-known/webfinger?resource={{uri}}", domain = BASE_URL.as_str())))
}
#[derive(FromForm)]
@@ -40,9 +40,9 @@ impl Resolver<DbConn> for WebfingerResolver {
}
fn find(acct: String, conn: DbConn) -> Result<Webfinger, ResolverError> {
match User::find_local(&*conn, acct.clone()) {
match User::find_local(&*conn, &acct) {
Some(usr) => Ok(usr.webfinger(&*conn)),
None => match Blog::find_local(&*conn, acct) {
None => match Blog::find_local(&*conn, &acct) {
Some(blog) => Ok(blog.webfinger(&*conn)),
None => Err(ResolverError::NotFound)
}