2  * ============LICENSE_START=======================================================
 
   3  * ONAP : ccsdk features
 
   4  * ================================================================================
 
   5  * Copyright (C) 2021 highstreet technologies GmbH Intellectual Property.
 
   7  * ================================================================================
 
   8  * Licensed under the Apache License, Version 2.0 (the "License");
 
   9  * you may not use this file except in compliance with the License.
 
  10  * You may obtain a copy of the License at
 
  12  *     http://www.apache.org/licenses/LICENSE-2.0
 
  14  * Unless required by applicable law or agreed to in writing, software
 
  15  * distributed under the License is distributed on an "AS IS" BASIS,
 
  16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 
  17  * See the License for the specific language governing permissions and
 
  18  * limitations under the License.
 
  19  * ============LICENSE_END=========================================================
 
  22 package org.onap.ccsdk.features.sdnr.wt.oauthprovider.providers;
 
  24 import com.fasterxml.jackson.core.JsonProcessingException;
 
  25 import com.fasterxml.jackson.databind.JsonMappingException;
 
  26 import java.util.ArrayList;
 
  27 import java.util.HashMap;
 
  28 import java.util.List;
 
  30 import java.util.Optional;
 
  31 import org.onap.ccsdk.features.sdnr.wt.oauthprovider.data.Config;
 
  32 import org.onap.ccsdk.features.sdnr.wt.oauthprovider.data.OAuthProviderConfig;
 
  33 import org.onap.ccsdk.features.sdnr.wt.oauthprovider.data.UnableToConfigureOAuthService;
 
  34 import org.onap.ccsdk.features.sdnr.wt.oauthprovider.data.UserTokenPayload;
 
  35 import org.onap.ccsdk.features.sdnr.wt.oauthprovider.http.client.MappedBaseHttpResponse;
 
  36 import org.slf4j.Logger;
 
  37 import org.slf4j.LoggerFactory;
 
  39 public class GitlabProviderService extends AuthService {
 
  41     private static final Logger LOG = LoggerFactory.getLogger(GitlabProviderService.class);
 
  42     private Map<String, String> additionalTokenVerifierParams;
 
  43     protected final List<String> randomIds;
 
  44     private static final String API_USER_URI = "/api/v4/user";
 
  45     private static final String API_GROUP_URI = "/api/v4/groups?min_access_level=10";
 
  47     public GitlabProviderService(OAuthProviderConfig config, String redirectUri, TokenCreator tokenCreator) throws UnableToConfigureOAuthService {
 
  48         super(config, redirectUri, tokenCreator);
 
  49         this.additionalTokenVerifierParams = new HashMap<>();
 
  50         this.additionalTokenVerifierParams.put("grant_type", "authorization_code");
 
  51         this.randomIds = new ArrayList<>();
 
  55     protected String getTokenVerifierUri() {
 
  56         return "/oauth/token";
 
  60     protected String getLoginUrl(String callbackUrl) {
 
  61         return String.format("%s/oauth/authorize?client_id=%s&response_type=code&state=%s&redirect_uri=%s",
 
  62                 this.config.getUrl(), urlEncode(this.config.getClientId()), this.createRandomId(), callbackUrl);
 
  66     protected String getLogoutUrl() {
 
  67         return String.format("%s/oauth/logout", this.config.getUrl());
 
  70     private String createRandomId() {
 
  73             rnd=Config.generateSecret(20);
 
  74             if(!this.randomIds.contains(rnd)) {
 
  78         this.randomIds.add(rnd);
 
  83     protected ResponseType getResponseType() {
 
  84         return ResponseType.CODE;
 
  88     protected Map<String, String> getAdditionalTokenVerifierParams() {
 
  89         return this.additionalTokenVerifierParams;
 
  94     protected boolean doSeperateRolesRequest() {
 
  99     protected UserTokenPayload mapAccessToken(String spayload) throws JsonMappingException, JsonProcessingException {
 
 104     protected UserTokenPayload requestUserRoles(String access_token, long issued_at, long expires_at) {
 
 105         LOG.debug("reqesting user roles with token={}", access_token);
 
 106         Map<String, String> authHeaders = new HashMap<>();
 
 107         authHeaders.put("Authorization", String.format("Bearer %s", access_token));
 
 108         Optional<MappedBaseHttpResponse<GitlabUserInfo>> userInfo =
 
 109                 this.getHttpClient().sendMappedRequest(API_USER_URI, "GET", null, authHeaders, GitlabUserInfo.class);
 
 110         if (userInfo.isEmpty()) {
 
 111             LOG.warn("unable to read user data");
 
 114         Optional<MappedBaseHttpResponse<GitlabGroupInfo[]>> groupInfos = this.getHttpClient()
 
 115                 .sendMappedRequest(API_GROUP_URI, "GET", null, authHeaders, GitlabGroupInfo[].class);
 
 116         if (groupInfos.isEmpty()) {
 
 117             LOG.warn("unable to read group information for user");
 
 120         UserTokenPayload data = new UserTokenPayload();
 
 121         GitlabUserInfo uInfo = userInfo.get().body;
 
 122         data.setPreferredUsername(uInfo.getUsername());
 
 123         data.setGivenName(uInfo.getName());
 
 124         data.setFamilyName(uInfo.getName());
 
 125         data.setIat(issued_at);
 
 126         data.setExp(expires_at);
 
 127         List<String> roles = new ArrayList<>();
 
 128         GitlabGroupInfo[] uRoles = groupInfos.get().body;
 
 129         for (GitlabGroupInfo uRole : uRoles) {
 
 130             roles.add(uRole.getName());
 
 132         data.setRoles(this.mapRoles(roles));
 
 138     @SuppressWarnings("unused")
 
 139     private static class GitlabUserInfo {
 
 141         private String username;
 
 144         public String getUsername() {
 
 148         public void setUsername(String username) {
 
 149             this.username = username;
 
 152         public String getName() {
 
 156         public void setName(String name) {
 
 160     @SuppressWarnings("unused")
 
 161     private static class GitlabGroupInfo {
 
 164         public String getName() {
 
 168         public void setName(String name) {
 
 173     protected boolean verifyState(String state) {
 
 174         if(this.randomIds.contains(state)) {
 
 175             this.randomIds.remove(state);