pass comments on trust list subscriptions

pull/24/head
Zlatin Balevsky 2019-11-08 07:37:51 +00:00
parent 6e2b3f4f33
commit 2017b53a43
6 changed files with 117 additions and 44 deletions

View File

@ -379,10 +379,10 @@ class ConnectionAcceptor {
dis.readFully(RUST) dis.readFully(RUST)
if (RUST != "RUST\r\n".getBytes(StandardCharsets.US_ASCII)) if (RUST != "RUST\r\n".getBytes(StandardCharsets.US_ASCII))
throw new IOException("Invalid TRUST connection") throw new IOException("Invalid TRUST connection")
String header
while ((header = DataUtil.readTillRN(dis)) != ""); // ignore headers for now Map<String,String> headers = DataUtil.readAllHeaders(dis)
OutputStream os = e.getOutputStream() OutputStream os = e.getOutputStream()
if (!settings.allowTrustLists) { if (!settings.allowTrustLists) {
os.write("403 Not Allowed\r\n\r\n".getBytes(StandardCharsets.US_ASCII)) os.write("403 Not Allowed\r\n\r\n".getBytes(StandardCharsets.US_ASCII))
os.flush() os.flush()
@ -390,22 +390,53 @@ class ConnectionAcceptor {
return return
} }
os.write("200 OK\r\n\r\n".getBytes(StandardCharsets.US_ASCII)) os.write("200 OK\r\n".getBytes(StandardCharsets.US_ASCII))
boolean json = headers.containsKey('Json') && Boolean.parseBoolean(headers['Json'])
List<TrustService.TrustEntry> good = new ArrayList<>(trustService.good.values()) List<TrustService.TrustEntry> good = new ArrayList<>(trustService.good.values())
int size = Math.min(Short.MAX_VALUE * 2, good.size())
good = good.subList(0, size)
DataOutputStream dos = new DataOutputStream(os)
dos.writeShort(size)
good.each {
it.persona.write(dos)
}
List<TrustService.TrustEntry> bad = new ArrayList<>(trustService.bad.values()) List<TrustService.TrustEntry> bad = new ArrayList<>(trustService.bad.values())
size = Math.min(Short.MAX_VALUE * 2, bad.size()) DataOutputStream dos = new DataOutputStream(os)
bad = bad.subList(0, size)
dos.writeShort(size) if (!json) {
bad.each { os.write("\r\n")
it.persona.write(dos) int size = Math.min(Short.MAX_VALUE * 2, good.size())
good = good.subList(0, size)
dos.writeShort(size)
good.each {
it.persona.write(dos)
}
size = Math.min(Short.MAX_VALUE * 2, bad.size())
bad = bad.subList(0, size)
dos.writeShort(size)
bad.each {
it.persona.write(dos)
}
} else {
dos.write("Json: true\r\n")
dos.write("Good:${good.size()}\r\n")
dos.write("Bad:${bad.size()}\r\n")
dos.write("\r\n")
good.each {
def obj = [:]
obj.persona = it.persona.toBase64()
obj.reason = it.reason
String toJson = JsonOutput.toJson(obj)
byte [] payload = toJson.getBytes(StandardCharsets.US_ASCII)
dos.writeShort(payload.length)
dos.write(payload)
}
bad.each {
def obj = [:]
obj.persona = it.persona.toBase64()
obj.reason = it.reason
String toJson = JsonOutput.toJson(obj)
byte [] payload = toJson.getBytes(StandardCharsets.US_ASCII)
dos.writeShort(payload.length)
dos.write(payload)
}
} }
dos.flush() dos.flush()

View File

@ -3,6 +3,7 @@ package com.muwire.core.trust
import java.util.concurrent.ConcurrentHashMap import java.util.concurrent.ConcurrentHashMap
import com.muwire.core.Persona import com.muwire.core.Persona
import com.muwire.core.trust.TrustService.TrustEntry
import net.i2p.util.ConcurrentHashSet import net.i2p.util.ConcurrentHashSet
@ -10,7 +11,7 @@ class RemoteTrustList {
public enum Status { NEW, UPDATING, UPDATED, UPDATE_FAILED } public enum Status { NEW, UPDATING, UPDATED, UPDATE_FAILED }
private final Persona persona private final Persona persona
private final Set<Persona> good, bad private final Set<TrustEntry> good, bad
volatile long timestamp volatile long timestamp
volatile boolean forceUpdate volatile boolean forceUpdate
Status status = Status.NEW Status status = Status.NEW

View File

@ -136,5 +136,16 @@ class TrustService extends Service {
this.persona = persona this.persona = persona
this.reason = reason this.reason = reason
} }
public int hashCode() {
persona.hashCode()
}
public boolean equals(Object o) {
if (!(o instanceof TrustEntry))
return false
persona == o.persona
}
} }
} }

View File

@ -12,9 +12,12 @@ import com.muwire.core.Persona
import com.muwire.core.UILoadedEvent import com.muwire.core.UILoadedEvent
import com.muwire.core.connection.Endpoint import com.muwire.core.connection.Endpoint
import com.muwire.core.connection.I2PConnector import com.muwire.core.connection.I2PConnector
import com.muwire.core.trust.TrustService.TrustEntry
import com.muwire.core.util.DataUtil import com.muwire.core.util.DataUtil
import groovy.json.JsonSlurper
import groovy.util.logging.Log import groovy.util.logging.Log
import net.i2p.data.Base64
import net.i2p.data.Destination import net.i2p.data.Destination
@Log @Log
@ -109,7 +112,9 @@ class TrustSubscriber {
endpoint = i2pConnector.connect(trustList.persona.destination) endpoint = i2pConnector.connect(trustList.persona.destination)
OutputStream os = endpoint.getOutputStream() OutputStream os = endpoint.getOutputStream()
InputStream is = endpoint.getInputStream() InputStream is = endpoint.getInputStream()
os.write("TRUST\r\n\r\n".getBytes(StandardCharsets.US_ASCII)) os.write("TRUST\r\n".getBytes(StandardCharsets.US_ASCII))
os.write("Json:true\r\n")
os.write("\r\n")
os.flush() os.flush()
String codeString = DataUtil.readTillRN(is) String codeString = DataUtil.readTillRN(is)
@ -123,24 +128,47 @@ class TrustSubscriber {
return false return false
} }
// swallow any headers Map<String,String> headers = DataUtil.readAllHeaders(is)
String header
while (( header = DataUtil.readTillRN(is)) != "");
DataInputStream dis = new DataInputStream(is) DataInputStream dis = new DataInputStream(is)
Set<TrustService.TrustEntry> good = new HashSet<>()
Set<TrustService.TrustEntry> bad = new HashSet<>()
if (headers.containsKey('Json') && Boolean.parseBoolean(headers['Json'])) {
int countGood = Integer.parseInt(headers['Good'])
int countBad = Integer.parseInt(headers['Bad'])
JsonSlurper slurper = new JsonSlurper()
for (int i = 0; i < countGood; i++) {
int length = dis.readUnsignedShort()
byte []payload = new byte[length]
dis.readFully(payload)
def json = slurper.parse(payload)
Persona persona = new Persona(new ByteArrayInputStream(Base64.decode(json.persona)))
good.add(new TrustEntry(persona, json.reason))
}
for (int i = 0; i < countBad; i++) {
int length = dis.readUnsignedShort()
byte []payload = new byte[length]
dis.readFully(payload)
def json = slurper.parse(payload)
Persona persona = new Persona(new ByteArrayInputStream(Base64.decode(json.persona)))
bad.add(new TrustEntry(persona, json.reason))
}
} else {
int nGood = dis.readUnsignedShort()
for (int i = 0; i < nGood; i++) {
Persona p = new Persona(dis)
good.add(p)
}
Set<Persona> good = new HashSet<>() int nBad = dis.readUnsignedShort()
int nGood = dis.readUnsignedShort() for (int i = 0; i < nBad; i++) {
for (int i = 0; i < nGood; i++) { Persona p = new Persona(dis)
Persona p = new Persona(dis) bad.add(p)
good.add(p) }
}
Set<Persona> bad = new HashSet<>()
int nBad = dis.readUnsignedShort()
for (int i = 0; i < nBad; i++) {
Persona p = new Persona(dis)
bad.add(p)
} }
trustList.timestamp = now trustList.timestamp = now

View File

@ -27,7 +27,7 @@ class TrustListController {
if (selectedRow < 0) if (selectedRow < 0)
return return
String reason = JOptionPane.showInputDialog("Enter reason (optional)") String reason = JOptionPane.showInputDialog("Enter reason (optional)")
Persona p = model.trusted[selectedRow] Persona p = model.trusted[selectedRow].persona
eventBus.publish(new TrustEvent(persona : p, level : TrustLevel.TRUSTED, reason : reason)) eventBus.publish(new TrustEvent(persona : p, level : TrustLevel.TRUSTED, reason : reason))
view.fireUpdate("trusted-table") view.fireUpdate("trusted-table")
} }
@ -38,7 +38,7 @@ class TrustListController {
if (selectedRow < 0) if (selectedRow < 0)
return return
String reason = JOptionPane.showInputDialog("Enter reason (optional)") String reason = JOptionPane.showInputDialog("Enter reason (optional)")
Persona p = model.distrusted[selectedRow] Persona p = model.distrusted[selectedRow].persona
eventBus.publish(new TrustEvent(persona : p, level : TrustLevel.TRUSTED, reason : reason)) eventBus.publish(new TrustEvent(persona : p, level : TrustLevel.TRUSTED, reason : reason))
view.fireUpdate("distrusted-table") view.fireUpdate("distrusted-table")
} }
@ -49,7 +49,7 @@ class TrustListController {
if (selectedRow < 0) if (selectedRow < 0)
return return
String reason = JOptionPane.showInputDialog("Enter reason (optional)") String reason = JOptionPane.showInputDialog("Enter reason (optional)")
Persona p = model.trusted[selectedRow] Persona p = model.trusted[selectedRow].persona
eventBus.publish(new TrustEvent(persona : p, level : TrustLevel.DISTRUSTED, reason : reason)) eventBus.publish(new TrustEvent(persona : p, level : TrustLevel.DISTRUSTED, reason : reason))
view.fireUpdate("trusted-table") view.fireUpdate("trusted-table")
} }
@ -60,7 +60,7 @@ class TrustListController {
if (selectedRow < 0) if (selectedRow < 0)
return return
String reason = JOptionPane.showInputDialog("Enter reason (optional)") String reason = JOptionPane.showInputDialog("Enter reason (optional)")
Persona p = model.distrusted[selectedRow] Persona p = model.distrusted[selectedRow].persona
eventBus.publish(new TrustEvent(persona : p, level : TrustLevel.DISTRUSTED, reason : reason)) eventBus.publish(new TrustEvent(persona : p, level : TrustLevel.DISTRUSTED, reason : reason))
view.fireUpdate("distrusted-table") view.fireUpdate("distrusted-table")
} }

View File

@ -49,8 +49,9 @@ class TrustListView {
scrollPane (constraints : BorderLayout.CENTER){ scrollPane (constraints : BorderLayout.CENTER){
table(id : "trusted-table", autoCreateRowSorter : true, rowHeight : rowHeight) { table(id : "trusted-table", autoCreateRowSorter : true, rowHeight : rowHeight) {
tableModel(list : model.trusted) { tableModel(list : model.trusted) {
closureColumn(header: "Trusted Users", type : String, read : {it.getHumanReadableName()}) closureColumn(header: "Trusted Users", type : String, read : {it.persona.getHumanReadableName()})
closureColumn(header: "Your Trust", type : String, read : {model.trustService.getLevel(it.destination).toString()}) closureColumn(header: "Reason", type : String, read : {it.reason})
closureColumn(header: "Your Trust", type : String, read : {model.trustService.getLevel(it.persona.destination).toString()})
} }
} }
} }
@ -65,8 +66,9 @@ class TrustListView {
scrollPane (constraints : BorderLayout.CENTER ){ scrollPane (constraints : BorderLayout.CENTER ){
table(id : "distrusted-table", autoCreateRowSorter : true, rowHeight : rowHeight) { table(id : "distrusted-table", autoCreateRowSorter : true, rowHeight : rowHeight) {
tableModel(list : model.distrusted) { tableModel(list : model.distrusted) {
closureColumn(header: "Distrusted Users", type : String, read : {it.getHumanReadableName()}) closureColumn(header: "Distrusted Users", type : String, read : {it.persona.getHumanReadableName()})
closureColumn(header: "Your Trust", type : String, read : {model.trustService.getLevel(it.destination).toString()}) closureColumn(header: "Reason", type:String, read : {it.reason})
closureColumn(header: "Your Trust", type : String, read : {model.trustService.getLevel(it.persona.destination).toString()})
} }
} }
} }