}
/**
- * Sets the trust value of the given origin Sone for the target Sone.
- *
- * @param origin
- * The origin Sone
- * @param target
- * The target Sone
- * @param trustValue
- * The trust value (from {@code -100} to {@code 100})
- */
- public void setTrust(Sone origin, Sone target, int trustValue) {
- checkNotNull(origin, "origin must not be null");
- checkArgument(origin.getIdentity() instanceof OwnIdentity, "origin must be a local Sone");
- checkNotNull(target, "target must not be null");
- checkArgument((trustValue >= -100) && (trustValue <= 100), "trustValue must be within [-100, 100]");
- webOfTrustUpdater.setTrust((OwnIdentity) origin.getIdentity(), target.getIdentity(), trustValue, preferences.getTrustComment());
- }
-
- /**
- * Removes any trust assignment for the given target Sone.
- *
- * @param origin
- * The trust origin
- * @param target
- * The trust target
- */
- public void removeTrust(Sone origin, Sone target) {
- checkNotNull(origin, "origin must not be null");
- checkNotNull(target, "target must not be null");
- checkArgument(origin.getIdentity() instanceof OwnIdentity, "origin must be a local Sone");
- webOfTrustUpdater.setTrust((OwnIdentity) origin.getIdentity(), target.getIdentity(), null, null);
- }
-
- /**
- * Assigns the configured positive trust value for the given target.
- *
- * @param origin
- * The trust origin
- * @param target
- * The trust target
- */
- public void trustSone(Sone origin, Sone target) {
- setTrust(origin, target, preferences.getPositiveTrust());
- }
-
- /**
- * Assigns the configured negative trust value for the given target.
- *
- * @param origin
- * The trust origin
- * @param target
- * The trust target
- */
- public void distrustSone(Sone origin, Sone target) {
- setTrust(origin, target, preferences.getNegativeTrust());
- }
-
- /**
- * Removes the trust assignment for the given target.
- *
- * @param origin
- * The trust origin
- * @param target
- * The trust target
- */
- public void untrustSone(Sone origin, Sone target) {
- removeTrust(origin, target);
- }
-
- /**
* Updates the stored Sone with the given Sone.
*
* @param sone
package net.pterodactylus.sone.core;
-import net.pterodactylus.sone.freenet.wot.Identity;
import net.pterodactylus.sone.freenet.wot.OwnIdentity;
import net.pterodactylus.util.service.Service;
@ImplementedBy(WebOfTrustUpdaterImpl.class)
public interface WebOfTrustUpdater extends Service {
- void setTrust(OwnIdentity truster, Identity trustee, Integer score, String comment);
boolean addContextWait(OwnIdentity ownIdentity, String context);
void removeContext(OwnIdentity ownIdentity, String context);
void setProperty(OwnIdentity ownIdentity, String propertyName, String propertyValue);
import java.util.logging.Logger;
import net.pterodactylus.sone.freenet.plugin.PluginException;
-import net.pterodactylus.sone.freenet.wot.Identity;
import net.pterodactylus.sone.freenet.wot.OwnIdentity;
-import net.pterodactylus.sone.freenet.wot.Trust;
import net.pterodactylus.sone.freenet.wot.WebOfTrustConnector;
-import net.pterodactylus.sone.freenet.wot.WebOfTrustException;
import net.pterodactylus.util.service.AbstractService;
import com.google.common.annotations.VisibleForTesting;
//
/**
- * Updates the trust relation between the truster and the trustee. This method
- * will return immediately and perform a trust update in the background.
- *
- * @param truster
- * The identity giving the trust
- * @param trustee
- * The identity receiving the trust
- * @param score
- * The new level of trust (from -100 to 100, may be {@code null} to remove
- * the trust completely)
- * @param comment
- * The comment of the trust relation
- */
- @Override
- public void setTrust(OwnIdentity truster, Identity trustee, Integer score, String comment) {
- SetTrustJob setTrustJob = new SetTrustJob(truster, trustee, score, comment);
- if (updateJobs.contains(setTrustJob)) {
- updateJobs.remove(setTrustJob);
- }
- logger.log(Level.FINER, "Adding Trust Update Job: " + setTrustJob);
- try {
- updateJobs.put(setTrustJob);
- } catch (InterruptedException e) {
- /* the queue is unbounded so it should never block. */
- }
- }
-
- /**
* Adds the given context to the given own identity, waiting for completion of
* the operation.
*
}
/**
- * Update job that sets the trust relation between two identities.
- */
- @VisibleForTesting
- class SetTrustJob extends WebOfTrustUpdateJob {
-
- /** The identity giving the trust. */
- private final OwnIdentity truster;
-
- /** The identity receiving the trust. */
- private final Identity trustee;
-
- /** The score of the relation. */
- private final Integer score;
-
- /** The comment of the relation. */
- private final String comment;
-
- /**
- * Creates a new set trust job.
- *
- * @param truster
- * The identity giving the trust
- * @param trustee
- * The identity receiving the trust
- * @param score
- * The score of the trust (from -100 to 100, may be {@code null} to remote
- * the trust relation completely)
- * @param comment
- * The comment of the trust relation
- */
- public SetTrustJob(OwnIdentity truster, Identity trustee, Integer score, String comment) {
- this.truster = checkNotNull(truster, "truster must not be null");
- this.trustee = checkNotNull(trustee, "trustee must not be null");
- this.score = score;
- this.comment = comment;
- }
-
- /** {@inheritDoc} */
- @Override
- @SuppressWarnings("synthetic-access")
- public void run() {
- try {
- if (score != null) {
- webOfTrustConnector.setTrust(truster, trustee, score, comment);
- trustee.setTrust(truster, new Trust(score, null, 0));
- } else {
- webOfTrustConnector.removeTrust(truster, trustee);
- trustee.removeTrust(truster);
- }
- finish(true);
- } catch (WebOfTrustException wote1) {
- logger.log(Level.WARNING, "Could not set Trust value for " + truster + " -> " + trustee + " to " + score + " (" + comment + ")!", wote1);
- finish(false);
- }
- }
-
- //
- // OBJECT METHODS
- //
-
- /** {@inheritDoc} */
- @Override
- public boolean equals(Object object) {
- if ((object == null) || !object.getClass().equals(getClass())) {
- return false;
- }
- SetTrustJob updateJob = (SetTrustJob) object;
- return updateJob.truster.equals(truster) && updateJob.trustee.equals(trustee);
- }
-
- /** {@inheritDoc} */
- @Override
- public int hashCode() {
- return getClass().hashCode() ^ truster.hashCode() ^ trustee.hashCode();
- }
-
- /** {@inheritDoc} */
- @Override
- public String toString() {
- return String.format("%s[truster=%s,trustee=%s]", getClass().getSimpleName(), truster.getId(), trustee.getId());
- }
-
- }
-
- /**
* Base class for context updates of an {@link OwnIdentity}.
*/
@VisibleForTesting
performRequest(SimpleFieldSetBuilder().put("Message", "RemoveProperty").put("Identity", ownIdentity.id).put("Property", name).get())
}
- override fun getTrust(ownIdentity: OwnIdentity, identity: Identity) =
- performRequest(SimpleFieldSetBuilder().put("Message", "GetIdentity").put("Truster", ownIdentity.id).put("Identity", identity.id).get())
- .fields
- .parseTrust()
-
- override fun setTrust(ownIdentity: OwnIdentity, identity: Identity, trust: Int, comment: String) {
- performRequest(SimpleFieldSetBuilder().put("Message", "SetTrust").put("Truster", ownIdentity.id).put("Trustee", identity.id).put("Value", trust.toString()).put("Comment", comment).get())
- }
-
- override fun removeTrust(ownIdentity: OwnIdentity, identity: Identity) {
- performRequest(SimpleFieldSetBuilder().put("Message", "RemoveTrust").put("Truster", ownIdentity.id).put("Trustee", identity.id).get())
- }
-
override fun ping() {
performRequest(SimpleFieldSetBuilder().put("Message", "Ping").get())
}
fun removeProperty(ownIdentity: OwnIdentity, name: String)
/**
- * Returns the trust for the given identity assigned to it by the given own
- * identity.
- *
- * @param ownIdentity The own identity
- * @param identity The identity to get the trust for
- * @return The trust for the given identity
- * @throws PluginException if an error occured talking to the Web of Trust plugin
- */
- @Throws(PluginException::class)
- fun getTrust(ownIdentity: OwnIdentity, identity: Identity): Trust
-
- /**
- * Sets the trust for the given identity.
- *
- * @param ownIdentity The trusting identity
- * @param identity The trusted identity
- * @param trust The amount of trust (-100 thru 100)
- * @param comment The comment or explanation of the trust value
- * @throws PluginException if an error occured talking to the Web of Trust plugin
- */
- @Throws(PluginException::class)
- fun setTrust(ownIdentity: OwnIdentity, identity: Identity, trust: Int, comment: String)
-
- /**
- * Removes any trust assignment of the given own identity for the given
- * identity.
- *
- * @param ownIdentity The own identity
- * @param identity The identity to remove all trust for
- * @throws WebOfTrustException if an error occurs
- */
- @Throws(WebOfTrustException::class)
- fun removeTrust(ownIdentity: OwnIdentity, identity: Identity)
-
- /**
* Pings the Web of Trust plugin. If the plugin can not be reached, a
* [PluginException] is thrown.
*
import net.pterodactylus.sone.core.WebOfTrustUpdaterImpl.AddContextJob;
import net.pterodactylus.sone.core.WebOfTrustUpdaterImpl.RemoveContextJob;
import net.pterodactylus.sone.core.WebOfTrustUpdaterImpl.SetPropertyJob;
-import net.pterodactylus.sone.core.WebOfTrustUpdaterImpl.SetTrustJob;
import net.pterodactylus.sone.core.WebOfTrustUpdaterImpl.WebOfTrustContextUpdateJob;
import net.pterodactylus.sone.core.WebOfTrustUpdaterImpl.WebOfTrustUpdateJob;
import net.pterodactylus.sone.freenet.plugin.PluginException;
import net.pterodactylus.sone.freenet.wot.Identity;
import net.pterodactylus.sone.freenet.wot.OwnIdentity;
-import net.pterodactylus.sone.freenet.wot.Trust;
import net.pterodactylus.sone.freenet.wot.WebOfTrustConnector;
-import net.pterodactylus.sone.freenet.wot.WebOfTrustException;
import org.junit.Test;
import org.mockito.invocation.InvocationOnMock;
public class WebOfTrustUpdaterTest {
private static final String CONTEXT = "test-context";
- private static final Integer SCORE = 50;
- private static final Integer OTHER_SCORE = 25;
- private static final String TRUST_COMMENT = "set in a test";
private static final String PROPERTY_NAME = "test-property";
private final WebOfTrustConnector webOfTrustConnector = mock(WebOfTrustConnector.class);
private final WebOfTrustUpdaterImpl webOfTrustUpdater = new WebOfTrustUpdaterImpl(webOfTrustConnector);
private final WebOfTrustContextUpdateJob contextUpdateJob = webOfTrustUpdater.new WebOfTrustContextUpdateJob(ownIdentity, CONTEXT);
private final AddContextJob addContextJob = webOfTrustUpdater.new AddContextJob(ownIdentity, CONTEXT);
private final RemoveContextJob removeContextJob = webOfTrustUpdater.new RemoveContextJob(ownIdentity, CONTEXT);
- private final Identity trustee = when(mock(Identity.class).getId()).thenReturn("trustee-id").getMock();
private WebOfTrustUpdateJob createWebOfTrustUpdateJob(final boolean success) {
return webOfTrustUpdater.new WebOfTrustUpdateJob() {
}
@Test
- public void setTrustJobSetsTrust() throws PluginException {
- SetTrustJob setTrustJob = webOfTrustUpdater.new SetTrustJob(ownIdentity, trustee, SCORE, TRUST_COMMENT);
- setTrustJob.run();
- verify(webOfTrustConnector).setTrust(eq(ownIdentity), eq(trustee), eq(SCORE), eq(TRUST_COMMENT));
- verify(trustee).setTrust(eq(ownIdentity), eq(new Trust(SCORE, null, 0)));
- assertThat(setTrustJob.waitForCompletion(), is(true));
- }
-
- @Test
- public void settingNullTrustRemovesTrust() throws WebOfTrustException {
- SetTrustJob setTrustJob = webOfTrustUpdater.new SetTrustJob(ownIdentity, trustee, null, TRUST_COMMENT);
- setTrustJob.run();
- verify(webOfTrustConnector).removeTrust(eq(ownIdentity), eq(trustee));
- verify(trustee).removeTrust(eq(ownIdentity));
- assertThat(setTrustJob.waitForCompletion(), is(true));
- }
-
- @Test
- public void exceptionWhileSettingTrustIsCaught() throws PluginException {
- doThrow(PluginException.class).when(webOfTrustConnector).setTrust(eq(ownIdentity), eq(trustee), eq(SCORE), eq(TRUST_COMMENT));
- SetTrustJob setTrustJob = webOfTrustUpdater.new SetTrustJob(ownIdentity, trustee, SCORE, TRUST_COMMENT);
- setTrustJob.run();
- verify(webOfTrustConnector).setTrust(eq(ownIdentity), eq(trustee), eq(SCORE), eq(TRUST_COMMENT));
- verify(trustee, never()).setTrust(eq(ownIdentity), eq(new Trust(SCORE, null, 0)));
- assertThat(setTrustJob.waitForCompletion(), is(false));
- }
-
- @Test
- public void setTrustJobsWithDifferentClassesAreNotEqual() {
- SetTrustJob firstSetTrustJob = webOfTrustUpdater.new SetTrustJob(ownIdentity, trustee, SCORE, TRUST_COMMENT);
- SetTrustJob secondSetTrustJob = webOfTrustUpdater.new SetTrustJob(ownIdentity, trustee, SCORE, TRUST_COMMENT) {
- };
- assertThat(firstSetTrustJob, not(is(secondSetTrustJob)));
- assertThat(secondSetTrustJob, not(is(firstSetTrustJob)));
- }
-
- @Test
- public void setTrustJobsWithDifferentTrustersAreNotEqual() {
- SetTrustJob firstSetTrustJob = webOfTrustUpdater.new SetTrustJob(ownIdentity, trustee, SCORE, TRUST_COMMENT);
- SetTrustJob secondSetTrustJob = webOfTrustUpdater.new SetTrustJob(mock(OwnIdentity.class), trustee, SCORE, TRUST_COMMENT);
- assertThat(firstSetTrustJob, not(is(secondSetTrustJob)));
- assertThat(secondSetTrustJob, not(is(firstSetTrustJob)));
- }
-
- @Test
- public void setTrustJobsWithDifferentTrusteesAreNotEqual() {
- SetTrustJob firstSetTrustJob = webOfTrustUpdater.new SetTrustJob(ownIdentity, trustee, SCORE, TRUST_COMMENT);
- SetTrustJob secondSetTrustJob = webOfTrustUpdater.new SetTrustJob(ownIdentity, mock(Identity.class), SCORE, TRUST_COMMENT);
- assertThat(firstSetTrustJob, not(is(secondSetTrustJob)));
- assertThat(secondSetTrustJob, not(is(firstSetTrustJob)));
- }
-
- @Test
- public void setTrustJobsWithDifferentScoreAreEqual() {
- SetTrustJob firstSetTrustJob = webOfTrustUpdater.new SetTrustJob(ownIdentity, trustee, SCORE, TRUST_COMMENT);
- SetTrustJob secondSetTrustJob = webOfTrustUpdater.new SetTrustJob(ownIdentity, trustee, OTHER_SCORE, TRUST_COMMENT);
- assertThat(firstSetTrustJob, is(secondSetTrustJob));
- assertThat(secondSetTrustJob, is(firstSetTrustJob));
- assertThat(firstSetTrustJob.hashCode(), is(secondSetTrustJob.hashCode()));
- }
-
- @Test
- public void setTrustJobDoesNotEqualNull() {
- SetTrustJob setTrustJob = webOfTrustUpdater.new SetTrustJob(ownIdentity, trustee, SCORE, TRUST_COMMENT);
- assertThat(setTrustJob, not(is((Object) null)));
- }
-
- @Test
- public void toStringOfSetTrustJobContainsIdsOfTrusterAndTrustee() {
- SetTrustJob setTrustJob = webOfTrustUpdater.new SetTrustJob(ownIdentity, trustee, SCORE, TRUST_COMMENT);
- assertThat(setTrustJob.toString(), containsString(ownIdentity.getId()));
- assertThat(setTrustJob.toString(), containsString(trustee.getId()));
- }
-
- @Test
public void webOfTrustUpdaterStopsWhenItShould() {
webOfTrustUpdater.stop();
webOfTrustUpdater.serviceRun();
verify(ownIdentity).removeContext(eq(CONTEXT));
}
- @Test
- public void setTrustSetsTrust() throws InterruptedException, PluginException {
- final CountDownLatch trustSetTrigger = new CountDownLatch(1);
- doAnswer(new Answer<Void>() {
- @Override
- public Void answer(InvocationOnMock invocation) throws Throwable {
- trustSetTrigger.countDown();
- return null;
- }
- }).when(trustee).setTrust(eq(ownIdentity), eq(new Trust(SCORE, null, 0)));
- webOfTrustUpdater.start();
- webOfTrustUpdater.setTrust(ownIdentity, trustee, SCORE, TRUST_COMMENT);
- assertThat(trustSetTrigger.await(1, SECONDS), is(true));
- verify(trustee).setTrust(eq(ownIdentity), eq(new Trust(SCORE, null, 0)));
- verify(webOfTrustConnector).setTrust(eq(ownIdentity), eq(trustee), eq(SCORE), eq(TRUST_COMMENT));
- }
-
- @Test
- public void setTrustRequestsAreCoalesced() throws InterruptedException, PluginException {
- final CountDownLatch firstTrigger = new CountDownLatch(1);
- doAnswer((Answer<Void>) invocation -> {
- firstTrigger.countDown();
- return null;
- }).when(trustee).setTrust(eq(ownIdentity), eq(new Trust(SCORE, null, 0)));
- Identity secondTrustee = when(mock(Identity.class).getId()).thenReturn("trustee-id2").getMock();
- final CountDownLatch secondTrigger = new CountDownLatch(1);
- doAnswer((Answer<Void>) invocation -> {
- secondTrigger.countDown();
- return null;
- }).when(secondTrustee).setTrust(eq(ownIdentity), eq(new Trust(SCORE, null, 0)));
- webOfTrustUpdater.setTrust(ownIdentity, trustee, SCORE, TRUST_COMMENT);
- webOfTrustUpdater.setTrust(ownIdentity, secondTrustee, SCORE, TRUST_COMMENT);
- webOfTrustUpdater.setTrust(ownIdentity, trustee, SCORE, TRUST_COMMENT);
- webOfTrustUpdater.start();
- assertThat(firstTrigger.await(1, SECONDS), is(true));
- assertThat(secondTrigger.await(1, SECONDS), is(true));
- verify(trustee, times(1)).setTrust(eq(ownIdentity), eq(new Trust(SCORE, null, 0)));
- verify(webOfTrustConnector).setTrust(eq(ownIdentity), eq(trustee), eq(SCORE), eq(TRUST_COMMENT));
- }
-
}
override fun removeContext(ownIdentity: OwnIdentity, context: String) = Unit
override fun setProperty(ownIdentity: OwnIdentity, name: String, value: String) = Unit
override fun removeProperty(ownIdentity: OwnIdentity, name: String) = Unit
- override fun getTrust(ownIdentity: OwnIdentity, identity: Identity) = Trust(null, null, null)
- override fun setTrust(ownIdentity: OwnIdentity, identity: Identity, trust: Int, comment: String) = Unit
- override fun removeTrust(ownIdentity: OwnIdentity, identity: Identity) = Unit
override fun ping() = Unit
}
class PluginWebOfTrustConnectorTest {
private val ownIdentity = DefaultOwnIdentity("id", "nickname", "requestUri", "insertUri")
- private val identity = DefaultIdentity("id-a", "alpha", "url://alpha")
@Test
fun `wot plugin can be pinged`() {
.connect { removeProperty(ownIdentity, "TestProperty") }
}
- @Test
- fun `getting trust sends correct own identity id`() {
- createPluginConnector("GetIdentity", hasField("Truster", equalTo(ownIdentity.id)))
- .connect { getTrust(ownIdentity, identity) }
- }
-
- @Test
- fun `getting trust sends correct identity id`() {
- createPluginConnector("GetIdentity", hasField("Identity", equalTo(identity.id)))
- .connect { getTrust(ownIdentity, identity) }
- }
-
- @Test
- fun `getting trust returns correct trust values`() {
- val trust = createPluginConnector("GetIdentity", hasField("Identity", equalTo(identity.id))) {
- put("Trust", "12")
- put("Score", "34")
- put("Rank", "56")
- }.connect { getTrust(ownIdentity, identity) }
- assertThat(trust, isTrust(12, 34, 56))
- }
-
- @Test
- fun `getting trust reads incorrect numbers for trust as null`() {
- val trust = createPluginConnector("GetIdentity", hasField("Identity", equalTo(identity.id))) {
- put("Trust", "incorrect")
- put("Score", "34")
- put("Rank", "56")
- }.connect { getTrust(ownIdentity, identity) }
- assertThat(trust, isTrust(null, 34, 56))
- }
-
- @Test
- fun `getting trust reads incorrect numbers for score as null`() {
- val trust = createPluginConnector("GetIdentity", hasField("Identity", equalTo(identity.id))) {
- put("Trust", "12")
- put("Score", "incorrect")
- put("Rank", "56")
- }.connect { getTrust(ownIdentity, identity) }
- assertThat(trust, isTrust(12, null, 56))
- }
-
- @Test
- fun `getting trust reads incorrect numbers for rank as null`() {
- val trust = createPluginConnector("GetIdentity", hasField("Identity", equalTo(identity.id))) {
- put("Trust", "12")
- put("Score", "34")
- put("Rank", "incorrect")
- }.connect { getTrust(ownIdentity, identity) }
- assertThat(trust, isTrust(12, 34, null))
- }
-
- @Test
- fun `setting trust sends correct own identity id`() {
- createPluginConnector("SetTrust", hasField("Truster", equalTo(ownIdentity.id)))
- .connect { setTrust(ownIdentity, identity, 123, "Test Trust") }
- }
-
- @Test
- fun `setting trust sends correct identity id`() {
- createPluginConnector("SetTrust", hasField("Trustee", equalTo(identity.id)))
- .connect { setTrust(ownIdentity, identity, 123, "Test Trust") }
- }
-
- @Test
- fun `setting trust sends correct trust value`() {
- createPluginConnector("SetTrust", hasField("Value", equalTo("123")))
- .connect { setTrust(ownIdentity, identity, 123, "Test Trust") }
- }
-
- @Test
- fun `setting trust sends correct comment`() {
- createPluginConnector("SetTrust", hasField("Comment", equalTo("Test Trust")))
- .connect { setTrust(ownIdentity, identity, 123, "Test Trust") }
- }
-
- @Test
- fun `removing trust sends correct own identity id`() {
- createPluginConnector("RemoveTrust", hasField("Truster", equalTo(ownIdentity.id)))
- .connect { removeTrust(ownIdentity, identity) }
- }
-
- @Test
- fun `removing trust sends correct identity id`() {
- createPluginConnector("RemoveTrust", hasField("Trustee", equalTo(identity.id)))
- .connect { removeTrust(ownIdentity, identity) }
- }
-
}
private fun <R> PluginConnector.connect(block: PluginWebOfTrustConnector.() -> R) =