@ -26,7 +26,7 @@ use safe_string::SafeString;
use schema ::blogs ;
use search ::Searcher ;
use users ::User ;
use { Connection , BASE_URL , USE_HTTPS };
use { Connection , BASE_URL , USE_HTTPS , Error , Result };
pub type CustomGroup = CustomObject < ApSignature , Group > ;
@ -67,11 +67,11 @@ impl Blog {
find_by ! ( blogs , find_by_ap_url , ap_url as & str ) ;
find_by ! ( blogs , find_by_name , actor_id as & str , instance_id as i32 ) ;
pub fn get_instance ( & self , conn : & Connection ) -> Instance {
Instance ::get ( conn , self . instance_id ) . expect ( "Blog::get_instance: instance not found error" )
pub fn get_instance ( & self , conn : & Connection ) -> Result < Instance > {
Instance ::get ( conn , self . instance_id )
}
pub fn list_authors ( & self , conn : & Connection ) -> Vec< User > {
pub fn list_authors ( & self , conn : & Connection ) -> Result< Vec< User > > {
use schema ::blog_authors ;
use schema ::users ;
let authors_ids = blog_authors ::table
@ -80,19 +80,19 @@ impl Blog {
users ::table
. filter ( users ::id . eq_any ( authors_ids ) )
. load ::< User > ( conn )
. expect( "Blog::list_authors: author loading error" )
. map_err( Error ::from )
}
pub fn count_authors ( & self , conn : & Connection ) -> i64 {
pub fn count_authors ( & self , conn : & Connection ) -> Result < i64 > {
use schema ::blog_authors ;
blog_authors ::table
. filter ( blog_authors ::blog_id . eq ( self . id ) )
. count ( )
. get_result ( conn )
. expect( "Blog::count_authors: count loading error" )
. map_err( Error ::from )
}
pub fn find_for_author ( conn : & Connection , author : & User ) -> Vec< Blog > {
pub fn find_for_author ( conn : & Connection , author : & User ) -> Result< Vec< Blog > > {
use schema ::blog_authors ;
let author_ids = blog_authors ::table
. filter ( blog_authors ::author_id . eq ( author . id ) )
@ -100,62 +100,40 @@ impl Blog {
blogs ::table
. filter ( blogs ::id . eq_any ( author_ids ) )
. load ::< Blog > ( conn )
. expect( "Blog::find_for_author: blog loading error" )
. map_err( Error ::from )
}
pub fn find_local ( conn : & Connection , name : & str ) -> Option < Blog > {
Blog ::find_by_name ( conn , name , Instance :: local_id ( conn ) )
pub fn find_local ( conn : & Connection , name : & str ) -> Result < Blog > {
Blog ::find_by_name ( conn , name , Instance ::get_ local( conn ) ? . id )
}
pub fn find_by_fqn ( conn : & Connection , fqn : & str ) -> Option < Blog > {
if fqn . contains ( '@' ) {
// remote blog
match Instance ::find_by_domain (
conn ,
fqn . split ( '@' )
. last ( )
. expect ( "Blog::find_by_fqn: unreachable" ) ,
) {
Some ( instance ) = > match Blog ::find_by_name (
conn ,
fqn . split ( '@' )
. nth ( 0 )
. expect ( "Blog::find_by_fqn: unreachable" ) ,
instance . id ,
) {
Some ( u ) = > Some ( u ) ,
None = > Blog ::fetch_from_webfinger ( conn , fqn ) ,
} ,
None = > Blog ::fetch_from_webfinger ( conn , fqn ) ,
}
} else {
// local blog
Blog ::find_local ( conn , fqn )
pub fn find_by_fqn ( conn : & Connection , fqn : & str ) -> Result < Blog > {
let mut split_fqn = fqn . split ( '@' ) ;
let actor = split_fqn . next ( ) . ok_or ( Error ::InvalidValue ) ? ;
if let Some ( domain ) = split_fqn . next ( ) { // remote blog
Instance ::find_by_domain ( conn , domain )
. and_then ( | instance | Blog ::find_by_name ( conn , actor , instance . id ) )
. or_else ( | _ | Blog ::fetch_from_webfinger ( conn , fqn ) )
} else { // local blog
Blog ::find_local ( conn , actor )
}
}
fn fetch_from_webfinger ( conn : & Connection , acct : & str ) -> Option < Blog > {
match resolve ( acct . to_owned ( ) , * USE_HTTPS ) {
Ok ( wf ) = > wf
. links
. into_iter ( )
. find ( | l | l . mime_type = = Some ( String ::from ( "application/activity+json" ) ) )
. and_then ( | l | {
Blog ::fetch_from_url (
conn ,
& l . href
. expect ( "Blog::fetch_from_webfinger: href not found error" ) ,
)
} ) ,
Err ( details ) = > {
println! ( "{:?}" , details ) ;
None
}
}
fn fetch_from_webfinger ( conn : & Connection , acct : & str ) -> Result < Blog > {
resolve ( acct . to_owned ( ) , * USE_HTTPS ) ? . links
. into_iter ( )
. find ( | l | l . mime_type = = Some ( String ::from ( "application/activity+json" ) ) )
. ok_or ( Error ::Webfinger )
. and_then ( | l | {
Blog ::fetch_from_url (
conn ,
& l . href ?
)
} )
}
fn fetch_from_url ( conn : & Connection , url : & str ) -> Option < Blog > {
let req = Client ::new ( )
fn fetch_from_url ( conn : & Connection , url : & str ) -> Result < Blog > {
let mut res = Client ::new ( )
. get ( url )
. header (
ACCEPT ,
@ -164,139 +142,109 @@ impl Blog {
. into_iter ( )
. collect ::< Vec < _ > > ( )
. join ( ", " ) ,
) . expect ( "Blog::fetch_from_url: accept_header generation error" ) ,
) ? ,
)
. send ( ) ;
match req {
Ok ( mut res ) = > {
let text = & res
. text ( )
. expect ( "Blog::fetch_from_url: body reading error" ) ;
let ap_sign : ApSignature =
serde_json ::from_str ( text ) . expect ( "Blog::fetch_from_url: body parsing error" ) ;
let mut json : CustomGroup =
serde_json ::from_str ( text ) . expect ( "Blog::fetch_from_url: body parsing error" ) ;
json . custom_props = ap_sign ; // without this workaround, publicKey is not correctly deserialized
Some ( Blog ::from_activity (
conn ,
& json ,
Url ::parse ( url )
. expect ( "Blog::fetch_from_url: url parsing error" )
. host_str ( )
. expect ( "Blog::fetch_from_url: host extraction error" ) ,
) )
}
Err ( _ ) = > None ,
}
. send ( ) ? ;
let text = & res . text ( ) ? ;
let ap_sign : ApSignature =
serde_json ::from_str ( text ) ? ;
let mut json : CustomGroup =
serde_json ::from_str ( text ) ? ;
json . custom_props = ap_sign ; // without this workaround, publicKey is not correctly deserialized
Blog ::from_activity (
conn ,
& json ,
Url ::parse ( url ) ? . host_str ( ) ? ,
)
}
fn from_activity ( conn : & Connection , acct : & CustomGroup , inst : & str ) -> Blog {
let instance = match Instance ::find_by_domain ( conn , inst ) {
Some ( instance ) = > instance ,
None = > {
Instance ::insert (
conn ,
NewInstance {
public_domain : inst . to_owned ( ) ,
name : inst . to_owned ( ) ,
local : false ,
// We don't really care about all the following for remote instances
long_description : SafeString ::new ( "" ) ,
short_description : SafeString ::new ( "" ) ,
default_license : String ::new ( ) ,
open_registrations : true ,
short_description_html : String ::new ( ) ,
long_description_html : String ::new ( ) ,
} ,
)
}
} ;
fn from_activity ( conn : & Connection , acct : & CustomGroup , inst : & str ) -> Result < Blog > {
let instance = Instance ::find_by_domain ( conn , inst ) . or_else ( | _ |
Instance ::insert (
conn ,
NewInstance {
public_domain : inst . to_owned ( ) ,
name : inst . to_owned ( ) ,
local : false ,
// We don't really care about all the following for remote instances
long_description : SafeString ::new ( "" ) ,
short_description : SafeString ::new ( "" ) ,
default_license : String ::new ( ) ,
open_registrations : true ,
short_description_html : String ::new ( ) ,
long_description_html : String ::new ( ) ,
} ,
)
) ? ;
Blog ::insert (
conn ,
NewBlog {
actor_id : acct
. object
. ap_actor_props
. preferred_username_string ( )
. expect ( "Blog::from_activity: preferredUsername error" ) ,
. preferred_username_string ( ) ? ,
title : acct
. object
. object_props
. name_string ( )
. expect ( "Blog::from_activity: name error" ) ,
. name_string ( ) ? ,
outbox_url : acct
. object
. ap_actor_props
. outbox_string ( )
. expect ( "Blog::from_activity: outbox error" ) ,
. outbox_string ( ) ? ,
inbox_url : acct
. object
. ap_actor_props
. inbox_string ( )
. expect ( "Blog::from_activity: inbox error" ) ,
. inbox_string ( ) ? ,
summary : acct
. object
. object_props
. summary_string ( )
. expect ( "Blog::from_activity: summary error" ) ,
. summary_string ( ) ? ,
instance_id : instance . id ,
ap_url : acct
. object
. object_props
. id_string ( )
. expect ( "Blog::from_activity: id error" ) ,
. id_string ( ) ? ,
public_key : acct
. custom_props
. public_key_publickey ( )
. expect ( "Blog::from_activity: publicKey error" )
. public_key_pem_string ( )
. expect ( "Blog::from_activity: publicKey.publicKeyPem error" ) ,
. public_key_publickey ( ) ?
. public_key_pem_string ( ) ? ,
private_key : None ,
} ,
)
}
pub fn to_activity ( & self , _conn : & Connection ) -> CustomGroup {
pub fn to_activity ( & self , _conn : & Connection ) -> Result < CustomGroup > {
let mut blog = Group ::default ( ) ;
blog . ap_actor_props
. set_preferred_username_string ( self . actor_id . clone ( ) )
. expect ( "Blog::to_activity: preferredUsername error" ) ;
. set_preferred_username_string ( self . actor_id . clone ( ) ) ? ;
blog . object_props
. set_name_string ( self . title . clone ( ) )
. expect ( "Blog::to_activity: name error" ) ;
. set_name_string ( self . title . clone ( ) ) ? ;
blog . ap_actor_props
. set_outbox_string ( self . outbox_url . clone ( ) )
. expect ( "Blog::to_activity: outbox error" ) ;
. set_outbox_string ( self . outbox_url . clone ( ) ) ? ;
blog . ap_actor_props
. set_inbox_string ( self . inbox_url . clone ( ) )
. expect ( "Blog::to_activity: inbox error" ) ;
. set_inbox_string ( self . inbox_url . clone ( ) ) ? ;
blog . object_props
. set_summary_string ( self . summary . clone ( ) )
. expect ( "Blog::to_activity: summary error" ) ;
. set_summary_string ( self . summary . clone ( ) ) ? ;
blog . object_props
. set_id_string ( self . ap_url . clone ( ) )
. expect ( "Blog::to_activity: id error" ) ;
. set_id_string ( self . ap_url . clone ( ) ) ? ;
let mut public_key = PublicKey ::default ( ) ;
public_key
. set_id_string ( format! ( "{}#main-key" , self . ap_url ) )
. expect ( "Blog::to_activity: publicKey.id error" ) ;
. set_id_string ( format! ( "{}#main-key" , self . ap_url ) ) ? ;
public_key
. set_owner_string ( self . ap_url . clone ( ) )
. expect ( "Blog::to_activity: publicKey.owner error" ) ;
. set_owner_string ( self . ap_url . clone ( ) ) ? ;
public_key
. set_public_key_pem_string ( self . public_key . clone ( ) )
. expect ( "Blog::to_activity: publicKey.publicKeyPem error" ) ;
. set_public_key_pem_string ( self . public_key . clone ( ) ) ? ;
let mut ap_signature = ApSignature ::default ( ) ;
ap_signature
. set_public_key_publickey ( public_key )
. expect ( "Blog::to_activity: publicKey error" ) ;
. set_public_key_publickey ( public_key ) ? ;
CustomGroup ::new ( blog , ap_signature )
Ok ( CustomGroup ::new ( blog , ap_signature ) )
}
pub fn update_boxes ( & self , conn : & Connection ) {
let instance = self . get_instance ( conn ) ;
pub fn update_boxes ( & self , conn : & Connection ) -> Result < ( ) > {
let instance = self . get_instance ( conn ) ? ;
if self . outbox_url . is_empty ( ) {
diesel ::update ( self )
. set ( blogs ::outbox_url . eq ( instance . compute_box (
@ -304,8 +252,7 @@ impl Blog {
& self . actor_id ,
"outbox" ,
) ) )
. execute ( conn )
. expect ( "Blog::update_boxes: outbox update error" ) ;
. execute ( conn ) ? ;
}
if self . inbox_url . is_empty ( ) {
@ -315,49 +262,45 @@ impl Blog {
& self . actor_id ,
"inbox" ,
) ) )
. execute ( conn )
. expect ( "Blog::update_boxes: inbox update error" ) ;
. execute ( conn ) ? ;
}
if self . ap_url . is_empty ( ) {
diesel ::update ( self )
. set ( blogs ::ap_url . eq ( instance . compute_box ( BLOG_PREFIX , & self . actor_id , "" ) ) )
. execute ( conn )
. expect ( "Blog::update_boxes: ap_url update error" ) ;
. execute ( conn ) ? ;
}
Ok ( ( ) )
}
pub fn outbox ( & self , conn : & Connection ) -> ActivityStream< OrderedCollection > {
pub fn outbox ( & self , conn : & Connection ) -> Result < ActivityStream< OrderedCollection > > {
let mut coll = OrderedCollection ::default ( ) ;
coll . collection_props . items = serde_json ::to_value ( self . get_activities ( conn ) )
. expect ( "Blog::outbox: activity serialization error" ) ;
coll . collection_props . items = serde_json ::to_value ( self . get_activities ( conn ) ? ) ? ;
coll . collection_props
. set_total_items_u64 ( self . get_activities ( conn ) . len ( ) as u64 )
. expect ( "Blog::outbox: count serialization error" ) ;
ActivityStream ::new ( coll )
. set_total_items_u64 ( self . get_activities ( conn ) ? . len ( ) as u64 ) ? ;
Ok ( ActivityStream ::new ( coll ) )
}
fn get_activities ( & self , _conn : & Connection ) -> Vec< serde_json ::Value > {
vec! [ ]
fn get_activities ( & self , _conn : & Connection ) -> Result< Vec< serde_json ::Value > > {
Ok ( vec! [ ] )
}
pub fn get_keypair ( & self ) -> PKey < Private > {
pub fn get_keypair ( & self ) -> Result < PKey < Private > > {
PKey ::from_rsa (
Rsa ::private_key_from_pem (
self . private_key
. clone ( )
. expect ( "Blog::get_keypair: private key not found error" )
. clone ( ) ?
. as_ref ( ) ,
) . expect ( "Blog::get_keypair: pem parsing error" ) ,
) . expect( "Blog::get_keypair: private key deserialization error" )
) ? ,
) . map_err( Error ::from )
}
pub fn webfinger ( & self , conn : & Connection ) -> Webfinger {
Webfinger {
pub fn webfinger ( & self , conn : & Connection ) -> Result < Webfinger > {
Ok ( Webfinger {
subject : format ! (
"acct:{}@{}" ,
self . actor_id ,
self . get_instance ( conn ) . public_domain
self . get_instance ( conn ) ? . public_domain
) ,
aliases : vec ! [ self . ap_url . clone ( ) ] ,
links : vec ! [
@ -370,7 +313,7 @@ impl Blog {
Link {
rel : String ::from ( "http://schemas.google.com/g/2010#updates-from" ) ,
mime_type : Some ( String ::from ( "application/atom+xml" ) ) ,
href : Some ( self . get_instance ( conn ) . compute_box (
href : Some ( self . get_instance ( conn ) ? . compute_box (
BLOG_PREFIX ,
& self . actor_id ,
"feed.atom" ,
@ -384,50 +327,41 @@ impl Blog {
template : None ,
} ,
] ,
}
} )
}
pub fn from_url ( conn : & Connection , url : & str ) -> Option < Blog > {
Blog ::find_by_ap_url ( conn , url ) . or_else ( | | {
pub fn from_url ( conn : & Connection , url : & str ) -> Result < Blog > {
Blog ::find_by_ap_url ( conn , url ) . or_else ( | _ | {
// The requested blog was not in the DB
// We try to fetch it if it is remote
if Url ::parse ( url )
. expect ( "Blog::from_url: ap_url parsing error" )
. host_str ( )
. expect ( "Blog::from_url: host extraction error" ) ! = BASE_URL . as_str ( )
{
if Url ::parse ( url ) ? . host_str ( ) ? ! = BASE_URL . as_str ( ) {
Blog ::fetch_from_url ( conn , url )
} else {
None
Err ( Error ::NotFound )
}
} )
}
pub fn get_fqn ( & self , conn : & Connection ) -> String {
if self . instance_id = = Instance :: local_id ( conn ) {
if self . instance_id = = Instance ::get_ local( conn ) . ok ( ) . expect ( "Blog::get_fqn: local instance error" ) . id {
self . actor_id . clone ( )
} else {
format! (
"{}@{}" ,
self . actor_id ,
self . get_instance ( conn ) . public_domain
self . get_instance ( conn ) . ok( ) . expect ( "Blog::get_fqn: instance error" ) . public_domain
)
}
}
pub fn to_json ( & self , conn : & Connection ) -> serde_json ::Value {
let mut json = serde_json ::to_value ( self ) . expect ( "Blog::to_json: serialization error" ) ;
json [ "fqn" ] = json ! ( self . get_fqn ( conn ) ) ;
json
}
pub fn delete ( & self , conn : & Connection , searcher : & Searcher ) {
for post in Post ::get_for_blog ( conn , & self ) {
post . delete ( & ( conn , searcher ) ) ;
pub fn delete ( & self , conn : & Connection , searcher : & Searcher ) -> Result < ( ) > {
for post in Post ::get_for_blog ( conn , & self ) ? {
post . delete ( & ( conn , searcher ) ) ? ;
}
diesel ::delete ( self )
. execute ( conn )
. expect ( "Blog::delete: blog deletion error" ) ;
. map ( | _ | ( ) )
. map_err ( Error ::from )
}
}
@ -455,35 +389,33 @@ impl WithInbox for Blog {
}
impl sign ::Signer for Blog {
type Error = Error ;
fn get_key_id ( & self ) -> String {
format! ( "{}#main-key" , self . ap_url )
}
fn sign ( & self , to_sign : & str ) -> Vec< u8 > {
let key = self . get_keypair ( ) ;
fn sign ( & self , to_sign : & str ) -> Result< Vec< u8 > > {
let key = self . get_keypair ( ) ? ;
let mut signer =
Signer ::new ( MessageDigest ::sha256 ( ) , & key ) . expect ( "Blog::sign: initialization error" ) ;
Signer ::new ( MessageDigest ::sha256 ( ) , & key ) ? ;
signer
. update ( to_sign . as_bytes ( ) )
. expect ( "Blog::sign: content insertion error" ) ;
. update ( to_sign . as_bytes ( ) ) ? ;
signer
. sign_to_vec ( )
. expect( "Blog::sign: finalization error" )
. map_err( Error ::from )
}
fn verify ( & self , data : & str , signature : & [ u8 ] ) -> bool {
fn verify ( & self , data : & str , signature : & [ u8 ] ) -> Result < bool > {
let key = PKey ::from_rsa (
Rsa ::public_key_from_pem ( self . public_key . as_ref ( ) )
. expect ( "Blog::verify: pem parsing error" ) ,
) . expect ( "Blog::verify: deserialization error" ) ;
let mut verifier = Verifier ::new ( MessageDigest ::sha256 ( ) , & key )
. expect ( "Blog::verify: initialization error" ) ;
Rsa ::public_key_from_pem ( self . public_key . as_ref ( ) ) ?
) ? ;
let mut verifier = Verifier ::new ( MessageDigest ::sha256 ( ) , & key ) ? ;
verifier
. update ( data . as_bytes ( ) )
. expect ( "Blog::verify: content insertion error" ) ;
. update ( data . as_bytes ( ) ) ? ;
verifier
. verify ( & signature )
. expect( "Blog::verify: finalization error" )
. map_err( Error ::from )
}
}
@ -493,9 +425,9 @@ impl NewBlog {
title : String ,
summary : String ,
instance_id : i32 ,
) -> NewBlog {
) -> Result < NewBlog > {
let ( pub_key , priv_key ) = sign ::gen_keypair ( ) ;
NewBlog {
Ok ( NewBlog {
actor_id ,
title ,
summary ,
@ -503,11 +435,9 @@ impl NewBlog {
inbox_url : String ::from ( "" ) ,
instance_id ,
ap_url : String ::from ( "" ) ,
public_key : String ::from_utf8 ( pub_key ) . expect ( "NewBlog::new_local: public key error" ) ,
private_key : Some (
String ::from_utf8 ( priv_key ) . expect ( "NewBlog::new_local: private key error" ) ,
) ,
}
public_key : String ::from_utf8 ( pub_key ) . or ( Err ( Error ::Signature ) ) ? ,
private_key : Some ( String ::from_utf8 ( priv_key ) . or ( Err ( Error ::Signature ) ) ? ) ,
} )
}
}
@ -529,23 +459,23 @@ pub(crate) mod tests {
"BlogName" . to_owned ( ) ,
"Blog name" . to_owned ( ) ,
"This is a small blog" . to_owned ( ) ,
Instance ::local_id( conn ) ,
) );
blog1 . update_boxes ( conn ) ;
Instance ::get_local( conn ) . unwrap ( ) . id
) .unwrap ( ) ) . unwrap ( );
blog1 . update_boxes ( conn ) .unwrap ( ) ;
let blog2 = Blog ::insert ( conn , NewBlog ::new_local (
"MyBlog" . to_owned ( ) ,
"My blog" . to_owned ( ) ,
"Welcome to my blog" . to_owned ( ) ,
Instance ::local_id( conn ) ,
) );
blog2 . update_boxes ( conn ) ;
Instance ::get_local( conn ) . unwrap ( ) . id
) .unwrap ( ) ) . unwrap ( );
blog2 . update_boxes ( conn ) .unwrap ( ) ;
let blog3 = Blog ::insert ( conn , NewBlog ::new_local (
"WhyILikePlume" . to_owned ( ) ,
"Why I like Plume" . to_owned ( ) ,
"In this blog I will explay you why I like Plume so much" . to_owned ( ) ,
Instance ::local_id( conn ) ,
) );
blog3 . update_boxes ( conn ) ;
Instance ::get_local( conn ) . unwrap ( ) . id
) .unwrap ( ) ) . unwrap ( );
blog3 . update_boxes ( conn ) .unwrap ( ) ;
BlogAuthor ::insert (
conn ,
@ -554,7 +484,7 @@ pub(crate) mod tests {
author_id : users [ 0 ] . id ,
is_owner : true ,
} ,
) ;
) .unwrap ( ) ;
BlogAuthor ::insert (
conn ,
@ -563,7 +493,7 @@ pub(crate) mod tests {
author_id : users [ 1 ] . id ,
is_owner : false ,
} ,
) ;
) .unwrap ( ) ;
BlogAuthor ::insert (
conn ,
@ -572,7 +502,7 @@ pub(crate) mod tests {
author_id : users [ 1 ] . id ,
is_owner : true ,
} ,
) ;
) .unwrap ( ) ;
BlogAuthor ::insert (
conn ,
@ -581,7 +511,7 @@ pub(crate) mod tests {
author_id : users [ 2 ] . id ,
is_owner : true ,
} ,
) ;
) .unwrap ( ) ;
( users , vec! [ blog1 , blog2 , blog3 ] )
}
@ -597,11 +527,11 @@ pub(crate) mod tests {
"SomeName" . to_owned ( ) ,
"Some name" . to_owned ( ) ,
"This is some blog" . to_owned ( ) ,
Instance ::local_id( conn ) ,
) ,
) ;
Instance ::get_local( conn ) . unwrap ( ) . id
) .unwrap ( ) ,
) .unwrap ( ) ;
assert_eq! ( blog . get_instance ( conn ) . id, Instance :: local_id ( conn ) ) ;
assert_eq! ( blog . get_instance ( conn ) . unwrap( ) . id, Instance ::get_ local( conn ) . unwrap ( ) . id ) ;
// TODO add tests for remote instance
Ok ( ( ) )
@ -620,20 +550,20 @@ pub(crate) mod tests {
"SomeName" . to_owned ( ) ,
"Some name" . to_owned ( ) ,
"This is some blog" . to_owned ( ) ,
Instance :: local_id ( conn ) ,
) ,
) ;
b1 . update_boxes ( conn ) ;
Instance ::get_ local( conn ) . unwrap ( ) . id ,
) .unwrap ( ) ,
) .unwrap ( ) ;
b1 . update_boxes ( conn ) .unwrap ( ) ;
let b2 = Blog ::insert (
conn ,
NewBlog ::new_local (
"Blog" . to_owned ( ) ,
"Blog" . to_owned ( ) ,
"I've named my blog Blog" . to_owned ( ) ,
Instance ::local_id( conn ) ,
) ,
) ;
b2 . update_boxes ( conn ) ;
Instance ::get_local( conn ) . unwrap ( ) . id
) .unwrap ( ) ,
) .unwrap ( ) ;
b2 . update_boxes ( conn ) .unwrap ( ) ;
let blog = vec! [ b1 , b2 ] ;
BlogAuthor ::insert (
@ -643,7 +573,7 @@ pub(crate) mod tests {
author_id : user [ 0 ] . id ,
is_owner : true ,
} ,
) ;
) .unwrap ( ) ;
BlogAuthor ::insert (
conn ,
@ -652,7 +582,7 @@ pub(crate) mod tests {
author_id : user [ 1 ] . id ,
is_owner : false ,
} ,
) ;
) .unwrap ( ) ;
BlogAuthor ::insert (
conn ,
@ -661,50 +591,50 @@ pub(crate) mod tests {
author_id : user [ 0 ] . id ,
is_owner : true ,
} ,
) ;
) .unwrap ( ) ;
assert! (
blog [ 0 ]
. list_authors ( conn )
. list_authors ( conn ) . unwrap ( )
. iter ( )
. any ( | a | a . id = = user [ 0 ] . id )
) ;
assert! (
blog [ 0 ]
. list_authors ( conn )
. list_authors ( conn ) . unwrap ( )
. iter ( )
. any ( | a | a . id = = user [ 1 ] . id )
) ;
assert! (
blog [ 1 ]
. list_authors ( conn )
. list_authors ( conn ) . unwrap ( )
. iter ( )
. any ( | a | a . id = = user [ 0 ] . id )
) ;
assert! (
! blog [ 1 ]
. list_authors ( conn )
. list_authors ( conn ) . unwrap ( )
. iter ( )
. any ( | a | a . id = = user [ 1 ] . id )
) ;
assert! (
Blog ::find_for_author ( conn , & user [ 0 ] )
Blog ::find_for_author ( conn , & user [ 0 ] ) . unwrap ( )
. iter ( )
. any ( | b | b . id = = blog [ 0 ] . id )
) ;
assert! (
Blog ::find_for_author ( conn , & user [ 1 ] )
Blog ::find_for_author ( conn , & user [ 1 ] ) . unwrap ( )
. iter ( )
. any ( | b | b . id = = blog [ 0 ] . id )
) ;
assert! (
Blog ::find_for_author ( conn , & user [ 0 ] )
Blog ::find_for_author ( conn , & user [ 0 ] ) . unwrap ( )
. iter ( )
. any ( | b | b . id = = blog [ 1 ] . id )
) ;
assert! (
! Blog ::find_for_author ( conn , & user [ 1 ] )
! Blog ::find_for_author ( conn , & user [ 1 ] ) . unwrap ( )
. iter ( )
. any ( | b | b . id = = blog [ 1 ] . id )
) ;
@ -725,9 +655,9 @@ pub(crate) mod tests {
"SomeName" . to_owned ( ) ,
"Some name" . to_owned ( ) ,
"This is some blog" . to_owned ( ) ,
Instance :: local_id ( conn ) ,
) ,
) ;
Instance ::get_ local( conn ) . unwrap ( ) . id ,
) .unwrap ( ) ,
) .unwrap ( ) ;
assert_eq! (
Blog ::find_local ( conn , "SomeName" ) . unwrap ( ) . id ,
@ -750,9 +680,9 @@ pub(crate) mod tests {
"SomeName" . to_owned ( ) ,
"Some name" . to_owned ( ) ,
"This is some blog" . to_owned ( ) ,
Instance :: local_id ( conn ) ,
) ,
) ;
Instance ::get_ local( conn ) . unwrap ( ) . id ,
) .unwrap ( ) ,
) .unwrap ( ) ;
assert_eq! ( blog . get_fqn ( conn ) , "SomeName" ) ;
@ -766,8 +696,8 @@ pub(crate) mod tests {
conn . test_transaction ::< _ , ( ) , _ > ( | | {
let ( _ , blogs ) = fill_database ( conn ) ;
blogs [ 0 ] . delete ( conn , & get_searcher ( ) ) ;
assert! ( Blog ::get ( conn , blogs [ 0 ] . id ) . is_ non e( ) ) ;
blogs [ 0 ] . delete ( conn , & get_searcher ( ) ) .unwrap ( ) ;
assert! ( Blog ::get ( conn , blogs [ 0 ] . id ) . is_ err ( ) ) ;
Ok ( ( ) )
} ) ;
@ -786,20 +716,20 @@ pub(crate) mod tests {
"SomeName" . to_owned ( ) ,
"Some name" . to_owned ( ) ,
"This is some blog" . to_owned ( ) ,
Instance :: local_id ( conn ) ,
) ,
) ;
b1 . update_boxes ( conn ) ;
Instance ::get_ local( conn ) . unwrap ( ) . id ,
) .unwrap ( ) ,
) .unwrap ( ) ;
b1 . update_boxes ( conn ) .unwrap ( ) ;
let b2 = Blog ::insert (
conn ,
NewBlog ::new_local (
"Blog" . to_owned ( ) ,
"Blog" . to_owned ( ) ,
"I've named my blog Blog" . to_owned ( ) ,
Instance :: local_id ( conn ) ,
) ,
) ;
b2 . update_boxes ( conn ) ;
Instance ::get_ local( conn ) . unwrap ( ) . id ,
) .unwrap ( ) ,
) .unwrap ( ) ;
b2 . update_boxes ( conn ) .unwrap ( ) ;
let blog = vec! [ b1 , b2 ] ;
BlogAuthor ::insert (
@ -809,7 +739,7 @@ pub(crate) mod tests {
author_id : user [ 0 ] . id ,
is_owner : true ,
} ,
) ;
) .unwrap ( ) ;
BlogAuthor ::insert (
conn ,
@ -818,7 +748,7 @@ pub(crate) mod tests {
author_id : user [ 1 ] . id ,
is_owner : false ,
} ,
) ;
) .unwrap ( ) ;
BlogAuthor ::insert (
conn ,
@ -827,13 +757,13 @@ pub(crate) mod tests {
author_id : user [ 0 ] . id ,
is_owner : true ,
} ,
) ;
) .unwrap ( ) ;
user [ 0 ] . delete ( conn , & searcher ) ;
assert! ( Blog ::get ( conn , blog [ 0 ] . id ) . is_ some ( ) ) ;
assert! ( Blog ::get ( conn , blog [ 1 ] . id ) . is_ non e( ) ) ;
user [ 1 ] . delete ( conn , & searcher ) ;
assert! ( Blog ::get ( conn , blog [ 0 ] . id ) . is_ non e( ) ) ;
user [ 0 ] . delete ( conn , & searcher ) .unwrap ( ) ;
assert! ( Blog ::get ( conn , blog [ 0 ] . id ) . is_ ok ( ) ) ;
assert! ( Blog ::get ( conn , blog [ 1 ] . id ) . is_ err ( ) ) ;
user [ 1 ] . delete ( conn , & searcher ) .unwrap ( ) ;
assert! ( Blog ::get ( conn , blog [ 0 ] . id ) . is_ err ( ) ) ;
Ok ( ( ) )
} ) ;