mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-13 11:19:04 +01:00
Added a flag for making groups visible to future contacts.
This commit is contained in:
@@ -791,6 +791,13 @@ interface Database<T> {
|
||||
void setTransportUpdateAcked(T txn, ContactId c, TransportId t,
|
||||
long version) throws DbException;
|
||||
|
||||
/**
|
||||
* Makes the given group visible or invisible to future contacts by default.
|
||||
* <p>
|
||||
* Locking: subscription write.
|
||||
*/
|
||||
void setVisibleToAll(T txn, GroupId g, boolean visible) throws DbException;
|
||||
|
||||
/**
|
||||
* Updates the expiry times of the given messages with respect to the given
|
||||
* contact, using the given transmission counts and the latency of the
|
||||
|
||||
@@ -1982,22 +1982,61 @@ DatabaseCleaner.Callback {
|
||||
if(!db.containsSubscription(txn, g))
|
||||
throw new NoSuchSubscriptionException();
|
||||
// Use HashSets for O(1) lookups, O(n) overall running time
|
||||
HashSet<ContactId> newVisible =
|
||||
new HashSet<ContactId>(visible);
|
||||
HashSet<ContactId> oldVisible =
|
||||
new HashSet<ContactId>(db.getVisibility(txn, g));
|
||||
HashSet<ContactId> now = new HashSet<ContactId>(visible);
|
||||
Collection<ContactId> before = db.getVisibility(txn, g);
|
||||
before = new HashSet<ContactId>(before);
|
||||
// Set the group's visibility for each current contact
|
||||
for(ContactId c : db.getContactIds(txn)) {
|
||||
boolean then = oldVisible.contains(c);
|
||||
boolean now = newVisible.contains(c);
|
||||
if(!then && now) {
|
||||
boolean wasBefore = before.contains(c);
|
||||
boolean isNow = now.contains(c);
|
||||
if(!wasBefore && isNow) {
|
||||
db.addVisibility(txn, c, g);
|
||||
affected.add(c);
|
||||
} else if(then && !now) {
|
||||
} else if(wasBefore && !isNow) {
|
||||
db.removeVisibility(txn, c, g);
|
||||
affected.add(c);
|
||||
}
|
||||
}
|
||||
// Make the group invisible to future contacts
|
||||
db.setVisibleToAll(txn, g, false);
|
||||
db.commitTransaction(txn);
|
||||
} catch(DbException e) {
|
||||
db.abortTransaction(txn);
|
||||
throw e;
|
||||
}
|
||||
} finally {
|
||||
subscriptionLock.writeLock().unlock();
|
||||
}
|
||||
} finally {
|
||||
contactLock.readLock().unlock();
|
||||
}
|
||||
if(!affected.isEmpty())
|
||||
callListeners(new LocalSubscriptionsUpdatedEvent(affected));
|
||||
}
|
||||
|
||||
public void setVisibleToAll(GroupId g, boolean visible) throws DbException {
|
||||
Collection<ContactId> affected = new ArrayList<ContactId>();
|
||||
contactLock.readLock().lock();
|
||||
try {
|
||||
subscriptionLock.writeLock().lock();
|
||||
try {
|
||||
T txn = db.startTransaction();
|
||||
try {
|
||||
if(!db.containsSubscription(txn, g))
|
||||
throw new NoSuchSubscriptionException();
|
||||
// Make the group visible or invisible to future contacts
|
||||
db.setVisibleToAll(txn, g, visible);
|
||||
if(visible) {
|
||||
// Make the group visible to all current contacts
|
||||
Collection<ContactId> before = db.getVisibility(txn, g);
|
||||
before = new HashSet<ContactId>(before);
|
||||
for(ContactId c : db.getContactIds(txn)) {
|
||||
if(!before.contains(c)) {
|
||||
db.addVisibility(txn, c, g);
|
||||
affected.add(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
db.commitTransaction(txn);
|
||||
} catch(DbException e) {
|
||||
db.abortTransaction(txn);
|
||||
|
||||
@@ -103,6 +103,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
||||
+ " (groupId HASH NOT NULL,"
|
||||
+ " name VARCHAR NOT NULL,"
|
||||
+ " publicKey BINARY," // Null for unrestricted groups
|
||||
+ " visibleToAll BOOLEAN NOT NULL,"
|
||||
+ " PRIMARY KEY (groupId))";
|
||||
|
||||
// Locking: subscription
|
||||
@@ -573,6 +574,27 @@ abstract class JdbcDatabase implements Database<Connection> {
|
||||
if(rs.next()) throw new DbStateException();
|
||||
rs.close();
|
||||
ps.close();
|
||||
// Make groups that are visible to everyone visible to this contact
|
||||
sql = "SELECT groupId FROM groups WHERE visibleToAll = TRUE";
|
||||
ps = txn.prepareStatement(sql);
|
||||
rs = ps.executeQuery();
|
||||
Collection<byte[]> ids = new ArrayList<byte[]>();
|
||||
while(rs.next()) ids.add(rs.getBytes(1));
|
||||
rs.close();
|
||||
ps.close();
|
||||
if(!ids.isEmpty()) {
|
||||
sql = "INSERT INTO groupVisibilities (contactId, groupId)"
|
||||
+ " VALUES (?, ?)";
|
||||
ps = txn.prepareStatement(sql);
|
||||
ps.setInt(1, c.getInt());
|
||||
for(byte[] id : ids) {
|
||||
ps.setBytes(2, id);
|
||||
ps.addBatch();
|
||||
}
|
||||
affected = ps.executeUpdate();
|
||||
if(affected != ids.size()) throw new DbStateException();
|
||||
ps.close();
|
||||
}
|
||||
// Create a connection time row
|
||||
sql = "INSERT INTO connectionTimes (contactId, lastConnected)"
|
||||
+ " VALUES (?, ?)";
|
||||
@@ -893,8 +915,8 @@ abstract class JdbcDatabase implements Database<Connection> {
|
||||
ps.close();
|
||||
if(count > MAX_SUBSCRIPTIONS) throw new DbStateException();
|
||||
if(count == MAX_SUBSCRIPTIONS) return false;
|
||||
sql = "INSERT INTO groups (groupId, name, publicKey)"
|
||||
+ " VALUES (?, ?, ?)";
|
||||
sql = "INSERT INTO groups (groupId, name, publicKey, visibleToAll)"
|
||||
+ " VALUES (?, ?, ?, FALSE)";
|
||||
ps = txn.prepareStatement(sql);
|
||||
ps.setBytes(1, g.getId().getBytes());
|
||||
ps.setString(2, g.getName());
|
||||
@@ -3376,6 +3398,23 @@ abstract class JdbcDatabase implements Database<Connection> {
|
||||
}
|
||||
}
|
||||
|
||||
public void setVisibleToAll(Connection txn, GroupId g, boolean visible)
|
||||
throws DbException {
|
||||
PreparedStatement ps = null;
|
||||
try {
|
||||
String sql = "UPDATE groups SET visibleToAll = ? WHERE groupId = ?";
|
||||
ps = txn.prepareStatement(sql);
|
||||
ps.setBoolean(1, visible);
|
||||
ps.setBytes(2, g.getBytes());
|
||||
int affected = ps.executeUpdate();
|
||||
if(affected > 1) throw new DbStateException();
|
||||
ps.close();
|
||||
} catch(SQLException e) {
|
||||
tryToClose(ps);
|
||||
throw new DbException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public void updateExpiryTimes(Connection txn, ContactId c,
|
||||
Map<MessageId, Integer> sent, long maxLatency) throws DbException {
|
||||
long now = clock.currentTimeMillis();
|
||||
|
||||
Reference in New Issue
Block a user