github.com/minio/console@v1.3.0/pkg/subnet/subnet.go (about)

     1  // This file is part of MinIO Console Server
     2  // Copyright (c) 2021 MinIO, Inc.
     3  //
     4  // This program is free software: you can redistribute it and/or modify
     5  // it under the terms of the GNU Affero General Public License as published by
     6  // the Free Software Foundation, either version 3 of the License, or
     7  // (at your option) any later version.
     8  //
     9  // This program is distributed in the hope that it will be useful,
    10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    12  // GNU Affero General Public License for more details.
    13  //
    14  // You should have received a copy of the GNU Affero General Public License
    15  // along with this program.  If not, see <http://www.gnu.org/licenses/>.
    16  //
    17  
    18  package subnet
    19  
    20  import (
    21  	"encoding/json"
    22  	"errors"
    23  
    24  	"github.com/minio/console/pkg/http"
    25  
    26  	"github.com/minio/console/models"
    27  	"github.com/minio/madmin-go/v3"
    28  	mc "github.com/minio/mc/cmd"
    29  	"github.com/tidwall/gjson"
    30  )
    31  
    32  func LoginWithMFA(client http.ClientI, username, mfaToken, otp string) (*LoginResp, error) {
    33  	mfaLoginReq := MfaReq{Username: username, OTP: otp, Token: mfaToken}
    34  	resp, err := subnetPostReq(client, subnetMFAURL(), mfaLoginReq, nil)
    35  	if err != nil {
    36  		return nil, err
    37  	}
    38  	token := gjson.Get(resp, "token_info.access_token")
    39  	if token.Exists() {
    40  		return &LoginResp{AccessToken: token.String(), MfaToken: ""}, nil
    41  	}
    42  	return nil, errors.New("access token not found in response")
    43  }
    44  
    45  func Login(client http.ClientI, username, password string) (*LoginResp, error) {
    46  	loginReq := map[string]string{
    47  		"username": username,
    48  		"password": password,
    49  	}
    50  	respStr, err := subnetPostReq(client, subnetLoginURL(), loginReq, nil)
    51  	if err != nil {
    52  		return nil, err
    53  	}
    54  	mfaRequired := gjson.Get(respStr, "mfa_required").Bool()
    55  	if mfaRequired {
    56  		mfaToken := gjson.Get(respStr, "mfa_token").String()
    57  		if mfaToken == "" {
    58  			return nil, errors.New("missing mfa token")
    59  		}
    60  		return &LoginResp{AccessToken: "", MfaToken: mfaToken}, nil
    61  	}
    62  	token := gjson.Get(respStr, "token_info.access_token")
    63  	if token.Exists() {
    64  		return &LoginResp{AccessToken: token.String(), MfaToken: ""}, nil
    65  	}
    66  	return nil, errors.New("access token not found in response")
    67  }
    68  
    69  func GetOrganizations(client http.ClientI, token string) ([]*models.SubnetOrganization, error) {
    70  	headers := subnetAuthHeaders(token)
    71  	respStr, err := subnetGetReq(client, subnetOrgsURL(), headers)
    72  	if err != nil {
    73  		return nil, err
    74  	}
    75  	var organizations []*models.SubnetOrganization
    76  	if err = json.Unmarshal([]byte(respStr), &organizations); err != nil {
    77  		return nil, err
    78  	}
    79  	return organizations, nil
    80  }
    81  
    82  type LicenseTokenConfig struct {
    83  	APIKey  string
    84  	License string
    85  	Proxy   string
    86  }
    87  
    88  func Register(client http.ClientI, admInfo madmin.InfoMessage, apiKey, token, accountID string) (*LicenseTokenConfig, error) {
    89  	var headers map[string]string
    90  	regInfo := GetClusterRegInfo(admInfo)
    91  	regURL := subnetRegisterURL()
    92  	if apiKey != "" {
    93  		regURL += "?api_key=" + apiKey
    94  	} else {
    95  		if accountID == "" || token == "" {
    96  			return nil, errors.New("missing accountID or authentication token")
    97  		}
    98  		headers = subnetAuthHeaders(token)
    99  		regURL += "?aid=" + accountID
   100  	}
   101  	regToken, err := GenerateRegToken(regInfo)
   102  	if err != nil {
   103  		return nil, err
   104  	}
   105  	reqPayload := mc.ClusterRegistrationReq{Token: regToken}
   106  	resp, err := subnetPostReq(client, regURL, reqPayload, headers)
   107  	if err != nil {
   108  		return nil, err
   109  	}
   110  	respJSON := gjson.Parse(resp)
   111  	subnetAPIKey := respJSON.Get("api_key").String()
   112  	licenseJwt := respJSON.Get("license").String()
   113  
   114  	if subnetAPIKey != "" || licenseJwt != "" {
   115  		return &LicenseTokenConfig{
   116  			APIKey:  subnetAPIKey,
   117  			License: licenseJwt,
   118  		}, nil
   119  	}
   120  	return nil, errors.New("subnet api key not found")
   121  }
   122  
   123  func GetAPIKey(client http.ClientI, token string) (string, error) {
   124  	resp, err := subnetGetReq(client, subnetAPIKeyURL(), subnetAuthHeaders(token))
   125  	if err != nil {
   126  		return "", err
   127  	}
   128  	respJSON := gjson.Parse(resp)
   129  	apiKey := respJSON.Get("api_key").String()
   130  	return apiKey, nil
   131  }