16f65c81268366506bae4524dace8a8625dcf065
[nonrtric/plt/sme.git] / capifcore / internal / keycloak / keycloak.go
1 // -
2 //   ========================LICENSE_START=================================
3 //   O-RAN-SC
4 //   %%
5 //   Copyright (C) 2023: Nordix Foundation
6 //   %%
7 //   Licensed under the Apache License, Version 2.0 (the "License");
8 //   you may not use this file except in compliance with the License.
9 //   You may obtain a copy of the License at
10 //
11 //        http://www.apache.org/licenses/LICENSE-2.0
12 //
13 //   Unless required by applicable law or agreed to in writing, software
14 //   distributed under the License is distributed on an "AS IS" BASIS,
15 //   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 //   See the License for the specific language governing permissions and
17 //   limitations under the License.
18 //   ========================LICENSE_END===================================
19 //
20
21 package keycloak
22
23 import (
24         "encoding/json"
25         "errors"
26         "io"
27         "net/http"
28         "net/url"
29
30         "oransc.org/nonrtric/capifcore/internal/config"
31 )
32
33 //go:generate mockery --name AccessManagement
34 type AccessManagement interface {
35         // Get JWT token for a client.
36         // Returns JWT token if client exits and credentials are correct otherwise returns error.
37         GetToken(clientId, clientPassword, scope string, realm string) (Jwttoken, error)
38 }
39
40 type KeycloakManager struct {
41         keycloakServerUrl string
42         realms            map[string]string
43 }
44
45 func NewKeycloakManager(cfg *config.Config) *KeycloakManager {
46
47         keycloakUrl := "http://" + cfg.AuthorizationServer.Host + ":" + cfg.AuthorizationServer.Port
48
49         return &KeycloakManager{
50                 keycloakServerUrl: keycloakUrl,
51                 realms:            cfg.AuthorizationServer.Realms,
52         }
53 }
54
55 type Jwttoken struct {
56         AccessToken      string `json:"access_token"`
57         IDToken          string `json:"id_token"`
58         ExpiresIn        int    `json:"expires_in"`
59         RefreshExpiresIn int    `json:"refresh_expires_in"`
60         RefreshToken     string `json:"refresh_token"`
61         TokenType        string `json:"token_type"`
62         NotBeforePolicy  int    `json:"not-before-policy"`
63         SessionState     string `json:"session_state"`
64         Scope            string `json:"scope"`
65 }
66
67 func (km *KeycloakManager) GetToken(clientId, clientPassword, scope string, realm string) (Jwttoken, error) {
68         var jwt Jwttoken
69         getTokenUrl := km.keycloakServerUrl + "/realms/" + realm + "/protocol/openid-connect/token"
70
71         resp, err := http.PostForm(getTokenUrl,
72                 url.Values{"grant_type": {"client_credentials"}, "client_id": {clientId}, "client_secret": {clientPassword}})
73
74         if err != nil {
75                 return jwt, err
76         }
77
78         defer resp.Body.Close()
79         body, err := io.ReadAll(resp.Body)
80
81         if err != nil {
82                 return jwt, err
83         }
84         if resp.StatusCode != http.StatusOK {
85                 return jwt, errors.New(string(body))
86         }
87
88         json.Unmarshal([]byte(body), &jwt)
89         return jwt, nil
90 }