Introduce OAuth scope description Allow to define a full text description associated to an OAuth scope configuration. Makes clearer to the end-user what is the purpose of the scope authorization and provide privacy warning and guidance on their use. Suitable to label a scope as GDPR compliant for EU Citizens. Change-Id: I80f30fcb62e59e252755df1d003646e16338c7ef
diff --git a/github-oauth/src/main/java/com/googlesource/gerrit/plugins/github/oauth/GitHubLogin.java b/github-oauth/src/main/java/com/googlesource/gerrit/plugins/github/oauth/GitHubLogin.java index 1625b81..07fc694 100644 --- a/github-oauth/src/main/java/com/googlesource/gerrit/plugins/github/oauth/GitHubLogin.java +++ b/github-oauth/src/main/java/com/googlesource/gerrit/plugins/github/oauth/GitHubLogin.java
@@ -107,7 +107,7 @@ response.sendRedirect(OAuthProtocol.getTargetUrl(request)); } } else { - Set<String> configuredScopesProfiles = config.scopes.keySet(); + Set<ScopeKey> configuredScopesProfiles = config.scopes.keySet(); String scopeRequested = getScopesKey(request, response); if (Strings.isNullOrEmpty(scopeRequested) && configuredScopesProfiles.size() > 1) { response.sendRedirect(config.getScopeSelectionUrl(request)); @@ -185,6 +185,13 @@ } private List<Scope> scopesForKey(String baseScopeKey) { - return MoreObjects.firstNonNull(config.scopes.get(baseScopeKey), DEFAULT_SCOPES); + return config + .scopes + .entrySet() + .stream() + .filter(entry -> entry.getKey().name.equals(baseScopeKey)) + .map(entry -> entry.getValue()) + .findFirst() + .orElse(DEFAULT_SCOPES); } }
diff --git a/github-oauth/src/main/java/com/googlesource/gerrit/plugins/github/oauth/GitHubOAuthConfig.java b/github-oauth/src/main/java/com/googlesource/gerrit/plugins/github/oauth/GitHubOAuthConfig.java index 319a850..cdc817b 100644 --- a/github-oauth/src/main/java/com/googlesource/gerrit/plugins/github/oauth/GitHubOAuthConfig.java +++ b/github-oauth/src/main/java/com/googlesource/gerrit/plugins/github/oauth/GitHubOAuthConfig.java
@@ -17,7 +17,6 @@ import com.google.common.base.MoreObjects; import com.google.common.base.Preconditions; import com.google.common.base.Strings; -import com.google.common.collect.Maps; import com.google.gerrit.extensions.client.AuthType; import com.google.gerrit.httpd.CanonicalWebUrl; import com.google.gerrit.server.config.AuthConfig; @@ -29,8 +28,8 @@ import java.util.ArrayList; import java.util.List; import java.util.Map; -import java.util.Set; import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; import javax.servlet.http.HttpServletRequest; import lombok.Getter; import org.eclipse.jgit.lib.Config; @@ -61,7 +60,7 @@ public final String gitHubOAuthAccessTokenUrl; public final boolean enabled; - @Getter public final Map<String, List<OAuthProtocol.Scope>> scopes; + @Getter public final Map<ScopeKey, List<OAuthProtocol.Scope>> scopes; public final int fileUpdateMaxRetryCount; public final int fileUpdateMaxRetryIntervalMsec; @@ -134,16 +133,16 @@ config.getString(CONF_SECTION, null, "scopeSelectionUrl"), GITHUB_PLUGIN_OAUTH_SCOPE); } - private Map<String, List<Scope>> getScopes(Config config) { - Map<String, List<Scope>> result = Maps.newHashMap(); - Set<String> configKeys = config.getNames(CONF_SECTION, true); - for (String key : configKeys) { - if (key.startsWith("scopes")) { - String scopesString = config.getString(CONF_SECTION, null, key); - result.put(key, parseScopesString(scopesString)); - } - } - return result; + private Map<ScopeKey, List<Scope>> getScopes(Config config) { + return config + .getNames(CONF_SECTION, true) + .stream() + .filter(k -> k.startsWith("scopes")) + .filter(k -> !k.endsWith("Description")) + .collect( + Collectors.toMap( + k -> new ScopeKey(k, config.getString(CONF_SECTION, null, k + "Description")), + v -> parseScopesString(config.getString(CONF_SECTION, null, v)))); } private String trimTrailingSlash(String url) {
diff --git a/github-oauth/src/main/java/com/googlesource/gerrit/plugins/github/oauth/ScopeKey.java b/github-oauth/src/main/java/com/googlesource/gerrit/plugins/github/oauth/ScopeKey.java new file mode 100644 index 0000000..2b99a71 --- /dev/null +++ b/github-oauth/src/main/java/com/googlesource/gerrit/plugins/github/oauth/ScopeKey.java
@@ -0,0 +1,27 @@ +// Copyright (C) 2018 The Android Open Source Project +// +// 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 com.googlesource.gerrit.plugins.github.oauth; + +import lombok.Getter; + +public class ScopeKey { + @Getter public final String name; + @Getter public final String description; + + public ScopeKey(String name, String description) { + this.name = name; + this.description = description; + } +}
diff --git a/github-plugin/src/main/resources/static/scope.html b/github-plugin/src/main/resources/static/scope.html index 29795f0..dc9b4a7 100644 --- a/github-plugin/src/main/resources/static/scope.html +++ b/github-plugin/src/main/resources/static/scope.html
@@ -38,9 +38,10 @@ <ul class="scopes"> #foreach ( $scope in $config.scopes.keySet() ) <li> - #set ( $scopeName = $scope.substring(6) ) + #set ( $scopeName = $scope.name.substring(6) ) + #set ( $scopeDescription = $scope.description ) #set ( $checked = "" ) - #if ( ( $scopeCookie && $scopeCookie == $scope ) || $scopeName == "" ) + #if ( ( $scopeCookie && $scopeCookie == $scope.name ) || $scopeName == "" ) #set ( $checked = "checked" ) #end @@ -49,7 +50,8 @@ #else <input type="radio" name="scope" value="scopes$scopeName" $checked ><p class="scope">$scopeName</p> #end - <p> + <p class="scopeDescription">$scopeDescription</p> + <p class="scopePermissions">Allow to: #set ( $scopeItems = $config.scopes.get($scope) ) #foreach ( $scopeItem in $scopeItems ) $scopeItem.description