diff --git a/src/main/java/org/breedinginsight/api/v1/controller/TokenController.java b/src/main/java/org/breedinginsight/api/v1/controller/TokenController.java deleted file mode 100644 index e1356dbfd..000000000 --- a/src/main/java/org/breedinginsight/api/v1/controller/TokenController.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * See the NOTICE file distributed with this work for additional information - * regarding copyright ownership. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.breedinginsight.api.v1.controller; - -import io.micronaut.http.HttpResponse; -import io.micronaut.http.annotation.Controller; -import io.micronaut.http.annotation.Get; -import io.micronaut.http.annotation.QueryValue; -import io.micronaut.http.uri.UriBuilder; -import io.micronaut.security.annotation.Secured; -import io.micronaut.security.rules.SecurityRule; -import lombok.extern.slf4j.Slf4j; -import org.breedinginsight.api.auth.AuthenticatedUser; -import org.breedinginsight.api.auth.SecurityService; -import org.breedinginsight.model.ApiToken; -import org.breedinginsight.services.TokenService; - -import javax.inject.Inject; -import javax.validation.constraints.NotBlank; -import java.net.URI; -import java.util.Optional; - -@Slf4j -@Controller("/${micronaut.bi.api.version}") -public class TokenController { - - private SecurityService securityService; - private TokenService tokenService; - - @Inject - public TokenController(SecurityService securityService, TokenService tokenService) { - this.securityService = securityService; - this.tokenService = tokenService; - } - - @Get("/api-token") - @Secured(SecurityRule.IS_AUTHENTICATED) - public HttpResponse apiToken(@QueryValue @NotBlank String returnUrl) { - - AuthenticatedUser actingUser = securityService.getUser(); - Optional token = tokenService.generateApiToken(actingUser); - - if(token.isPresent()) { - ApiToken apiToken = token.get(); - - URI location = UriBuilder.of(returnUrl) - .queryParam("status", 200) - .queryParam("token", apiToken.getAccessToken()) - .build(); - - return HttpResponse.seeOther(location) - .header("Cache-Control","no-store") - .header("Pragma", "no-cache"); - } else { - return HttpResponse.serverError(); - } - - } - -} diff --git a/src/main/java/org/breedinginsight/brapi/v1/controller/BrapiAuthorizeController.java b/src/main/java/org/breedinginsight/brapi/auth/BrapiAuthorizeController.java similarity index 83% rename from src/main/java/org/breedinginsight/brapi/v1/controller/BrapiAuthorizeController.java rename to src/main/java/org/breedinginsight/brapi/auth/BrapiAuthorizeController.java index 214890c8d..eda00965a 100644 --- a/src/main/java/org/breedinginsight/brapi/v1/controller/BrapiAuthorizeController.java +++ b/src/main/java/org/breedinginsight/brapi/auth/BrapiAuthorizeController.java @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.breedinginsight.brapi.v1.controller; +package org.breedinginsight.brapi.auth; import io.micronaut.context.annotation.Property; import io.micronaut.http.HttpResponse; @@ -45,12 +45,11 @@ public class BrapiAuthorizeController { @Get("/programs/{programId}/brapi/authorize") @Secured(SecurityRule.IS_ANONYMOUS) - public HttpResponse authorize(@QueryValue @NotBlank String display_name, @QueryValue @NotBlank String return_url, @PathVariable("programId") String programId) { + public HttpResponse authorize(@QueryValue @NotBlank String client_id, @QueryValue @NotBlank String redirect_uri, @PathVariable("programId") String programId) { URI location = UriBuilder.of(String.format("%s/programs/%s/brapi/authorize", webBaseUrl, programId)) - .queryParam("display_name", display_name) - .queryParam("return_url", return_url) + .queryParam("display_name", client_id) + .queryParam("return_url", redirect_uri) .build(); return HttpResponse.seeOther(location); } - } diff --git a/src/main/java/org/breedinginsight/brapi/auth/TokenController.java b/src/main/java/org/breedinginsight/brapi/auth/TokenController.java new file mode 100644 index 000000000..c825761e4 --- /dev/null +++ b/src/main/java/org/breedinginsight/brapi/auth/TokenController.java @@ -0,0 +1,132 @@ +/* + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.breedinginsight.brapi.auth; + +import com.google.gson.JsonArray; +import com.google.gson.JsonObject; +import com.google.gson.JsonPrimitive; +import io.micronaut.context.annotation.Property; +import io.micronaut.http.HttpResponse; +import io.micronaut.http.annotation.Controller; +import io.micronaut.http.annotation.Get; +import io.micronaut.http.annotation.PathVariable; +import io.micronaut.http.annotation.QueryValue; +import io.micronaut.http.uri.UriBuilder; +import io.micronaut.security.annotation.Secured; +import io.micronaut.security.rules.SecurityRule; +import lombok.extern.slf4j.Slf4j; +import org.breedinginsight.api.auth.AuthenticatedUser; +import org.breedinginsight.api.auth.SecurityService; +import org.breedinginsight.brapi.auth.model.OpenIdConfiguration; +import org.breedinginsight.model.ApiToken; +import org.breedinginsight.services.TokenService; + +import javax.inject.Inject; +import javax.validation.constraints.NotBlank; +import java.net.URI; +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; +import java.util.UUID; + +@Slf4j +@Controller("/${micronaut.bi.api.version}") +public class TokenController { + + private SecurityService securityService; + private TokenService tokenService; + + @Property(name = "backend.base-url") + protected String backendBaseUrl; + + @Property(name = "micronaut.bi.api.version") + protected String biapiVersion; + + @Inject + public TokenController(SecurityService securityService, TokenService tokenService) { + this.securityService = securityService; + this.tokenService = tokenService; + } + + @Get("/api-token") + @Secured(SecurityRule.IS_AUTHENTICATED) + public HttpResponse apiToken(@QueryValue @NotBlank String returnUrl) { + + AuthenticatedUser actingUser = securityService.getUser(); + Optional token = tokenService.generateApiToken(actingUser); + + // FieldBook sends user to brapi-authorize endpoint + // brapi authorize endpoint sends user to bi-web authorization page + // User logs in and is redirected to orcid + // User logs into orcid + // Orcid back to bi-api authorization flow + // Bi-api returns user to that authorization page + // User sees fieldbook authorize page on bi-web + // User clicks authorize button + // bi-web sends user to this endpoint + + if(token.isPresent()) { + ApiToken apiToken = token.get(); + + URI location = UriBuilder.of(returnUrl) + .queryParam("status", 200) + .queryParam("access_token", apiToken.getAccessToken()) + .build(); + + return HttpResponse.seeOther(location) + .header("Cache-Control","no-store") + .header("Pragma", "no-cache"); + } else { + return HttpResponse.serverError(); + } + } + + @Get("/programs/{programId}/.well-known/openid-configuration") + @Secured(SecurityRule.IS_ANONYMOUS) + public HttpResponse getConfiguration(@PathVariable("programId") UUID programId) { + + /* + { + "issuer": "", + "authorization_endpoint": "", + "jwks_uri": "", + "token_endpoint": "", + "grant_types_supported": ["implicit"], + "response_types_supported": ["token"], + "subject_types_supported": ["public"], + "id_token_signing_alg_values_supported": [] + } + */ + OpenIdConfiguration configuration = new OpenIdConfiguration(); + configuration.setIssuer(""); + String authorizeUrl = String.format("%s/%s/programs/%s/brapi/authorize", backendBaseUrl, biapiVersion, programId); + configuration.setAuthorization_endpoint(authorizeUrl); + configuration.setJwks_uri(""); + configuration.setToken_endpoint(""); + configuration.setGrant_types_supported(List.of("implicit")); + JsonArray responseTypes = new JsonArray(); + responseTypes.add("token"); + configuration.setResponse_types_supported(List.of("token")); + JsonArray subjectTypes = new JsonArray(); + subjectTypes.add("public"); + configuration.setSubject_types_supported(List.of("public")); + configuration.setId_token_signing_alg_values_supported(new ArrayList()); + + return HttpResponse.ok(configuration); + } + +} diff --git a/src/main/java/org/breedinginsight/brapi/auth/model/OpenIdConfiguration.java b/src/main/java/org/breedinginsight/brapi/auth/model/OpenIdConfiguration.java new file mode 100644 index 000000000..82bf7292b --- /dev/null +++ b/src/main/java/org/breedinginsight/brapi/auth/model/OpenIdConfiguration.java @@ -0,0 +1,36 @@ +/* + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.breedinginsight.brapi.auth.model; + +import lombok.Getter; +import lombok.Setter; + +import java.util.List; + +@Getter +@Setter +public class OpenIdConfiguration { + String issuer; + String authorization_endpoint; + String jwks_uri; + String token_endpoint; + List grant_types_supported; + List response_types_supported; + List subject_types_supported; + List id_token_signing_alg_values_supported; +} diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index b7c035f46..be53508ba 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -140,6 +140,9 @@ web: error: url: ${web.base-url}/account-error +backend: + base-url: ${WEB_BASE_URL:`http://localhost:8081`} + brapi: server: default-url: ${BRAPI_DEFAULT_URL:`https://test-server.brapi.org`}