mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-13 03:09:04 +01:00
Backend for Automatic Personal Blogs
When a contact is added, her personal blog will also be added automatically. Also, when a new identity is added, a personal blog for that identity is created. Part of #436
This commit is contained in:
@@ -11,13 +11,16 @@ public class Blog extends Forum {
|
||||
private final String description;
|
||||
@NotNull
|
||||
private final Author author;
|
||||
private final boolean permanent;
|
||||
|
||||
public Blog(@NotNull Group group, @NotNull String name,
|
||||
@NotNull String description, @NotNull Author author) {
|
||||
@NotNull String description, @NotNull Author author,
|
||||
boolean permanent) {
|
||||
super(group, name, null);
|
||||
|
||||
this.description = description;
|
||||
this.author = author;
|
||||
this.permanent = permanent;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -29,4 +32,8 @@ public class Blog extends Forum {
|
||||
public Author getAuthor() {
|
||||
return author;
|
||||
}
|
||||
|
||||
public boolean isPermanent() {
|
||||
return permanent;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,6 +19,9 @@ public interface BlogConstants {
|
||||
/** The maximum length of a blog post's body in bytes. */
|
||||
int MAX_BLOG_POST_BODY_LENGTH = MAX_MESSAGE_BODY_LENGTH - 1024;
|
||||
|
||||
/** The internal name of personal blogs that are created automatically */
|
||||
String PERSONAL_BLOG_NAME = "briar.PERSONAL_BLOG_NAME";
|
||||
|
||||
/* Blog Sharing Constants */
|
||||
String BLOG_TITLE = "blogTitle";
|
||||
String BLOG_DESC = "blogDescription";
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package org.briarproject.api.blogs;
|
||||
|
||||
import org.briarproject.api.FormatException;
|
||||
import org.briarproject.api.contact.Contact;
|
||||
import org.briarproject.api.identity.Author;
|
||||
import org.briarproject.api.sync.Group;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -11,6 +12,9 @@ public interface BlogFactory {
|
||||
Blog createBlog(@NotNull String name, @NotNull String description,
|
||||
@NotNull Author author);
|
||||
|
||||
/** Creates a personal blog for a given author. */
|
||||
Blog createPersonalBlog(@NotNull Author author);
|
||||
|
||||
/** Parses a blog with the given Group and description */
|
||||
Blog parseBlog(@NotNull Group g, @NotNull String description)
|
||||
throws FormatException;
|
||||
|
||||
@@ -2,6 +2,7 @@ package org.briarproject.api.blogs;
|
||||
|
||||
import org.briarproject.api.db.DbException;
|
||||
import org.briarproject.api.db.Transaction;
|
||||
import org.briarproject.api.identity.Author;
|
||||
import org.briarproject.api.identity.LocalAuthor;
|
||||
import org.briarproject.api.sync.ClientId;
|
||||
import org.briarproject.api.sync.GroupId;
|
||||
@@ -31,9 +32,12 @@ public interface BlogManager {
|
||||
/** Returns the blog with the given ID. */
|
||||
Blog getBlog(Transaction txn, GroupId g) throws DbException;
|
||||
|
||||
/** Returns all blogs to which the localAuthor created. */
|
||||
/** Returns all blogs owned by the given localAuthor. */
|
||||
Collection<Blog> getBlogs(LocalAuthor localAuthor) throws DbException;
|
||||
|
||||
/** Returns only the personal blog of the given author. */
|
||||
Blog getPersonalBlog(Author author) throws DbException;
|
||||
|
||||
/** Returns all blogs to which the user subscribes. */
|
||||
Collection<Blog> getBlogs() throws DbException;
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ import org.briarproject.api.FormatException;
|
||||
import org.briarproject.api.blogs.Blog;
|
||||
import org.briarproject.api.blogs.BlogFactory;
|
||||
import org.briarproject.api.clients.ClientHelper;
|
||||
import org.briarproject.api.contact.Contact;
|
||||
import org.briarproject.api.data.BdfList;
|
||||
import org.briarproject.api.identity.Author;
|
||||
import org.briarproject.api.identity.AuthorFactory;
|
||||
@@ -13,6 +14,8 @@ import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import static org.briarproject.api.blogs.BlogConstants.PERSONAL_BLOG_NAME;
|
||||
|
||||
class BlogFactoryImpl implements BlogFactory {
|
||||
|
||||
private final GroupFactory groupFactory;
|
||||
@@ -31,6 +34,16 @@ class BlogFactoryImpl implements BlogFactory {
|
||||
@Override
|
||||
public Blog createBlog(@NotNull String name, @NotNull String description,
|
||||
@NotNull Author author) {
|
||||
return createBlog(name, description, author, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Blog createPersonalBlog(@NotNull Author a) {
|
||||
return createBlog(PERSONAL_BLOG_NAME, "", a, true);
|
||||
}
|
||||
|
||||
private Blog createBlog(@NotNull String name, @NotNull String description,
|
||||
@NotNull Author author, boolean permanent) {
|
||||
try {
|
||||
BdfList blog = BdfList.of(
|
||||
name,
|
||||
@@ -40,7 +53,7 @@ class BlogFactoryImpl implements BlogFactory {
|
||||
byte[] descriptor = clientHelper.toByteArray(blog);
|
||||
Group g = groupFactory
|
||||
.createGroup(BlogManagerImpl.CLIENT_ID, descriptor);
|
||||
return new Blog(g, name, description, author);
|
||||
return new Blog(g, name, description, author, permanent);
|
||||
} catch (FormatException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
@@ -55,7 +68,9 @@ class BlogFactoryImpl implements BlogFactory {
|
||||
BdfList blog = clientHelper.toList(descriptor, 0, descriptor.length);
|
||||
Author a =
|
||||
authorFactory.createAuthor(blog.getString(1), blog.getRaw(2));
|
||||
return new Blog(g, blog.getString(0), description, a);
|
||||
// TODO change permanent depending on how this will be used
|
||||
boolean permanent = false;
|
||||
return new Blog(g, blog.getString(0), description, a, permanent);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -6,7 +6,10 @@ import org.briarproject.api.blogs.BlogFactory;
|
||||
import org.briarproject.api.blogs.BlogManager;
|
||||
import org.briarproject.api.blogs.BlogPost;
|
||||
import org.briarproject.api.blogs.BlogPostHeader;
|
||||
import org.briarproject.api.clients.Client;
|
||||
import org.briarproject.api.clients.ClientHelper;
|
||||
import org.briarproject.api.contact.Contact;
|
||||
import org.briarproject.api.contact.ContactId;
|
||||
import org.briarproject.api.data.BdfDictionary;
|
||||
import org.briarproject.api.data.BdfEntry;
|
||||
import org.briarproject.api.data.BdfList;
|
||||
@@ -19,6 +22,8 @@ import org.briarproject.api.identity.Author;
|
||||
import org.briarproject.api.identity.Author.Status;
|
||||
import org.briarproject.api.identity.AuthorId;
|
||||
import org.briarproject.api.identity.IdentityManager;
|
||||
import org.briarproject.api.identity.IdentityManager.AddIdentityHook;
|
||||
import org.briarproject.api.identity.IdentityManager.RemoveIdentityHook;
|
||||
import org.briarproject.api.identity.LocalAuthor;
|
||||
import org.briarproject.api.sync.ClientId;
|
||||
import org.briarproject.api.sync.Group;
|
||||
@@ -51,8 +56,12 @@ import static org.briarproject.api.blogs.BlogConstants.KEY_PUBLIC_KEY;
|
||||
import static org.briarproject.api.blogs.BlogConstants.KEY_READ;
|
||||
import static org.briarproject.api.blogs.BlogConstants.KEY_TIMESTAMP;
|
||||
import static org.briarproject.api.blogs.BlogConstants.KEY_TITLE;
|
||||
import static org.briarproject.api.contact.ContactManager.AddContactHook;
|
||||
import static org.briarproject.api.contact.ContactManager.RemoveContactHook;
|
||||
|
||||
class BlogManagerImpl extends BdfIncomingMessageHook implements BlogManager {
|
||||
class BlogManagerImpl extends BdfIncomingMessageHook implements BlogManager,
|
||||
AddContactHook, RemoveContactHook, Client,
|
||||
AddIdentityHook, RemoveIdentityHook {
|
||||
|
||||
private static final Logger LOG =
|
||||
Logger.getLogger(BlogManagerImpl.class.getName());
|
||||
@@ -83,6 +92,68 @@ class BlogManagerImpl extends BdfIncomingMessageHook implements BlogManager {
|
||||
return CLIENT_ID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void createLocalState(Transaction txn) throws DbException {
|
||||
// Ensure every identity does have its own personal blog
|
||||
// TODO this can probably be removed once #446 is resolved and all users migrated to a new version
|
||||
for (LocalAuthor a : db.getLocalAuthors(txn)) {
|
||||
Blog b = blogFactory.createPersonalBlog(a);
|
||||
Group g = b.getGroup();
|
||||
if (!db.containsGroup(txn, g.getId())) {
|
||||
db.addGroup(txn, g);
|
||||
for (ContactId c : db.getContacts(txn, a.getId())) {
|
||||
db.setVisibleToContact(txn, c, g.getId(), true);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Ensure that we have the personal blogs of all pre-existing contacts
|
||||
for (Contact c : db.getContacts(txn)) addingContact(txn, c);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addingContact(Transaction txn, Contact c) throws DbException {
|
||||
// get personal blog of the contact
|
||||
Blog b = blogFactory.createPersonalBlog(c.getAuthor());
|
||||
Group g = b.getGroup();
|
||||
if (!db.containsGroup(txn, g.getId())) {
|
||||
// add the personal blog of the contact
|
||||
db.addGroup(txn, g);
|
||||
db.setVisibleToContact(txn, c.getId(), g.getId(), true);
|
||||
|
||||
// share our personal blog with the new contact
|
||||
LocalAuthor a = db.getLocalAuthor(txn, c.getLocalAuthorId());
|
||||
Blog b2 = blogFactory.createPersonalBlog(a);
|
||||
db.setVisibleToContact(txn, c.getId(), b2.getId(), true);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removingContact(Transaction txn, Contact c) throws DbException {
|
||||
if (c != null) {
|
||||
Blog b = blogFactory.createPersonalBlog(c.getAuthor());
|
||||
db.removeGroup(txn, b.getGroup());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addingIdentity(Transaction txn, LocalAuthor a)
|
||||
throws DbException {
|
||||
|
||||
// add a personal blog for the new identity
|
||||
LOG.info("New Personal Blog Added.");
|
||||
Blog b = blogFactory.createPersonalBlog(a);
|
||||
db.addGroup(txn, b.getGroup());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removingIdentity(Transaction txn, LocalAuthor a)
|
||||
throws DbException {
|
||||
|
||||
// remove the personal blog of that identity
|
||||
Blog b = blogFactory.createPersonalBlog(a);
|
||||
db.removeGroup(txn, b.getGroup());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void incomingMessage(Transaction txn, Message m, BdfList list,
|
||||
BdfDictionary meta) throws DbException, FormatException {
|
||||
@@ -208,6 +279,11 @@ class BlogManagerImpl extends BdfIncomingMessageHook implements BlogManager {
|
||||
return Collections.unmodifiableList(blogs);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Blog getPersonalBlog(Author author) throws DbException {
|
||||
return blogFactory.createPersonalBlog(author);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<Blog> getBlogs() throws DbException {
|
||||
try {
|
||||
@@ -291,7 +367,7 @@ class BlogManagerImpl extends BdfIncomingMessageHook implements BlogManager {
|
||||
private String getBlogDescription(Transaction txn, GroupId g)
|
||||
throws DbException, FormatException {
|
||||
BdfDictionary d = clientHelper.getGroupMetadataAsDictionary(txn, g);
|
||||
return d.getString(KEY_DESCRIPTION);
|
||||
return d.getString(KEY_DESCRIPTION, "");
|
||||
}
|
||||
|
||||
private BlogPostHeader getPostHeaderFromMetadata(@Nullable Transaction txn,
|
||||
@@ -321,5 +397,4 @@ class BlogManagerImpl extends BdfIncomingMessageHook implements BlogManager {
|
||||
return new BlogPostHeader(title, id, parentId, timestamp, author,
|
||||
authorStatus, contentType, read);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -4,11 +4,12 @@ import org.briarproject.api.blogs.BlogFactory;
|
||||
import org.briarproject.api.blogs.BlogManager;
|
||||
import org.briarproject.api.blogs.BlogPostFactory;
|
||||
import org.briarproject.api.clients.ClientHelper;
|
||||
import org.briarproject.api.contact.ContactManager;
|
||||
import org.briarproject.api.crypto.CryptoComponent;
|
||||
import org.briarproject.api.data.MetadataEncoder;
|
||||
import org.briarproject.api.db.DatabaseComponent;
|
||||
import org.briarproject.api.identity.AuthorFactory;
|
||||
import org.briarproject.api.identity.IdentityManager;
|
||||
import org.briarproject.api.lifecycle.LifecycleManager;
|
||||
import org.briarproject.api.sync.GroupFactory;
|
||||
import org.briarproject.api.sync.ValidationManager;
|
||||
import org.briarproject.api.system.Clock;
|
||||
@@ -19,17 +20,31 @@ import javax.inject.Singleton;
|
||||
import dagger.Module;
|
||||
import dagger.Provides;
|
||||
|
||||
import static org.briarproject.blogs.BlogManagerImpl.CLIENT_ID;
|
||||
|
||||
@Module
|
||||
public class BlogsModule {
|
||||
|
||||
public static class EagerSingletons {
|
||||
@Inject
|
||||
BlogPostValidator blogPostValidator;
|
||||
@Inject
|
||||
BlogManager blogManager;
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
BlogManager provideBlogManager(BlogManagerImpl blogManager) {
|
||||
BlogManager provideBlogManager(BlogManagerImpl blogManager,
|
||||
LifecycleManager lifecycleManager, ContactManager contactManager,
|
||||
IdentityManager identityManager,
|
||||
ValidationManager validationManager) {
|
||||
|
||||
lifecycleManager.registerClient(blogManager);
|
||||
contactManager.registerAddContactHook(blogManager);
|
||||
contactManager.registerRemoveContactHook(blogManager);
|
||||
identityManager.registerAddIdentityHook(blogManager);
|
||||
identityManager.registerRemoveIdentityHook(blogManager);
|
||||
validationManager.registerIncomingMessageHook(CLIENT_ID, blogManager);
|
||||
return blogManager;
|
||||
}
|
||||
|
||||
@@ -54,8 +69,7 @@ public class BlogsModule {
|
||||
|
||||
BlogPostValidator validator = new BlogPostValidator(crypto,
|
||||
blogFactory, clientHelper, metadataEncoder, clock);
|
||||
validationManager.registerMessageValidator(
|
||||
BlogManagerImpl.CLIENT_ID, validator);
|
||||
validationManager.registerMessageValidator(CLIENT_ID, validator);
|
||||
|
||||
return validator;
|
||||
}
|
||||
|
||||
@@ -792,6 +792,8 @@ abstract class SharingManagerImpl<S extends Shareable, I extends Invitation, IM
|
||||
} else if (task == TASK_REMOVE_SHAREABLE_FROM_LIST_SHARED_WITH_US) {
|
||||
removeFromList(txn, groupId, SHARED_WITH_US, f);
|
||||
} else if (task == TASK_ADD_SHARED_SHAREABLE) {
|
||||
// TODO we might want to call the add() method of the respective
|
||||
// manager here, because blogs add a description for example
|
||||
db.addGroup(txn, f.getGroup());
|
||||
db.setVisibleToContact(txn, contactId, f.getId(), true);
|
||||
} else if (task == TASK_ADD_SHAREABLE_TO_LIST_TO_BE_SHARED_BY_US) {
|
||||
|
||||
Reference in New Issue
Block a user