Skip to content
Snippets Groups Projects
Commit 4b064c7c authored by Martin Lowe's avatar Martin Lowe :flag_ca:
Browse files

Merge branch 'zacharysabourin/main/16' into 'main'

feat: Update user token validation

Closes #16

See merge request !5
parents 4cb8b185 6a492c20
No related branches found
No related tags found
1 merge request!5feat: Update user token validation
Pipeline #15658 passed
Showing
with 246 additions and 116 deletions
......@@ -23,7 +23,7 @@ services:
depends_on:
- foundationdb
foundationdb:
image: eclipsefdn/foundationdb-api:production-b43bc82-7
image: eclipsefdn/foundationdb-api:production-a25f588-21
ports:
- '10112:8095'
environment:
......
......@@ -156,8 +156,10 @@
</goals>
<configuration>
<systemPropertyVariables>
<native.image.path> ${project.build.directory}/${project.build.finalName}-runner</native.image.path>
<java.util.logging.manager> org.jboss.logmanager.LogManager</java.util.logging.manager>
<native.image.path>
${project.build.directory}/${project.build.finalName}-runner</native.image.path>
<java.util.logging.manager>
org.jboss.logmanager.LogManager</java.util.logging.manager>
<maven.home>${maven.home}</maven.home>
</systemPropertyVariables>
</configuration>
......@@ -167,7 +169,8 @@
</plugins>
</build>
<properties>
<quarkus.package.type> native</quarkus.package.type>
<quarkus.package.type>
native</quarkus.package.type>
</properties>
</profile>
</profiles>
......
......@@ -19,7 +19,7 @@ paths:
summary: Publisher Agreement
description: Fetch the open-vsx.org publisher agreement for the current user.
security:
- OAuth2: [openvsx_publisher_agreement]
- OAuth2: [openvsx_publisher_agreement, openid, profile]
responses:
200:
description: Success
......@@ -41,7 +41,7 @@ paths:
summary: Create a Publisher Agreement
description: Create an open-vsx.org publisher agreement for the current user.
security:
- OAuth2: [openvsx_publisher_agreement]
- OAuth2: [openvsx_publisher_agreement, openid, profile]
requestBody:
description: Required information to sign an open-vsx.org publisher agreement.
required: true
......
......@@ -13,6 +13,8 @@ package org.eclipsefoundation.openvsx.api;
import javax.enterprise.context.ApplicationScoped;
import javax.ws.rs.GET;
import javax.ws.rs.HeaderParam;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
......@@ -20,17 +22,23 @@ import javax.ws.rs.core.MediaType;
import org.eclipse.microprofile.rest.client.inject.RegisterRestClient;
import org.eclipsefoundation.openvsx.api.models.DrupalOAuthData;
import org.eclipsefoundation.openvsx.api.models.DrupalUserInfo;
import org.jboss.resteasy.util.HttpHeaderNames;
/**
* Drupal OAuth2 token validation API binding
*/
@Path("oauth2/tokens")
@Path("oauth2")
@Produces(MediaType.APPLICATION_JSON)
@ApplicationScoped
@RegisterRestClient(configKey = "accounts-api")
public interface DrupalOAuthAPI {
@GET
@Path("{token}")
@Path("/tokens/{token}")
DrupalOAuthData getTokenInfo(@PathParam("token") String token);
@POST
@Path("userinfo")
DrupalUserInfo getUserInfoFromToken(@HeaderParam(HttpHeaderNames.AUTHORIZATION) String token);
}
\ No newline at end of file
......@@ -26,12 +26,12 @@ import org.eclipsefoundation.openvsx.api.models.EfUser;
public interface EclipseAPI {
/**
* Retrieves user objects that matches the given Github username.
* Queries for a user with a given username.
*
* @param username GH handle to match against EF user
* @param username The desired username.
* @return the matching Eclipse account or null
*/
@GET
@Path("/github/profile/{username}")
EfUser getUserByGithubName(@PathParam("username") String username);
@Path("/account/profile/{username}")
EfUser getUserByUsername(@PathParam("username") String username);
}
/*********************************************************************
* Copyright (c) 2023 Eclipse Foundation.
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* Author: Zachary Sabourin <zachary.sabourin@eclipse-foundation.org>
*
* SPDX-License-Identifier: EPL-2.0
**********************************************************************/
package org.eclipsefoundation.openvsx.api.models;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder;
import com.google.auto.value.AutoValue;
@AutoValue
@JsonDeserialize(builder = AutoValue_DrupalUserInfo.Builder.class)
public abstract class DrupalUserInfo {
public abstract String getSub();
public abstract String getName();
public abstract String getGithubHandle();
public static Builder builder() {
return new AutoValue_DrupalUserInfo.Builder();
}
@AutoValue.Builder
@JsonPOJOBuilder(withPrefix = "set")
public abstract static class Builder {
public abstract Builder setSub(String sub);
public abstract Builder setName(String name);
public abstract Builder setGithubHandle(String handle);
public abstract DrupalUserInfo build();
}
}
......@@ -19,6 +19,8 @@ import com.google.auto.value.AutoValue;
@JsonDeserialize(builder = AutoValue_EfUser.Builder.class)
public abstract class EfUser {
public abstract Integer getUid();
public abstract String getName();
public abstract String getGithubHandle();
......@@ -31,6 +33,8 @@ public abstract class EfUser {
@JsonPOJOBuilder(withPrefix = "set")
public abstract static class Builder {
public abstract Builder setUid(Integer uid);
public abstract Builder setName(String name);
public abstract Builder setGithubHandle(String handle);
......
......@@ -16,6 +16,8 @@ import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import org.eclipsefoundation.core.exception.FinalForbiddenException;
/**
* Defines helper methods for Drupal OAuth2 token validation.
*/
......@@ -60,6 +62,28 @@ public class DrupalAuthHelper {
return validClientIds.stream().anyMatch(id -> id.equalsIgnoreCase(clientId));
}
/**
* Strips the bearer token down to just the token. Throws a
* FinalForbiddenException if the token is in an invalid format.
*
* @param header the bearer token suthorization header
* @return The raw token string.
*/
public static String stripBearerToken(String header) {
if (header == null || header.equals("")) {
throw new FinalForbiddenException("No auth token present");
}
String[] splits = header.split(" ");
// Invalid token if no space or more than one space
if (splits.length != 2 || !splits[0].equals("Bearer")) {
throw new FinalForbiddenException(String.format("Invalid auth header: %s", header));
}
return splits[1];
}
private DrupalAuthHelper() {
}
}
\ No newline at end of file
......@@ -21,8 +21,8 @@ import javax.ws.rs.container.ContainerRequestFilter;
import javax.ws.rs.ext.Provider;
import org.eclipse.microprofile.config.inject.ConfigProperty;
import org.eclipsefoundation.core.exception.FinalForbiddenException;
import org.eclipsefoundation.openvsx.api.models.DrupalOAuthData;
import org.eclipsefoundation.openvsx.helpers.DrupalAuthHelper;
import org.eclipsefoundation.openvsx.services.DrupalOAuthService;
import org.jboss.resteasy.util.HttpHeaderNames;
import org.slf4j.Logger;
......@@ -32,7 +32,7 @@ import org.slf4j.LoggerFactory;
public class OAuthFilter implements ContainerRequestFilter {
private static final Logger LOGGER = LoggerFactory.getLogger(OAuthFilter.class);
public static final String TOKEN_STATUS = "tokenStatus";
public static final String TOKEN_USER = "token_user";
@ConfigProperty(name = "eclipse.openvsx.scopes", defaultValue = "openvsx_publisher_agreement")
Instance<List<String>> validScopes;
......@@ -49,35 +49,18 @@ public class OAuthFilter implements ContainerRequestFilter {
@Override
public void filter(ContainerRequestContext requestContext) throws IOException {
if (Boolean.TRUE.equals(isEnabled.get())) {
String token = stripBearerToken(requestContext.getHeaderString(HttpHeaderNames.AUTHORIZATION));
LOGGER.debug("Parsing auth header");
String token = DrupalAuthHelper
.stripBearerToken(requestContext.getHeaderString(HttpHeaderNames.AUTHORIZATION));
DrupalOAuthData tokenStatus = oauthService.validateTokenStatus(token, validScopes.get(),
validClientIds.get());
if (tokenStatus != null && tokenStatus.getUserId() != null) {
requestContext.setProperty(TOKEN_STATUS, tokenStatus);
// Fetch user data from token and set in context
LOGGER.debug("Fetching user info for token");
requestContext.setProperty(TOKEN_USER, oauthService.getTokenUserInfo(token));
}
}
}
/**
* Strips the bearer token down to just the token. Throws a
* FinalForbiddenException if the token is in an invalid format.
*
* @param header the bearer token suthorization header
* @return The raw token string.
*/
private String stripBearerToken(String header) {
if (header == null || header.equals("")) {
throw new FinalForbiddenException("Invalid token");
}
String[] splits = header.split(" ");
// Invalid token if no space or more than one space
if (splits.length != 2 || !splits[0].equals("Bearer")) {
LOGGER.error("Invalid auth header: {}", header);
throw new FinalForbiddenException("Invalid token");
}
return splits[1];
}
}
......@@ -11,6 +11,8 @@
**********************************************************************/
package org.eclipsefoundation.openvsx.resources;
import java.util.Optional;
import javax.inject.Inject;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.BadRequestException;
......@@ -26,7 +28,7 @@ import javax.ws.rs.core.Response;
import org.eclipsefoundation.core.exception.FinalForbiddenException;
import org.eclipsefoundation.foundationdb.client.model.PeopleDocumentData;
import org.eclipsefoundation.openvsx.api.models.AgreementSigningRequest;
import org.eclipsefoundation.openvsx.api.models.DrupalOAuthData;
import org.eclipsefoundation.openvsx.api.models.DrupalUserInfo;
import org.eclipsefoundation.openvsx.request.OAuthFilter;
import org.eclipsefoundation.openvsx.services.PublisherAgreementService;
......@@ -41,27 +43,27 @@ public class PublisherAgreementResource {
@GET
public Response getAgreement() {
// Endpoint uses currently logged in user. Token must have user_id
return getAgreementForUser(extractUserIdFromToken());
// Endpoint uses currently logged in user.
return getAgreementForUser(getTokenUser().getName());
}
@POST
public Response createAgreement(AgreementSigningRequest body) {
// Endpoint uses currently logged in user. Token must have user_id
PeopleDocumentData result = agreementService.createPublisherAgreement(extractUserIdFromToken(), body);
if (result == null) {
// Endpoint uses currently logged in user
Optional<PeopleDocumentData> result = agreementService.createPublisherAgreement(getTokenUser(), body);
if (result.isEmpty()) {
throw new BadRequestException("Unable to create Publisher Agreement with current request parameters");
}
return Response.ok(result).build();
return Response.ok(result.get()).build();
}
@GET
@Path("{efUsername}")
public Response getAgreementForUser(@PathParam("efUsername") String username) {
PeopleDocumentData result = agreementService.getPublisherAgreement(username);
if (result == null) {
Optional<PeopleDocumentData> result = agreementService.getPublisherAgreementByUsername(username);
if (result.isEmpty()) {
throw new NotFoundException(String.format("Unable to find agreement for user: %s", username));
}
......@@ -79,17 +81,17 @@ public class PublisherAgreementResource {
}
/**
* Extracts the user_id from the token data in order to determine a user is
* Extracts the user from the request context in order to determine a user is
* signed in. Throws a FinalForbiddenException if there is no user associated
* with this token.
*
* @return The token user id.
* @return The token user.
*/
private String extractUserIdFromToken() {
DrupalOAuthData tokenStatus = (DrupalOAuthData) request.getAttribute(OAuthFilter.TOKEN_STATUS);
if (tokenStatus == null || tokenStatus.getUserId() == null) {
private DrupalUserInfo getTokenUser() {
DrupalUserInfo tokenUser = (DrupalUserInfo) request.getAttribute(OAuthFilter.TOKEN_USER);
if (tokenUser == null) {
throw new FinalForbiddenException("No user associated with this token");
}
return tokenStatus.getUserId();
return tokenUser;
}
}
\ No newline at end of file
......@@ -14,6 +14,7 @@ package org.eclipsefoundation.openvsx.services;
import java.util.List;
import org.eclipsefoundation.openvsx.api.models.DrupalOAuthData;
import org.eclipsefoundation.openvsx.api.models.DrupalUserInfo;
/**
* Defines a Drupal Oauth validation service.
......@@ -22,13 +23,24 @@ public interface DrupalOAuthService {
/**
* Validates an OAuth2 token using a list of valid scopes. Also validates token
* expiry and client id. Returns an OAuthTokenStatus entity containing token
* expiry and client id. Returns an DrupalOAuthData entity containing token
* validity information as well as the basis for denial if token deemed invalid.
*
* @param token The token string.
* @param validScopes A list of valid scopes for this token.
* @param validClientId A valid client_id for this token.
* @return A OAuthTokenStatus entity containing status info.
* @return A DrupalOAuthData entity containing status info.
*/
DrupalOAuthData validateTokenStatus(String token, List<String> validScopes, List<String> validClientIds);
/**
* Fetches the user data associated with the current token. Throws a
* FinalForbiddenException if no user data is found or if there is a connection
* error. Returns a DrupalUserInfo entity containing the user's uid, username,
* and gh handle.
*
* @param token The current request bearer token.
* @return A DrupalUserInfo entity containing logged in user data.
*/
DrupalUserInfo getTokenUserInfo(String token);
}
\ No newline at end of file
......@@ -11,8 +11,11 @@
**********************************************************************/
package org.eclipsefoundation.openvsx.services;
import java.util.Optional;
import org.eclipsefoundation.foundationdb.client.model.PeopleDocumentData;
import org.eclipsefoundation.openvsx.api.models.AgreementSigningRequest;
import org.eclipsefoundation.openvsx.api.models.DrupalUserInfo;
/**
* Defines the service for fetching, creating and deleting openvsx publisher
......@@ -21,26 +24,29 @@ import org.eclipsefoundation.openvsx.api.models.AgreementSigningRequest;
public interface PublisherAgreementService {
/**
* Retrieves the most recent openvsx publisher agreement for the given user.
* Given the username, retrieves the most recent openvsx publisher agreement for
* the given user.
*
* @param username The desired user's EF username.
* @return A PeopleDocumentData entity or null.
* @return An Optional containing a PeopleDocumentData entity if it exists.
*/
public PeopleDocumentData getPublisherAgreement(String username);
public Optional<PeopleDocumentData> getPublisherAgreementByUsername(String username);
/**
* Attempts to create a publisher agreement for the given user using the request
* body contining the user GH handle and document version. Validates the GH
* handle exists and is tied to the desired username. Returns null if the GH
* handle is incorrect, if it can't create the signed document, or if it
* encounters an error.
* body containing the user GH handle and document version. Validates the user
* exists and the provide GH is tied to the user making the request. Returns
* an empty Optional if the user can't be found or if the GH handle is
* incorrect, if it can't create the signed document, or if it encounters an
* error.
*
* @param username The desired user's EF username.
* @param request The rrequest body containing the GH handle and coument
* version.
* @return A PeopleDocumentData entity or null.
* @return An Optional containing the created PeopleDocumentData entity if it
* exists.
*/
public PeopleDocumentData createPublisherAgreement(String username, AgreementSigningRequest request);
public Optional<PeopleDocumentData> createPublisherAgreement(DrupalUserInfo user, AgreementSigningRequest request);
/**
* Attempts to delete the most recent publisher agreement for the given user and
......
......@@ -20,6 +20,7 @@ import org.eclipse.microprofile.rest.client.inject.RestClient;
import org.eclipsefoundation.core.exception.FinalForbiddenException;
import org.eclipsefoundation.openvsx.api.DrupalOAuthAPI;
import org.eclipsefoundation.openvsx.api.models.DrupalOAuthData;
import org.eclipsefoundation.openvsx.api.models.DrupalUserInfo;
import org.eclipsefoundation.openvsx.helpers.DrupalAuthHelper;
import org.eclipsefoundation.openvsx.services.DrupalOAuthService;
import org.slf4j.Logger;
......@@ -44,7 +45,8 @@ public class DefaultDrupalOAuthService implements DrupalOAuthService {
throw new FinalForbiddenException("The Authorization token is expired");
}
if (!DrupalAuthHelper.hasScopes(tokenData.getScope(), validScopes)) {
throw new FinalForbiddenException("The Authorization token does not have the required permissions/scopes");
throw new FinalForbiddenException(
"The Authorization token does not have the required permissions/scopes");
}
if (!DrupalAuthHelper.hasValidclientId(tokenData.getClientId(), validClientIds)) {
throw new FinalForbiddenException("The Authorization token has an Invalid client_id");
......@@ -56,4 +58,16 @@ public class DefaultDrupalOAuthService implements DrupalOAuthService {
throw new FinalForbiddenException("Error validating token");
}
}
@Override
public DrupalUserInfo getTokenUserInfo(String token) {
try {
LOGGER.debug("Fetching user info for token: {}", token);
return oauthAPI.getUserInfoFromToken("Bearer " + token);
} catch (Exception e) {
LOGGER.error("Error getting user from token", e);
throw new FinalForbiddenException("Error getting user from token");
}
}
}
\ No newline at end of file
......@@ -17,7 +17,6 @@ import java.util.Optional;
import javax.enterprise.context.ApplicationScoped;
import javax.inject.Inject;
import javax.ws.rs.core.Response;
import org.eclipse.microprofile.config.inject.ConfigProperty;
import org.eclipse.microprofile.rest.client.inject.RestClient;
......@@ -25,10 +24,9 @@ import org.eclipsefoundation.core.helper.DateTimeHelper;
import org.eclipsefoundation.core.service.CachingService;
import org.eclipsefoundation.core.service.CachingService.ParameterizedCacheKey;
import org.eclipsefoundation.foundationdb.client.model.PeopleDocumentData;
import org.eclipsefoundation.openvsx.api.EclipseAPI;
import org.eclipsefoundation.openvsx.api.PeopleAPI;
import org.eclipsefoundation.openvsx.api.models.AgreementSigningRequest;
import org.eclipsefoundation.openvsx.api.models.EfUser;
import org.eclipsefoundation.openvsx.api.models.DrupalUserInfo;
import org.eclipsefoundation.openvsx.services.PublisherAgreementService;
import org.jboss.resteasy.specimpl.MultivaluedMapImpl;
import org.slf4j.Logger;
......@@ -45,85 +43,86 @@ public class DefaultPublisherAgreementService implements PublisherAgreementServi
@RestClient
PeopleAPI peopleAPI;
@Inject
@RestClient
EclipseAPI eclipseAPI;
@Inject
CachingService cache;
@Override
public PeopleDocumentData getPublisherAgreement(String username) {
public Optional<PeopleDocumentData> getPublisherAgreementByUsername(String username) {
try {
Optional<List<PeopleDocumentData>> results = cache.get(username, new MultivaluedMapImpl<>(),
PeopleDocumentData.class, () -> peopleAPI.getPeopleDocuments(username, openvsxDocId));
List<PeopleDocumentData> results = peopleAPI.getPeopleDocuments(username, openvsxDocId);
if (results.isEmpty() || results.get().isEmpty()) {
if (results == null || results.isEmpty()) {
LOGGER.error("Unable to find agreements for user with name: {}", username);
return null;
return Optional.empty();
}
// Sort by date. Returning most recent
return results.get().stream()
return results.stream()
.sorted((pDoc1, pDoc2) -> pDoc2.getEffectiveDate().compareTo(pDoc1.getEffectiveDate()))
.findFirst().orElse(null);
.findFirst();
} catch (Exception e) {
LOGGER.error("Error while fetching publisher agreements for user: {}", username, e);
return null;
return Optional.empty();
}
}
@Override
public PeopleDocumentData createPublisherAgreement(String username, AgreementSigningRequest body) {
public Optional<PeopleDocumentData> createPublisherAgreement(DrupalUserInfo user, AgreementSigningRequest body) {
try {
Optional<EfUser> ghResult = cache.get("gh: " + body.getGithubHandle(), new MultivaluedMapImpl<>(),
Response.class, () -> eclipseAPI.getUserByGithubName(body.getGithubHandle()));
if (ghResult.isEmpty() || ghResult.get() == null) {
LOGGER.error("Unable to find account for GH user: {}", body.getGithubHandle());
return null;
// Ensure GH handle from current user as in request body.
if (!user.getGithubHandle().equalsIgnoreCase(body.getGithubHandle())) {
LOGGER.error("Invalid GH handle for use: {}", body.getGithubHandle());
return Optional.empty();
}
// Ensure username in URL matches GH fetch username
if (!ghResult.get().getName().equalsIgnoreCase(username)) {
LOGGER.error("Invalid GH handle for use: {}", username);
return null;
}
PeopleDocumentData fdnDbRequest = PeopleDocumentData.builder()
.setPersonID(username)
.setDocumentID(openvsxDocId)
.setVersion(Double.parseDouble(body.getVersion()))
.setEffectiveDate(new Date())
.setReceivedDate(new Date())
.build();
String username = user.getName();
// Submit new document to fdnDb for creation, can fail if invalid version is set
List<PeopleDocumentData> results = peopleAPI.createPeopleDocument(username, fdnDbRequest);
List<PeopleDocumentData> results = peopleAPI.createPeopleDocument(username,
createFdnDbRequest(username, Double.parseDouble(body.getVersion())));
if (results == null || results.isEmpty()) {
LOGGER.error("Unable to create agreement for user with name: {}", username);
return null;
return Optional.empty();
}
return results.get(0);
return Optional.of(results.get(0));
} catch (Exception e) {
LOGGER.error("Error while creating publisher agreement", e);
return null;
return Optional.empty();
}
}
@Override
public boolean deletePublisherAgreement(String username) {
// Get most recent document if it exists
PeopleDocumentData mostRecent = getPublisherAgreement(username);
if (mostRecent == null) {
Optional<PeopleDocumentData> mostRecent = getPublisherAgreementByUsername(username);
if (mostRecent.isEmpty()) {
return false;
}
// Delete and remove from cache entry
peopleAPI.deletePeopleDocument(username, openvsxDocId, DateTimeHelper.toRFC3339(mostRecent.getEffectiveDate()));
peopleAPI.deletePeopleDocument(username, openvsxDocId,
DateTimeHelper.toRFC3339(mostRecent.get().getEffectiveDate()));
cache.remove(new ParameterizedCacheKey(PeopleDocumentData.class, username, new MultivaluedMapImpl<>()));
return true;
}
/**
* Creates an OpenVSX publisher agreement document signing request using the
* given username and document version
*
* @param username The User signing the document
* @param docVersion The document version being signed
* @return The constructed PeopleDocumentData object.
*/
private PeopleDocumentData createFdnDbRequest(String username, double docVersion) {
return PeopleDocumentData.builder()
.setPersonID(username)
.setDocumentID(openvsxDocId)
.setVersion(docVersion)
.setEffectiveDate(new Date())
.setReceivedDate(new Date())
.build();
}
}
......@@ -19,8 +19,11 @@ import java.util.List;
import javax.enterprise.context.ApplicationScoped;
import org.eclipse.microprofile.rest.client.inject.RestClient;
import org.eclipsefoundation.core.exception.FinalForbiddenException;
import org.eclipsefoundation.openvsx.api.DrupalOAuthAPI;
import org.eclipsefoundation.openvsx.api.models.DrupalOAuthData;
import org.eclipsefoundation.openvsx.api.models.DrupalUserInfo;
import org.eclipsefoundation.openvsx.helpers.DrupalAuthHelper;
import io.quarkus.test.Mock;
......@@ -29,11 +32,12 @@ import io.quarkus.test.Mock;
@ApplicationScoped
public class MockDrupalOAuthAPI implements DrupalOAuthAPI {
List<DrupalOAuthData> internal;
List<DrupalOAuthData> tokens;
List<DrupalUserInfo> users;
public MockDrupalOAuthAPI() {
internal = new ArrayList<>();
internal.addAll(Arrays.asList(
tokens = new ArrayList<>();
tokens.addAll(Arrays.asList(
DrupalOAuthData.builder()
.setAccessToken("token1")
.setClientId("client-id")
......@@ -43,7 +47,7 @@ public class MockDrupalOAuthAPI implements DrupalOAuthAPI {
DrupalOAuthData.builder()
.setAccessToken("token2")
.setClientId("test-id")
.setUserId("fakeuser")
.setUserId("42")
.setExpires(Instant.now().getEpochSecond() + 20000)
.setScope("read write admin")
.build(),
......@@ -62,14 +66,37 @@ public class MockDrupalOAuthAPI implements DrupalOAuthAPI {
DrupalOAuthData.builder()
.setAccessToken("token5")
.setClientId("test-id")
.setUserId("name")
.setUserId("333")
.setExpires(Instant.now().getEpochSecond() + 20000)
.setScope("read write admin")
.build()));
users = new ArrayList<>();
users.addAll(Arrays.asList(
DrupalUserInfo.builder()
.setSub("42")
.setName("fakeuser")
.setGithubHandle("fakeuser")
.build(),
DrupalUserInfo.builder()
.setSub("333")
.setName("otheruser")
.setGithubHandle("other")
.build()));
}
@Override
public DrupalOAuthData getTokenInfo(String token) {
return internal.stream().filter(t -> t.getAccessToken().equalsIgnoreCase(token)).findFirst().orElse(null);
return tokens.stream().filter(t -> t.getAccessToken().equalsIgnoreCase(token)).findFirst().orElse(null);
}
@Override
public DrupalUserInfo getUserInfoFromToken(String token) {
DrupalOAuthData tokenInfo = getTokenInfo(DrupalAuthHelper.stripBearerToken(token));
if (tokenInfo == null || tokenInfo.getUserId() == null) {
throw new FinalForbiddenException("The access token provided is invalid");
}
return users.stream().filter(u -> u.getSub().equalsIgnoreCase(tokenInfo.getUserId())).findFirst().orElse(null);
}
}
\ No newline at end of file
......@@ -34,25 +34,29 @@ public class MockEclipseAPI implements EclipseAPI {
this.users = new ArrayList<>();
this.users.addAll(Arrays.asList(
EfUser.builder()
.setUid(666)
.setName("firstlast")
.setGithubHandle("handle")
.build(),
EfUser.builder()
.setUid(42)
.setName("fakeuser")
.setGithubHandle("fakeuser")
.build(),
EfUser.builder()
.setUid(333)
.setName("name")
.setGithubHandle("name")
.build(),
EfUser.builder()
.setUid(11)
.setName("testtesterson")
.setGithubHandle("mctesty")
.build()));
}
@Override
public EfUser getUserByGithubName(String username) {
return users.stream().filter(u -> u.getGithubHandle().equalsIgnoreCase(username)).findFirst().orElse(null);
public EfUser getUserByUsername(String username) {
return users.stream().filter(u -> u.getName().equalsIgnoreCase(username)).findFirst().orElse(null);
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment