Skip to content

Commit

Permalink
Verify WebIDs during setup
Browse files Browse the repository at this point in the history
  • Loading branch information
edwardsph committed Jan 29, 2024
1 parent 1a26a7a commit bb3b08b
Show file tree
Hide file tree
Showing 4 changed files with 83 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,7 @@ URI findStorage() throws TestHarnessException {
final Model profile;
try {
profile = publicClient.getContentAsModel(webId);
logger.info("Loaded WebID Document for [{}]", webId);
logger.info("Read WebID Document for [{}]", webId);
} catch (Exception e) {
throw new TestHarnessInitializationException(MessageFormat.format(
"Failed to read WebID Document for [{0}]", webId), e);
Expand Down
21 changes: 17 additions & 4 deletions src/main/java/org/solid/testharness/http/AuthManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,7 @@
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.text.MessageFormat;
import java.util.Base64;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
Expand Down Expand Up @@ -117,6 +114,9 @@ public SolidClientProvider authenticate(@NotNull final String user) {
throw new TestHarnessInitializationException(MessageFormat.format(
"No user credentials were provided for {0}", user));
}

checkWebId(userConfig.webId());

final URI oidcIssuer = Optional.ofNullable(userConfig.getIdp()).orElse(config.getSolidIdentityProvider());

authClient = new Client.Builder(user)
Expand Down Expand Up @@ -150,6 +150,19 @@ public SolidClientProvider authenticate(@NotNull final String user) {
return new SolidClientProvider(authClient);
}

void checkWebId(final String webId) {
try {
Objects.requireNonNull(webId, "webId is required");
final var webIdUri = URI.create(webId);
final var publicClient = new SolidClientProvider(ClientRegistry.ALICE_WEBID);
publicClient.getContentAsModel(webIdUri);
logger.info("Loaded WebID Document for [{}]", webId);
} catch (Exception e) {
throw new TestHarnessInitializationException(MessageFormat.format(
"Failed to read WebID Document for [{0}]", webId), e);
}
}

void exchangeRefreshToken(final Client authClient, final UserCredentials userConfig,
final OidcConfiguration oidcConfig) {
logger.info("Exchange refresh token for {}: [{}]", authClient.getUser(), userConfig.webId());
Expand Down
70 changes: 58 additions & 12 deletions src/test/java/org/solid/testharness/http/AuthManagerTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@
@QuarkusTest
@QuarkusTestResource(AuthenticationResource.class)
class AuthManagerTest {
public static final Map<String, String> ALICE_WEBID_MAP = Map.of(HttpConstants.ALICE,
"https://alice.target.example.org/profile/card#me");

private URI baseUri;

@Inject
Expand Down Expand Up @@ -71,23 +74,66 @@ void registerUser() {
assertDoesNotThrow(() -> authManager.registerUser(HttpConstants.ALICE));
}

@Test
void authenticateNoWebIdInCredentials() {
when(config.getWebIds()).thenReturn(ALICE_WEBID_MAP);
when(config.getSolidIdentityProvider()).thenReturn(baseUri);
when(config.getCredentials("nowebid")).thenReturn(new TestCredentials());

final TestHarnessInitializationException exception = assertThrows(TestHarnessInitializationException.class,
() -> authManager.authenticate("nowebid"));

assertEquals("Failed to read WebID Document for [null] " +
"Caused by: java.lang.NullPointerException: webId is required",
exception.getMessage());
}

@Test
void authenticateInvalidWebID() {
when(config.getWebIds()).thenReturn(ALICE_WEBID_MAP);
final var credentials = new TestCredentials();
credentials.webId = "not a web id";
when(config.getCredentials("notwebid")).thenReturn(credentials);
final TestHarnessInitializationException exception = assertThrows(TestHarnessInitializationException.class,
() -> authManager.authenticate("notwebid"));
assertEquals("Failed to read WebID Document for [not a web id] Caused by: " +
"java.lang.IllegalArgumentException: Illegal character in path at index 3: not a web id",
exception.getMessage());
}

@Test
void authenticateNotFoundWebID() {
when(config.getWebIds()).thenReturn(ALICE_WEBID_MAP);
final var credentials = new TestCredentials();
credentials.webId = baseUri.resolve("404webID").toString();
when(config.getCredentials("notfoundwebid")).thenReturn(credentials);
final TestHarnessInitializationException exception = assertThrows(TestHarnessInitializationException.class,
() -> authManager.authenticate("notfoundwebid"));
assertEquals("Failed to read WebID Document for [" + credentials.webId + "] Caused by: " +
"org.solid.testharness.utils.TestHarnessException: " +
"Error response=404 trying to get content for " + credentials.webId,
exception.getMessage());
}


@Test
void authenticateNoCredentials() {
when(config.getWebIds()).thenReturn(Map.of(HttpConstants.ALICE,
"https://alice.target.example.org/profile/card#me"));
when(config.getWebIds()).thenReturn(ALICE_WEBID_MAP);
when(config.getSolidIdentityProvider()).thenReturn(baseUri);
when(config.getCredentials("nocredentials")).thenReturn(new TestCredentials());
final var credentials = new TestCredentials();
credentials.webId = baseUri.resolve("webID").toString();
when(config.getCredentials("nocredentials")).thenReturn(credentials);

final TestHarnessInitializationException exception = assertThrows(TestHarnessInitializationException.class,
() -> authManager.authenticate("nocredentials"));
assertEquals("Neither login credentials nor refresh token details provided for nocredentials: [null]",
assertEquals("Neither login credentials nor refresh token details provided for nocredentials: ["
+ credentials.webId + "]",
exception.getMessage());
}

@Test
void authenticateLoginSession() {
when(config.getWebIds()).thenReturn(Map.of(HttpConstants.ALICE,
"https://alice.target.example.org/profile/card#me"));
when(config.getWebIds()).thenReturn(ALICE_WEBID_MAP);
when(config.getOrigin()).thenReturn("https://origin/goodcode");
setupLogin(baseUri, "login", "/login/password", null);

Expand All @@ -99,8 +145,7 @@ void authenticateLoginSession() {

@Test
void authenticateLoginUserRegistration() {
when(config.getWebIds()).thenReturn(Map.of(HttpConstants.ALICE,
"https://alice.target.example.org/profile/card#me"));
when(config.getWebIds()).thenReturn(ALICE_WEBID_MAP);
when(config.getOrigin()).thenReturn("https://origin/form");
setupLogin(baseUri, "login", "/login/password",
"/idp/register");
Expand All @@ -113,10 +158,10 @@ void authenticateLoginUserRegistration() {

@Test
void authenticateRefreshCredentials() {
when(config.getWebIds()).thenReturn(Map.of(HttpConstants.ALICE,
"https://alice.target.example.org/profile/card#me"));
when(config.getWebIds()).thenReturn(ALICE_WEBID_MAP);
when(config.getSolidIdentityProvider()).thenReturn(baseUri);
final TestCredentials credentials = new TestCredentials();
credentials.webId = baseUri.resolve("webID").toString();
credentials.refreshToken = Optional.of("REFRESH");
credentials.clientId = Optional.of("CLIENTID");
credentials.clientSecret = Optional.of("CLIENTSECRET");
Expand All @@ -130,10 +175,10 @@ void authenticateRefreshCredentials() {

@Test
void authenticateClientCredentials() {
when(config.getWebIds()).thenReturn(Map.of(HttpConstants.ALICE,
"https://alice.target.example.org/profile/card#me"));
when(config.getWebIds()).thenReturn(ALICE_WEBID_MAP);
when(config.getSolidIdentityProvider()).thenReturn(baseUri);
final TestCredentials credentials = new TestCredentials();
credentials.webId = baseUri.resolve("webID").toString();
credentials.clientId = Optional.of("CLIENTID");
credentials.clientSecret = Optional.of("CLIENTSECRET");
when(config.getCredentials("client_credentials")).thenReturn(credentials);
Expand All @@ -158,6 +203,7 @@ private void setupLogin(final URI idpBaseUri, final String testId,
when(config.getUserRegistrationEndpoint()).thenReturn(idpBaseUri.resolve(userRegistrationEndpoint));
}
final TestCredentials credentials = new TestCredentials();
credentials.webId = baseUri.resolve("webID").toString();
credentials.username = Optional.of("USERNAME");
credentials.password = Optional.of("PASSWORD");
when(config.getCredentials(testId)).thenReturn(credentials);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,13 @@ public Map<String, String> start() {
wireMockServer.stubFor(WireMock.post(WireMock.urlEqualTo("/idp/register"))
.willReturn(WireMock.aResponse().withStatus(200)));

// webID responses
wireMockServer.stubFor(WireMock.get(WireMock.urlEqualTo("/404webID"))
.willReturn(WireMock.aResponse().withStatus(404)));

wireMockServer.stubFor(WireMock.get(WireMock.urlEqualTo("/webID"))
.willReturn(WireMock.aResponse().withStatus(200)));

// return OIDC configuration
wireMockServer.stubFor(WireMock.get(WireMock.urlEqualTo("/" + HttpConstants.OPENID_CONFIGURATION))
.willReturn(WireMock.aResponse()
Expand Down

0 comments on commit bb3b08b

Please sign in to comment.