diff --git a/grails-app/services/grails/plugin/springsecurity/oauth2/SpringSecurityOauth2BaseService.groovy b/grails-app/services/grails/plugin/springsecurity/oauth2/SpringSecurityOauth2BaseService.groovy index 939adad..fbe25dc 100644 --- a/grails-app/services/grails/plugin/springsecurity/oauth2/SpringSecurityOauth2BaseService.groovy +++ b/grails-app/services/grails/plugin/springsecurity/oauth2/SpringSecurityOauth2BaseService.groovy @@ -122,6 +122,15 @@ class SpringSecurityOauth2BaseService { return oAuthToken } + private String buildUrl(OAuth2ProviderService providerService, String baseURL, String type, String alternative = null) { + String configValue = getConfigValue(providerService.providerID, type) + if (!configValue?.startsWith("/")) { + configValue + } else { + configValue ? baseURL + configValue : alternative + } + } + /** * Register the provider into the service * @param providerService @@ -133,11 +142,11 @@ class SpringSecurityOauth2BaseService { log.warn("There is already a provider with the name " + providerService.getProviderID() + " registered") } else { String baseURL = getBaseUrl() - def callbackURL = getConfigValue(providerService.providerID, "callback") ? baseURL + getConfigValue(providerService.providerID, "callback") : baseURL + "/oauth2/" + providerService.getProviderID() + "/callback" + def callbackURL = buildUrl(providerService, baseURL, "callback", baseURL + "/oauth2/" + providerService.getProviderID() + "/callback") log.debug("Callback URL: " + callbackURL) - def successUrl = getConfigValue(providerService.providerID, "successUri") ? baseURL + getConfigValue(providerService.providerID, "successUri") : null + def successUrl = buildUrl(providerService, baseURL, "successUri") log.debug("Success URL: " + successUrl) - def failureUrl = getConfigValue(providerService.providerID, "failureUri") ? baseURL + getConfigValue(providerService.providerID, "failureUri") : null + def failureUrl = buildUrl(providerService, baseURL, "failureUri") log.debug("Failure URL: " + failureUrl) def scopes = getConfigValue(providerService.providerID, "scopes") ?: null log.debug("Additional Scopes: " + scopes) @@ -189,7 +198,7 @@ class SpringSecurityOauth2BaseService { */ String getFailureUrl(String providerName) { def providerService = getProviderService(providerName) - providerService.failureUrl ?: baseUrl + "/oauth2/" + providerName + "/success" + providerService.failureUrl ?: baseUrl + "/oauth2/" + providerName + "/failure" } /** diff --git a/src/test/groovy/grails/plugin/springsecurity/oauth2/SpringSecurityOauth2BaseServiceSpec.groovy b/src/test/groovy/grails/plugin/springsecurity/oauth2/SpringSecurityOauth2BaseServiceSpec.groovy new file mode 100644 index 0000000..cbff6c4 --- /dev/null +++ b/src/test/groovy/grails/plugin/springsecurity/oauth2/SpringSecurityOauth2BaseServiceSpec.groovy @@ -0,0 +1,84 @@ +package grails.plugin.springsecurity.oauth2 + +import com.github.scribejava.apis.GoogleApi20 +import com.github.scribejava.core.builder.api.DefaultApi20 +import com.github.scribejava.core.model.OAuth2AccessToken +import grails.plugin.springsecurity.oauth2.service.OAuth2AbstractProviderService +import grails.plugin.springsecurity.oauth2.token.OAuth2SpringToken +import grails.testing.gorm.DataTest +import grails.testing.services.ServiceUnitTest +import spock.lang.Specification + +class SpringSecurityOauth2BaseServiceSpec extends Specification implements DataTest, ServiceUnitTest { + + String providerName = "google" + String propertyNamespace = "grails.plugin.springsecurity.oauth2.providers" + OAuth2AbstractProviderService oauthProviderService + + def setup() { + oauthProviderService = new OAuth2AbstractProviderService() { + + @Override + String getProviderID() { + providerName + } + + @Override + Class getApiClass() { + return GoogleApi20 + } + + @Override + String getProfileScope() { + return null + } + + @Override + String getScopes() { + return null + } + + @Override + String getScopeSeparator() { + return null + } + + @Override + OAuth2SpringToken createSpringAuthToken(OAuth2AccessToken accessToken) { + return null + } + } + } + + void "relative URLs"() { + given: + grailsApplication.config."${propertyNamespace}.${providerName}.api_key" = "api_key" + grailsApplication.config."${propertyNamespace}.${providerName}.api_secret" = "api_secret" + grailsApplication.config."${propertyNamespace}.${providerName}.successUri" = "/oauth2/${providerName}/success" + grailsApplication.config."${propertyNamespace}.${providerName}.failureUri" = "/oauth2/${providerName}/failure" + grailsApplication.config."${propertyNamespace}.${providerName}.callback" = "/oauth2/${providerName}/callback" + service.registerProvider(oauthProviderService) + + expect: + service.getFailureUrl(providerName) == "http://localhost:8080/oauth2/${providerName}/failure" + service.getSuccessUrl(providerName) == "http://localhost:8080/oauth2/${providerName}/success" + service.getProviderService(providerName).providerConfiguration.getCallbackUrl() == "http://localhost:8080/oauth2/${providerName}/callback" + } + + + void "absolute URLs"() { + given: + String otherDomain = "http://other.domain" + grailsApplication.config."${propertyNamespace}.${providerName}.api_key" = "api_key" + grailsApplication.config."${propertyNamespace}.${providerName}.api_secret" = "api_secret" + grailsApplication.config."${propertyNamespace}.${providerName}.successUri" = "${otherDomain}/oauth2/${providerName}/success" + grailsApplication.config."${propertyNamespace}.${providerName}.failureUri" = "${otherDomain}/oauth2/${providerName}/failure" + grailsApplication.config."${propertyNamespace}.${providerName}.callback" = "${otherDomain}/oauth2/${providerName}/callback" + service.registerProvider(oauthProviderService) + + expect: + service.getFailureUrl(providerName) == "${otherDomain}/oauth2/${providerName}/failure" + service.getSuccessUrl(providerName) == "${otherDomain}/oauth2/${providerName}/success" + service.getProviderService(providerName).providerConfiguration.getCallbackUrl() == "${otherDomain}/oauth2/${providerName}/callback" + } +}