Create PrivateGroupManager Facade and stub implementation

This commit is contained in:
Torsten Grote
2016-09-28 16:54:28 -03:00
parent 8b50cb1461
commit 6ece398a21
38 changed files with 691 additions and 146 deletions

View File

@@ -11,10 +11,6 @@ android {
consumerProguardFiles getDefaultProguardFile('proguard-android.txt'), '../briar-android/proguard-rules.txt'
}
dexOptions {
incremental true
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_7
targetCompatibility JavaVersion.VERSION_1_7

View File

@@ -2,13 +2,8 @@ package org.briarproject;
import org.briarproject.api.blogs.BlogManager;
import org.briarproject.api.blogs.BlogSharingManager;
import org.briarproject.api.clients.ClientHelper;
import org.briarproject.api.clients.MessageQueueManager;
import org.briarproject.api.clients.PrivateGroupFactory;
import org.briarproject.api.contact.ContactManager;
import org.briarproject.api.db.DatabaseComponent;
import org.briarproject.api.event.EventBus;
import org.briarproject.api.forum.ForumManager;
import org.briarproject.api.identity.IdentityManager;
import org.briarproject.api.lifecycle.LifecycleManager;
import org.briarproject.api.sync.SyncSessionFactory;
@@ -87,14 +82,4 @@ interface BlogSharingIntegrationTestComponent {
SyncSessionFactory getSyncSessionFactory();
/* the following methods are only needed to manually construct messages */
DatabaseComponent getDatabaseComponent();
PrivateGroupFactory getPrivateGroupFactory();
ClientHelper getClientHelper();
MessageQueueManager getMessageQueueManager();
}

View File

@@ -4,7 +4,7 @@ import net.jodah.concurrentunit.Waiter;
import org.briarproject.api.Bytes;
import org.briarproject.api.clients.MessageQueueManager;
import org.briarproject.api.clients.PrivateGroupFactory;
import org.briarproject.api.clients.ContactGroupFactory;
import org.briarproject.api.clients.SessionId;
import org.briarproject.api.contact.Contact;
import org.briarproject.api.contact.ContactId;
@@ -497,9 +497,9 @@ public class ForumSharingIntegrationTest extends BriarTestCase {
DatabaseComponent db = t0.getDatabaseComponent();
MessageQueueManager queue = t0.getMessageQueueManager();
Contact c1 = contactManager0.getContact(contactId1);
PrivateGroupFactory groupFactory = t0.getPrivateGroupFactory();
ContactGroupFactory groupFactory = t0.getContactGroupFactory();
Group group = groupFactory
.createPrivateGroup(forumSharingManager0.getClientId(), c1);
.createContactGroup(forumSharingManager0.getClientId(), c1);
long time = clock.currentTimeMillis();
BdfList bodyList = BdfList.of(SHARE_MSG_TYPE_INVITATION,
sessionId.getBytes(),
@@ -693,9 +693,9 @@ public class ForumSharingIntegrationTest extends BriarTestCase {
DatabaseComponent db = t0.getDatabaseComponent();
MessageQueueManager queue = t0.getMessageQueueManager();
Contact c1 = contactManager0.getContact(contactId1);
PrivateGroupFactory groupFactory = t0.getPrivateGroupFactory();
ContactGroupFactory groupFactory = t0.getContactGroupFactory();
Group group = groupFactory
.createPrivateGroup(forumSharingManager0.getClientId(), c1);
.createContactGroup(forumSharingManager0.getClientId(), c1);
long time = clock.currentTimeMillis();
// construct a new message re-using the old SessionId

View File

@@ -2,7 +2,7 @@ package org.briarproject;
import org.briarproject.api.clients.ClientHelper;
import org.briarproject.api.clients.MessageQueueManager;
import org.briarproject.api.clients.PrivateGroupFactory;
import org.briarproject.api.clients.ContactGroupFactory;
import org.briarproject.api.contact.ContactManager;
import org.briarproject.api.db.DatabaseComponent;
import org.briarproject.api.event.EventBus;
@@ -90,7 +90,7 @@ interface ForumSharingIntegrationTestComponent {
DatabaseComponent getDatabaseComponent();
PrivateGroupFactory getPrivateGroupFactory();
ContactGroupFactory getContactGroupFactory();
ClientHelper getClientHelper();

View File

@@ -1,15 +1,14 @@
package org.briarproject.api.blogs;
import org.briarproject.api.forum.Forum;
import org.briarproject.api.clients.BaseGroup;
import org.briarproject.api.identity.Author;
import org.briarproject.api.sharing.Shareable;
import org.briarproject.api.sync.Group;
import org.jetbrains.annotations.NotNull;
public class Blog extends Forum {
public class Blog extends BaseGroup implements Shareable {
@NotNull
private final String description;
@NotNull
private final Author author;
public Blog(@NotNull Group group, @NotNull String name,
@@ -29,4 +28,9 @@ public class Blog extends Forum {
public Author getAuthor() {
return author;
}
@Override
public boolean equals(Object o) {
return o instanceof Blog && super.equals(o);
}
}

View File

@@ -0,0 +1,46 @@
package org.briarproject.api.clients;
import org.briarproject.api.sync.Group;
import org.briarproject.api.sync.GroupId;
import org.jetbrains.annotations.NotNull;
public abstract class BaseGroup {
private final Group group;
private final String name;
private final byte[] salt;
public BaseGroup(@NotNull Group group, @NotNull String name, byte[] salt) {
this.group = group;
this.name = name;
this.salt = salt;
}
public GroupId getId() {
return group.getId();
}
public Group getGroup() {
return group;
}
public String getName() {
return name;
}
public byte[] getSalt() {
return salt;
}
@Override
public int hashCode() {
return group.hashCode();
}
@Override
public boolean equals(Object o) {
return o instanceof BaseGroup &&
getGroup().equals(((BaseGroup) o).getGroup());
}
}

View File

@@ -0,0 +1,28 @@
package org.briarproject.api.clients;
import org.briarproject.api.sync.Message;
import org.briarproject.api.sync.MessageId;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public abstract class BaseMessage {
private final Message message;
private final MessageId parent;
public BaseMessage(@NotNull Message message, @Nullable MessageId parent) {
this.message = message;
this.parent = parent;
}
@NotNull
public Message getMessage() {
return message;
}
@Nullable
public MessageId getParent() {
return parent;
}
}

View File

@@ -1,14 +1,14 @@
package org.briarproject.api.messaging;
package org.briarproject.api.clients;
import org.briarproject.api.sync.MessageId;
public abstract class BaseMessage {
public abstract class BaseMessageHeader {
private final MessageId id;
private final long timestamp;
private final boolean local, read, sent, seen;
public BaseMessage(MessageId id, long timestamp, boolean local,
public BaseMessageHeader(MessageId id, long timestamp, boolean local,
boolean read, boolean sent, boolean seen) {
this.id = id;

View File

@@ -3,12 +3,14 @@ package org.briarproject.api.clients;
import org.briarproject.api.contact.Contact;
import org.briarproject.api.sync.ClientId;
import org.briarproject.api.sync.Group;
import org.briarproject.api.sync.GroupFactory;
public interface PrivateGroupFactory {
public interface ContactGroupFactory {
/** Creates a group that is not shared with any contacts. */
Group createLocalGroup(ClientId clientId);
/** Creates a group for the given client to share with the given contact. */
Group createPrivateGroup(ClientId clientId, Contact contact);
Group createContactGroup(ClientId clientId, Contact contact);
}

View File

@@ -1,44 +1,18 @@
package org.briarproject.api.forum;
import org.briarproject.api.clients.BaseGroup;
import org.briarproject.api.sharing.Shareable;
import org.briarproject.api.sync.Group;
import org.briarproject.api.sync.GroupId;
public class Forum implements Shareable {
private final Group group;
private final String name;
private final byte[] salt;
public class Forum extends BaseGroup implements Shareable {
public Forum(Group group, String name, byte[] salt) {
this.group = group;
this.name = name;
this.salt = salt;
}
public GroupId getId() {
return group.getId();
}
public Group getGroup() {
return group;
}
public String getName() {
return name;
}
public byte[] getSalt() {
return salt;
}
@Override
public int hashCode() {
return group.hashCode();
super(group, name, salt);
}
@Override
public boolean equals(Object o) {
return o instanceof Forum && group.equals(((Forum) o).group);
return o instanceof Forum && super.equals(o);
}
}

View File

@@ -1,30 +1,25 @@
package org.briarproject.api.forum;
import org.briarproject.api.clients.BaseMessage;
import org.briarproject.api.identity.Author;
import org.briarproject.api.sync.Message;
import org.briarproject.api.sync.MessageId;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class ForumPost {
public class ForumPost extends BaseMessage {
private final Message message;
private final MessageId parent;
private final Author author;
public ForumPost(Message message, MessageId parent, Author author) {
this.message = message;
this.parent = parent;
public ForumPost(@NotNull Message message, @Nullable MessageId parent,
@Nullable Author author) {
super(message, parent);
this.author = author;
}
public Message getMessage() {
return message;
}
public MessageId getParent() {
return parent;
}
@Nullable
public Author getAuthor() {
return author;
}
}

View File

@@ -1,13 +1,13 @@
package org.briarproject.api.introduction;
import org.briarproject.api.clients.SessionId;
import org.briarproject.api.messaging.BaseMessage;
import org.briarproject.api.clients.BaseMessageHeader;
import org.briarproject.api.sync.MessageId;
import static org.briarproject.api.introduction.IntroductionConstants.ROLE_INTRODUCEE;
import static org.briarproject.api.introduction.IntroductionConstants.ROLE_INTRODUCER;
public class IntroductionMessage extends BaseMessage {
public class IntroductionMessage extends BaseMessageHeader {
private final SessionId sessionId;
private final MessageId messageId;

View File

@@ -1,30 +1,23 @@
package org.briarproject.api.messaging;
import org.briarproject.api.clients.BaseMessage;
import org.briarproject.api.sync.Message;
import org.briarproject.api.sync.MessageId;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class PrivateMessage {
public class PrivateMessage extends BaseMessage {
private final Message message;
private final MessageId parent;
private final String contentType;
public PrivateMessage(Message message, MessageId parent,
String contentType) {
this.message = message;
this.parent = parent;
public PrivateMessage(@NotNull Message message, @Nullable MessageId parent,
@NotNull String contentType) {
super(message, parent);
this.contentType = contentType;
}
public Message getMessage() {
return message;
}
public MessageId getParent() {
return parent;
}
public String getContentType() {
return contentType;
}
}

View File

@@ -1,8 +1,9 @@
package org.briarproject.api.messaging;
import org.briarproject.api.clients.BaseMessageHeader;
import org.briarproject.api.sync.MessageId;
public class PrivateMessageHeader extends BaseMessage {
public class PrivateMessageHeader extends BaseMessageHeader {
private final String contentType;

View File

@@ -0,0 +1,17 @@
package org.briarproject.api.privategroup;
import org.briarproject.api.forum.ForumPost;
import org.briarproject.api.identity.Author;
import org.briarproject.api.sync.Message;
import org.briarproject.api.sync.MessageId;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class GroupMessage extends ForumPost {
public GroupMessage(@NotNull Message message, @Nullable MessageId parent,
@NotNull Author author) {
super(message, parent, author);
}
}

View File

@@ -0,0 +1,20 @@
package org.briarproject.api.privategroup;
import org.briarproject.api.FormatException;
import org.briarproject.api.crypto.PrivateKey;
import org.briarproject.api.identity.Author;
import org.briarproject.api.identity.LocalAuthor;
import org.briarproject.api.sync.GroupId;
import org.briarproject.api.sync.MessageId;
import org.jetbrains.annotations.NotNull;
import java.security.GeneralSecurityException;
public interface GroupMessageFactory {
@NotNull
GroupMessage createGroupMessage(GroupId groupId, long timestamp,
MessageId parent, LocalAuthor author, String body)
throws FormatException, GeneralSecurityException;
}

View File

@@ -0,0 +1,14 @@
package org.briarproject.api.privategroup;
import org.briarproject.api.clients.PostHeader;
import org.briarproject.api.identity.Author;
import org.briarproject.api.sync.MessageId;
public class GroupMessageHeader extends PostHeader {
public GroupMessageHeader(MessageId id, MessageId parentId, long timestamp,
Author author, Author.Status authorStatus, boolean read) {
super(id, parentId, timestamp, author, authorStatus, read);
}
}

View File

@@ -0,0 +1,27 @@
package org.briarproject.api.privategroup;
import org.briarproject.api.clients.BaseGroup;
import org.briarproject.api.identity.Author;
import org.briarproject.api.sync.Group;
import org.jetbrains.annotations.NotNull;
public class PrivateGroup extends BaseGroup {
private final Author author;
public PrivateGroup(@NotNull Group group, @NotNull String name,
@NotNull Author author, @NotNull byte[] salt) {
super(group, name, salt);
this.author = author;
}
public Author getAuthor() {
return author;
}
@Override
public boolean equals(Object o) {
return o instanceof PrivateGroup && super.equals(o);
}
}

View File

@@ -0,0 +1,22 @@
package org.briarproject.api.privategroup;
import static org.briarproject.api.sync.SyncConstants.MAX_MESSAGE_BODY_LENGTH;
public interface PrivateGroupConstants {
/**
* The maximum length of a group's name in UTF-8 bytes.
*/
int MAX_GROUP_NAME_LENGTH = 100;
/**
* The length of a group's random salt in bytes.
*/
int GROUP_SALT_LENGTH = 32;
/**
* The maximum length of a group post's body in bytes.
*/
int MAX_GROUP_POST_BODY_LENGTH = MAX_MESSAGE_BODY_LENGTH - 1024;
}

View File

@@ -0,0 +1,20 @@
package org.briarproject.api.privategroup;
import org.briarproject.api.identity.Author;
import org.jetbrains.annotations.NotNull;
public interface PrivateGroupFactory {
/**
* Creates a private group with the given name and author.
*/
@NotNull
PrivateGroup createPrivateGroup(String name, Author author);
/**
* Creates a private group with the given name, author and salt.
*/
@NotNull
PrivateGroup createPrivateGroup(String name, Author author, byte[] salt);
}

View File

@@ -0,0 +1,46 @@
package org.briarproject.api.privategroup;
import org.briarproject.api.db.DbException;
import org.briarproject.api.db.Transaction;
import org.briarproject.api.sync.ClientId;
import org.briarproject.api.sync.GroupId;
import org.briarproject.api.sync.MessageId;
import org.jetbrains.annotations.NotNull;
import java.util.Collection;
public interface PrivateGroupManager {
/** Returns the unique ID of the private group client. */
@NotNull
ClientId getClientId();
/** Stores (and sends) a local group message. */
void addLocalMessage(GroupMessage p) throws DbException;
/** Returns the private group with the given ID. */
@NotNull
PrivateGroup getPrivateGroup(GroupId g) throws DbException;
/**
* Returns the private group with the given ID within the given transaction.
*/
@NotNull
PrivateGroup getPrivateGroup(Transaction txn, GroupId g) throws DbException;
/** Returns all private groups the user is a member of. */
@NotNull
Collection<PrivateGroup> getPrivateGroups() throws DbException;
/** Returns the body of the group message with the given ID. */
@NotNull
String getMessageBody(MessageId m) throws DbException;
/** Returns the headers of all group messages in the given group. */
@NotNull
Collection<GroupMessageHeader> getHeaders(GroupId g) throws DbException;
/** Marks a group message as read or unread. */
void setReadFlag(MessageId m, boolean read) throws DbException;
}

View File

@@ -2,10 +2,10 @@ package org.briarproject.api.sharing;
import org.briarproject.api.clients.SessionId;
import org.briarproject.api.contact.ContactId;
import org.briarproject.api.messaging.BaseMessage;
import org.briarproject.api.clients.BaseMessageHeader;
import org.briarproject.api.sync.MessageId;
public abstract class InvitationMessage extends BaseMessage {
public abstract class InvitationMessage extends BaseMessageHeader {
private final SessionId sessionId;
private final ContactId contactId;

View File

@@ -2,7 +2,7 @@ package org.briarproject.clients;
import org.briarproject.api.clients.ClientHelper;
import org.briarproject.api.clients.MessageQueueManager;
import org.briarproject.api.clients.PrivateGroupFactory;
import org.briarproject.api.clients.ContactGroupFactory;
import org.briarproject.api.clients.QueueMessageFactory;
import org.briarproject.api.crypto.CryptoComponent;
import org.briarproject.api.data.BdfReaderFactory;
@@ -33,9 +33,9 @@ public class ClientsModule {
}
@Provides
PrivateGroupFactory providePrivateGroupFactory(GroupFactory groupFactory,
ContactGroupFactory providePrivateGroupFactory(GroupFactory groupFactory,
ClientHelper clientHelper) {
return new PrivateGroupFactoryImpl(groupFactory, clientHelper);
return new ContactGroupFactoryImpl(groupFactory, clientHelper);
}
@Provides

View File

@@ -4,7 +4,7 @@ package org.briarproject.clients;
import org.briarproject.api.Bytes;
import org.briarproject.api.FormatException;
import org.briarproject.api.clients.ClientHelper;
import org.briarproject.api.clients.PrivateGroupFactory;
import org.briarproject.api.clients.ContactGroupFactory;
import org.briarproject.api.contact.Contact;
import org.briarproject.api.data.BdfList;
import org.briarproject.api.identity.AuthorId;
@@ -14,7 +14,7 @@ import org.briarproject.api.sync.GroupFactory;
import javax.inject.Inject;
class PrivateGroupFactoryImpl implements PrivateGroupFactory {
class ContactGroupFactoryImpl implements ContactGroupFactory {
private static final byte[] LOCAL_GROUP_DESCRIPTOR = new byte[0];
@@ -22,7 +22,7 @@ class PrivateGroupFactoryImpl implements PrivateGroupFactory {
private final ClientHelper clientHelper;
@Inject
PrivateGroupFactoryImpl(GroupFactory groupFactory,
ContactGroupFactoryImpl(GroupFactory groupFactory,
ClientHelper clientHelper) {
this.groupFactory = groupFactory;
this.clientHelper = clientHelper;
@@ -34,7 +34,7 @@ class PrivateGroupFactoryImpl implements PrivateGroupFactory {
}
@Override
public Group createPrivateGroup(ClientId clientId, Contact contact) {
public Group createContactGroup(ClientId clientId, Contact contact) {
AuthorId local = contact.getLocalAuthorId();
AuthorId remote = contact.getAuthor().getId();
byte[] descriptor = createGroupDescriptor(local, remote);

View File

@@ -15,7 +15,7 @@ import org.briarproject.api.blogs.BlogPost;
import org.briarproject.api.blogs.BlogPostFactory;
import org.briarproject.api.clients.Client;
import org.briarproject.api.clients.ClientHelper;
import org.briarproject.api.clients.PrivateGroupFactory;
import org.briarproject.api.clients.ContactGroupFactory;
import org.briarproject.api.data.BdfDictionary;
import org.briarproject.api.data.BdfEntry;
import org.briarproject.api.data.BdfList;
@@ -42,7 +42,6 @@ import java.io.IOException;
import java.io.InputStream;
import java.security.GeneralSecurityException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
@@ -86,7 +85,7 @@ class FeedManagerImpl implements FeedManager, Client, EventListener {
private final ScheduledExecutorService feedExecutor;
private final Executor ioExecutor;
private final DatabaseComponent db;
private final PrivateGroupFactory privateGroupFactory;
private final ContactGroupFactory contactGroupFactory;
private final ClientHelper clientHelper;
private final IdentityManager identityManager;
private final BlogManager blogManager;
@@ -103,14 +102,14 @@ class FeedManagerImpl implements FeedManager, Client, EventListener {
@Inject
FeedManagerImpl(ScheduledExecutorService feedExecutor,
@IoExecutor Executor ioExecutor, DatabaseComponent db,
PrivateGroupFactory privateGroupFactory, ClientHelper clientHelper,
ContactGroupFactory contactGroupFactory, ClientHelper clientHelper,
IdentityManager identityManager, BlogManager blogManager,
SocketFactory torSocketFactory) {
this.feedExecutor = feedExecutor;
this.ioExecutor = ioExecutor;
this.db = db;
this.privateGroupFactory = privateGroupFactory;
this.contactGroupFactory = contactGroupFactory;
this.clientHelper = clientHelper;
this.identityManager = identityManager;
this.blogManager = blogManager;
@@ -518,7 +517,7 @@ class FeedManagerImpl implements FeedManager, Client, EventListener {
}
private Group getLocalGroup() {
return privateGroupFactory.createLocalGroup(getClientId());
return contactGroupFactory.createLocalGroup(getClientId());
}
}

View File

@@ -1,6 +1,6 @@
package org.briarproject.introduction;
import org.briarproject.api.clients.PrivateGroupFactory;
import org.briarproject.api.clients.ContactGroupFactory;
import org.briarproject.api.contact.Contact;
import org.briarproject.api.sync.Group;
@@ -8,19 +8,19 @@ import javax.inject.Inject;
public class IntroductionGroupFactory {
final private PrivateGroupFactory privateGroupFactory;
final private ContactGroupFactory contactGroupFactory;
final private Group localGroup;
@Inject
IntroductionGroupFactory(PrivateGroupFactory privateGroupFactory) {
this.privateGroupFactory = privateGroupFactory;
localGroup = privateGroupFactory
IntroductionGroupFactory(ContactGroupFactory contactGroupFactory) {
this.contactGroupFactory = contactGroupFactory;
localGroup = contactGroupFactory
.createLocalGroup(IntroductionManagerImpl.CLIENT_ID);
}
public Group createIntroductionGroup(Contact c) {
return privateGroupFactory
.createPrivateGroup(IntroductionManagerImpl.CLIENT_ID, c);
return contactGroupFactory
.createContactGroup(IntroductionManagerImpl.CLIENT_ID, c);
}
public Group createLocalGroup() {

View File

@@ -3,7 +3,7 @@ package org.briarproject.messaging;
import org.briarproject.api.FormatException;
import org.briarproject.api.clients.Client;
import org.briarproject.api.clients.ClientHelper;
import org.briarproject.api.clients.PrivateGroupFactory;
import org.briarproject.api.clients.ContactGroupFactory;
import org.briarproject.api.contact.Contact;
import org.briarproject.api.contact.ContactId;
import org.briarproject.api.contact.ContactManager.AddContactHook;
@@ -41,16 +41,16 @@ class MessagingManagerImpl extends BdfIncomingMessageHook
+ "8bf9a6d6021d40d219c86b731b903070"));
private final DatabaseComponent db;
private final PrivateGroupFactory privateGroupFactory;
private final ContactGroupFactory contactGroupFactory;
@Inject
MessagingManagerImpl(DatabaseComponent db, ClientHelper clientHelper,
MetadataParser metadataParser,
PrivateGroupFactory privateGroupFactory) {
ContactGroupFactory contactGroupFactory) {
super(clientHelper, metadataParser);
this.db = db;
this.privateGroupFactory = privateGroupFactory;
this.contactGroupFactory = contactGroupFactory;
}
@Override
@@ -79,7 +79,7 @@ class MessagingManagerImpl extends BdfIncomingMessageHook
}
private Group getContactGroup(Contact c) {
return privateGroupFactory.createPrivateGroup(CLIENT_ID, c);
return contactGroupFactory.createContactGroup(CLIENT_ID, c);
}
@Override

View File

@@ -0,0 +1,8 @@
package org.briarproject.privategroup;
interface Constants {
// Database keys
String KEY_READ = "read";
}

View File

@@ -0,0 +1,43 @@
package org.briarproject.privategroup;
import org.briarproject.api.FormatException;
import org.briarproject.api.clients.ClientHelper;
import org.briarproject.api.data.BdfList;
import org.briarproject.api.identity.LocalAuthor;
import org.briarproject.api.privategroup.GroupMessage;
import org.briarproject.api.privategroup.GroupMessageFactory;
import org.briarproject.api.sync.GroupId;
import org.briarproject.api.sync.Message;
import org.briarproject.api.sync.MessageId;
import org.jetbrains.annotations.NotNull;
import java.security.GeneralSecurityException;
import javax.inject.Inject;
class GroupMessageFactoryImpl implements GroupMessageFactory {
private final ClientHelper clientHelper;
@Inject
GroupMessageFactoryImpl(ClientHelper clientHelper) {
this.clientHelper = clientHelper;
}
@NotNull
@Override
public GroupMessage createGroupMessage(GroupId groupId, long timestamp,
MessageId parent, LocalAuthor author, String body)
throws FormatException, GeneralSecurityException {
// Generate the signature
byte[] sig = clientHelper.sign(new BdfList(), author.getPrivateKey());
// Compose the message
Message m =
clientHelper.createMessage(groupId, timestamp, new BdfList());
return new GroupMessage(m, parent, author);
}
}

View File

@@ -0,0 +1,43 @@
package org.briarproject.privategroup;
import org.briarproject.api.FormatException;
import org.briarproject.api.clients.BdfMessageContext;
import org.briarproject.api.clients.ClientHelper;
import org.briarproject.api.crypto.CryptoComponent;
import org.briarproject.api.data.BdfDictionary;
import org.briarproject.api.data.BdfList;
import org.briarproject.api.data.MetadataEncoder;
import org.briarproject.api.identity.AuthorFactory;
import org.briarproject.api.sync.Group;
import org.briarproject.api.sync.InvalidMessageException;
import org.briarproject.api.sync.Message;
import org.briarproject.api.sync.MessageId;
import org.briarproject.api.system.Clock;
import org.briarproject.clients.BdfMessageValidator;
import java.util.Collection;
import java.util.Collections;
class GroupMessageValidator extends BdfMessageValidator {
private final CryptoComponent crypto;
private final AuthorFactory authorFactory;
GroupMessageValidator(CryptoComponent crypto, AuthorFactory authorFactory,
ClientHelper clientHelper, MetadataEncoder metadataEncoder,
Clock clock) {
super(clientHelper, metadataEncoder, clock);
this.crypto = crypto;
this.authorFactory = authorFactory;
}
@Override
protected BdfMessageContext validateMessage(Message m, Group g,
BdfList body) throws InvalidMessageException, FormatException {
BdfDictionary meta = new BdfDictionary();
Collection<MessageId> dependencies = Collections.emptyList();
return new BdfMessageContext(meta, dependencies);
}
}

View File

@@ -0,0 +1,69 @@
package org.briarproject.privategroup;
import org.briarproject.api.FormatException;
import org.briarproject.api.clients.ClientHelper;
import org.briarproject.api.data.BdfList;
import org.briarproject.api.identity.Author;
import org.briarproject.api.privategroup.PrivateGroup;
import org.briarproject.api.privategroup.PrivateGroupFactory;
import org.briarproject.api.sync.Group;
import org.briarproject.api.sync.GroupFactory;
import org.briarproject.util.StringUtils;
import org.jetbrains.annotations.NotNull;
import java.security.SecureRandom;
import javax.inject.Inject;
import static org.briarproject.api.privategroup.PrivateGroupConstants.GROUP_SALT_LENGTH;
import static org.briarproject.api.privategroup.PrivateGroupConstants.MAX_GROUP_NAME_LENGTH;
class PrivateGroupFactoryImpl implements PrivateGroupFactory {
private final GroupFactory groupFactory;
private final ClientHelper clientHelper;
private final SecureRandom random;
@Inject
PrivateGroupFactoryImpl(GroupFactory groupFactory,
ClientHelper clientHelper, SecureRandom random) {
this.groupFactory = groupFactory;
this.clientHelper = clientHelper;
this.random = random;
}
@NotNull
@Override
public PrivateGroup createPrivateGroup(String name, Author author) {
int length = StringUtils.toUtf8(name).length;
if (length == 0) throw new IllegalArgumentException("Group name empty");
if (length > MAX_GROUP_NAME_LENGTH)
throw new IllegalArgumentException(
"Group name exceeds maximum length");
byte[] salt = new byte[GROUP_SALT_LENGTH];
random.nextBytes(salt);
return createPrivateGroup(name, author, salt);
}
@NotNull
@Override
public PrivateGroup createPrivateGroup(String name, Author author,
byte[] salt) {
try {
BdfList group = BdfList.of(
name,
author.getName(),
author.getPublicKey(),
salt
);
byte[] descriptor = clientHelper.toByteArray(group);
Group g = groupFactory
.createGroup(PrivateGroupManagerImpl.CLIENT_ID, descriptor);
return new PrivateGroup(g, name, author, salt);
} catch (FormatException e) {
throw new RuntimeException(e);
}
}
}

View File

@@ -0,0 +1,125 @@
package org.briarproject.privategroup;
import org.briarproject.api.FormatException;
import org.briarproject.api.clients.ClientHelper;
import org.briarproject.api.data.BdfDictionary;
import org.briarproject.api.data.BdfList;
import org.briarproject.api.data.MetadataParser;
import org.briarproject.api.db.DatabaseComponent;
import org.briarproject.api.db.DbException;
import org.briarproject.api.db.Transaction;
import org.briarproject.api.identity.Author;
import org.briarproject.api.identity.IdentityManager;
import org.briarproject.api.privategroup.GroupMessage;
import org.briarproject.api.privategroup.GroupMessageHeader;
import org.briarproject.api.privategroup.PrivateGroup;
import org.briarproject.api.privategroup.PrivateGroupFactory;
import org.briarproject.api.privategroup.PrivateGroupManager;
import org.briarproject.api.sync.ClientId;
import org.briarproject.api.sync.GroupId;
import org.briarproject.api.sync.Message;
import org.briarproject.api.sync.MessageId;
import org.briarproject.clients.BdfIncomingMessageHook;
import org.briarproject.util.StringUtils;
import org.jetbrains.annotations.NotNull;
import java.util.Collection;
import java.util.Collections;
import javax.inject.Inject;
import static org.briarproject.privategroup.Constants.KEY_READ;
public class PrivateGroupManagerImpl extends BdfIncomingMessageHook implements
PrivateGroupManager {
static final ClientId CLIENT_ID = new ClientId(
StringUtils.fromHexString("5072697661746547726f75704d616e61"
+ "67657220627920546f727374656e2047"));
private final DatabaseComponent db;
private final IdentityManager identityManager;
private final PrivateGroupFactory privateGroupFactory;
@Inject
PrivateGroupManagerImpl(ClientHelper clientHelper,
MetadataParser metadataParser, DatabaseComponent db,
IdentityManager identityManager,
PrivateGroupFactory privateGroupFactory) {
super(clientHelper, metadataParser);
this.db = db;
this.identityManager = identityManager;
this.privateGroupFactory = privateGroupFactory;
}
@NotNull
@Override
public ClientId getClientId() {
return CLIENT_ID;
}
@Override
public void addLocalMessage(GroupMessage m) throws DbException {
try {
BdfDictionary meta = new BdfDictionary();
clientHelper.addLocalMessage(m.getMessage(), meta, true);
} catch (FormatException e) {
throw new DbException(e);
}
}
@NotNull
@Override
public PrivateGroup getPrivateGroup(GroupId g) throws DbException {
Author a = identityManager.getLocalAuthor();
return privateGroupFactory.createPrivateGroup("todo", a);
}
@NotNull
@Override
public PrivateGroup getPrivateGroup(Transaction txn, GroupId g)
throws DbException {
Author a = identityManager.getLocalAuthor(txn);
return privateGroupFactory.createPrivateGroup("todo", a);
}
@NotNull
@Override
public Collection<PrivateGroup> getPrivateGroups() throws DbException {
return Collections.emptyList();
}
@NotNull
@Override
public String getMessageBody(MessageId m) throws DbException {
return "empty";
}
@NotNull
@Override
public Collection<GroupMessageHeader> getHeaders(GroupId g)
throws DbException {
return Collections.emptyList();
}
@Override
public void setReadFlag(MessageId m, boolean read) throws DbException {
try {
BdfDictionary meta = new BdfDictionary();
meta.put(KEY_READ, read);
clientHelper.mergeMessageMetadata(m, meta);
} catch (FormatException e) {
throw new RuntimeException(e);
}
}
@Override
protected boolean incomingMessage(Transaction txn, Message m, BdfList body,
BdfDictionary meta) throws DbException, FormatException {
return true;
}
}

View File

@@ -0,0 +1,68 @@
package org.briarproject.privategroup;
import org.briarproject.api.clients.ClientHelper;
import org.briarproject.api.crypto.CryptoComponent;
import org.briarproject.api.data.MetadataEncoder;
import org.briarproject.api.identity.AuthorFactory;
import org.briarproject.api.privategroup.GroupMessageFactory;
import org.briarproject.api.privategroup.PrivateGroupFactory;
import org.briarproject.api.privategroup.PrivateGroupManager;
import org.briarproject.api.sync.GroupFactory;
import org.briarproject.api.sync.ValidationManager;
import org.briarproject.api.system.Clock;
import java.security.SecureRandom;
import javax.inject.Inject;
import javax.inject.Singleton;
import dagger.Module;
import dagger.Provides;
@Module
public class PrivateGroupModule {
public static class EagerSingletons {
@Inject
GroupMessageValidator groupMessageValidator;
}
@Provides
@Singleton
PrivateGroupManager provideForumManager(
PrivateGroupManagerImpl groupManager,
ValidationManager validationManager) {
validationManager
.registerIncomingMessageHook(groupManager.getClientId(),
groupManager);
return groupManager;
}
@Provides
PrivateGroupFactory providePrivateGroupFactory(
PrivateGroupFactoryImpl privateGroupFactory) {
return privateGroupFactory;
}
@Provides
GroupMessageFactory provideGroupMessageFactory(
GroupMessageFactoryImpl groupMessageFactory) {
return groupMessageFactory;
}
@Provides
@Singleton
GroupMessageValidator provideGroupMessageValidator(
ValidationManager validationManager, CryptoComponent crypto,
AuthorFactory authorFactory, ClientHelper clientHelper,
MetadataEncoder metadataEncoder, Clock clock) {
GroupMessageValidator validator = new GroupMessageValidator(crypto,
authorFactory, clientHelper, metadataEncoder, clock);
validationManager.registerMessageValidator(
PrivateGroupManagerImpl.CLIENT_ID, validator);
return validator;
}
}

View File

@@ -4,7 +4,7 @@ import org.briarproject.api.FormatException;
import org.briarproject.api.TransportId;
import org.briarproject.api.clients.Client;
import org.briarproject.api.clients.ClientHelper;
import org.briarproject.api.clients.PrivateGroupFactory;
import org.briarproject.api.clients.ContactGroupFactory;
import org.briarproject.api.contact.Contact;
import org.briarproject.api.contact.ContactId;
import org.briarproject.api.contact.ContactManager.AddContactHook;
@@ -40,19 +40,19 @@ class TransportPropertyManagerImpl implements TransportPropertyManager,
private final DatabaseComponent db;
private final ClientHelper clientHelper;
private final PrivateGroupFactory privateGroupFactory;
private final ContactGroupFactory contactGroupFactory;
private final Clock clock;
private final Group localGroup;
@Inject
TransportPropertyManagerImpl(DatabaseComponent db,
ClientHelper clientHelper, PrivateGroupFactory privateGroupFactory,
ClientHelper clientHelper, ContactGroupFactory contactGroupFactory,
Clock clock) {
this.db = db;
this.clientHelper = clientHelper;
this.privateGroupFactory = privateGroupFactory;
this.contactGroupFactory = contactGroupFactory;
this.clock = clock;
localGroup = privateGroupFactory.createLocalGroup(CLIENT_ID);
localGroup = contactGroupFactory.createLocalGroup(CLIENT_ID);
}
@Override
@@ -232,7 +232,7 @@ class TransportPropertyManagerImpl implements TransportPropertyManager,
}
private Group getContactGroup(Contact c) {
return privateGroupFactory.createPrivateGroup(CLIENT_ID, c);
return contactGroupFactory.createContactGroup(CLIENT_ID, c);
}
private void storeMessage(Transaction txn, GroupId g, TransportId t,

View File

@@ -11,7 +11,7 @@ import org.briarproject.api.blogs.BlogSharingManager;
import org.briarproject.api.blogs.BlogSharingMessage.BlogInvitation;
import org.briarproject.api.clients.ClientHelper;
import org.briarproject.api.clients.MessageQueueManager;
import org.briarproject.api.clients.PrivateGroupFactory;
import org.briarproject.api.clients.ContactGroupFactory;
import org.briarproject.api.clients.SessionId;
import org.briarproject.api.contact.Contact;
import org.briarproject.api.contact.ContactId;
@@ -68,10 +68,10 @@ class BlogSharingManagerImpl extends
BlogManager blogManager, ClientHelper clientHelper, Clock clock,
DatabaseComponent db, MessageQueueManager messageQueueManager,
MetadataEncoder metadataEncoder, MetadataParser metadataParser,
PrivateGroupFactory privateGroupFactory, SecureRandom random) {
ContactGroupFactory contactGroupFactory, SecureRandom random) {
super(db, messageQueueManager, clientHelper, metadataParser,
metadataEncoder, random, privateGroupFactory, clock);
metadataEncoder, random, contactGroupFactory, clock);
this.blogManager = blogManager;
sFactory = new SFactory(authorFactory, blogFactory, blogManager);

View File

@@ -3,7 +3,7 @@ package org.briarproject.sharing;
import org.briarproject.api.FormatException;
import org.briarproject.api.clients.ClientHelper;
import org.briarproject.api.clients.MessageQueueManager;
import org.briarproject.api.clients.PrivateGroupFactory;
import org.briarproject.api.clients.ContactGroupFactory;
import org.briarproject.api.clients.SessionId;
import org.briarproject.api.contact.ContactId;
import org.briarproject.api.data.BdfDictionary;
@@ -59,10 +59,10 @@ class ForumSharingManagerImpl extends
MessageQueueManager messageQueueManager,
MetadataEncoder metadataEncoder,
MetadataParser metadataParser,
PrivateGroupFactory privateGroupFactory,
ContactGroupFactory contactGroupFactory,
SecureRandom random) {
super(db, messageQueueManager, clientHelper, metadataParser,
metadataEncoder, random, privateGroupFactory, clock);
metadataEncoder, random, contactGroupFactory, clock);
sFactory = new SFactory(forumFactory, forumManager);
iFactory = new IFactory();

View File

@@ -5,7 +5,7 @@ import org.briarproject.api.FormatException;
import org.briarproject.api.clients.Client;
import org.briarproject.api.clients.ClientHelper;
import org.briarproject.api.clients.MessageQueueManager;
import org.briarproject.api.clients.PrivateGroupFactory;
import org.briarproject.api.clients.ContactGroupFactory;
import org.briarproject.api.clients.SessionId;
import org.briarproject.api.contact.Contact;
import org.briarproject.api.contact.ContactId;
@@ -97,14 +97,14 @@ abstract class SharingManagerImpl<S extends Shareable, I extends Invitation, IS
private final MessageQueueManager messageQueueManager;
private final MetadataEncoder metadataEncoder;
private final SecureRandom random;
private final PrivateGroupFactory privateGroupFactory;
private final ContactGroupFactory contactGroupFactory;
private final Clock clock;
private final Group localGroup;
SharingManagerImpl(DatabaseComponent db,
MessageQueueManager messageQueueManager, ClientHelper clientHelper,
MetadataParser metadataParser, MetadataEncoder metadataEncoder,
SecureRandom random, PrivateGroupFactory privateGroupFactory,
SecureRandom random, ContactGroupFactory contactGroupFactory,
Clock clock) {
super(clientHelper, metadataParser);
@@ -112,9 +112,9 @@ abstract class SharingManagerImpl<S extends Shareable, I extends Invitation, IS
this.messageQueueManager = messageQueueManager;
this.metadataEncoder = metadataEncoder;
this.random = random;
this.privateGroupFactory = privateGroupFactory;
this.contactGroupFactory = contactGroupFactory;
this.clock = clock;
localGroup = privateGroupFactory.createLocalGroup(getClientId());
localGroup = contactGroupFactory.createLocalGroup(getClientId());
}
public abstract ClientId getClientId();
@@ -903,7 +903,7 @@ abstract class SharingManagerImpl<S extends Shareable, I extends Invitation, IS
}
private Group getContactGroup(Contact c) {
return privateGroupFactory.createPrivateGroup(getClientId(), c);
return contactGroupFactory.createContactGroup(getClientId(), c);
}
private ContactId getContactId(Transaction txn, GroupId contactGroupId)

View File

@@ -5,7 +5,7 @@ import org.briarproject.TestUtils;
import org.briarproject.api.FormatException;
import org.briarproject.api.clients.ClientHelper;
import org.briarproject.api.clients.MessageQueueManager;
import org.briarproject.api.clients.PrivateGroupFactory;
import org.briarproject.api.clients.ContactGroupFactory;
import org.briarproject.api.contact.Contact;
import org.briarproject.api.contact.ContactId;
import org.briarproject.api.data.BdfDictionary;
@@ -55,7 +55,7 @@ public class IntroductionManagerImplTest extends BriarTestCase {
final IntroducerManager introducerManager;
final IntroduceeManager introduceeManager;
final DatabaseComponent db;
final PrivateGroupFactory privateGroupFactory;
final ContactGroupFactory contactGroupFactory;
final ClientHelper clientHelper;
final MetadataEncoder metadataEncoder;
final MessageQueueManager messageQueueManager;
@@ -109,7 +109,7 @@ public class IntroductionManagerImplTest extends BriarTestCase {
introducerManager = context.mock(IntroducerManager.class);
introduceeManager = context.mock(IntroduceeManager.class);
db = context.mock(DatabaseComponent.class);
privateGroupFactory = context.mock(PrivateGroupFactory.class);
contactGroupFactory = context.mock(ContactGroupFactory.class);
clientHelper = context.mock(ClientHelper.class);
metadataEncoder =
context.mock(MetadataEncoder.class);