New Login Design (#1675)

Signed-off-by: Daniel Valdivia <18384552+dvaldivia@users.noreply.github.com>
This commit is contained in:
Daniel Valdivia
2022-03-07 17:56:42 -08:00
committed by GitHub
parent 5e42f96eaf
commit 8e21039ef1
34 changed files with 3018 additions and 175 deletions

View File

@@ -24,17 +24,17 @@ import (
"fmt"
"log"
"github.com/minio/console/pkg/utils"
"github.com/minio/pkg/licverifier"
"github.com/minio/console/models"
"github.com/minio/madmin-go"
mc "github.com/minio/mc/cmd"
"github.com/tidwall/gjson"
"github.com/minio/console/cluster"
)
func LoginWithMFA(client cluster.HTTPClientI, username, mfaToken, otp string) (*LoginResp, error) {
func LoginWithMFA(client utils.HTTPClientI, username, mfaToken, otp string) (*LoginResp, error) {
mfaLoginReq := MfaReq{Username: username, OTP: otp, Token: mfaToken}
resp, err := subnetPostReq(client, subnetMFAURL(), mfaLoginReq, nil)
if err != nil {
@@ -47,7 +47,7 @@ func LoginWithMFA(client cluster.HTTPClientI, username, mfaToken, otp string) (*
return nil, errors.New("access token not found in response")
}
func Login(client cluster.HTTPClientI, username, password string) (*LoginResp, error) {
func Login(client utils.HTTPClientI, username, password string) (*LoginResp, error) {
loginReq := map[string]string{
"username": username,
"password": password,
@@ -71,7 +71,7 @@ func Login(client cluster.HTTPClientI, username, password string) (*LoginResp, e
return nil, errors.New("access token not found in response")
}
func GetOrganizations(client cluster.HTTPClientI, token string) ([]*models.SubnetOrganization, error) {
func GetOrganizations(client utils.HTTPClientI, token string) ([]*models.SubnetOrganization, error) {
headers := subnetAuthHeaders(token)
respStr, err := subnetGetReq(client, subnetOrgsURL(), headers)
if err != nil {
@@ -90,7 +90,7 @@ type LicenseTokenConfig struct {
Proxy string
}
func Register(client cluster.HTTPClientI, admInfo madmin.InfoMessage, apiKey, token, accountID string) (*LicenseTokenConfig, error) {
func Register(client utils.HTTPClientI, admInfo madmin.InfoMessage, apiKey, token, accountID string) (*LicenseTokenConfig, error) {
var headers map[string]string
regInfo := GetClusterRegInfo(admInfo)
regURL := subnetRegisterURL()
@@ -128,7 +128,7 @@ func Register(client cluster.HTTPClientI, admInfo madmin.InfoMessage, apiKey, to
const publicKey = "/downloads/license-pubkey.pem"
// downloadSubnetPublicKey will download the current subnet public key.
func downloadSubnetPublicKey(client cluster.HTTPClientI) (string, error) {
func downloadSubnetPublicKey(client utils.HTTPClientI) (string, error) {
// Get the public key directly from Subnet
url := fmt.Sprintf("%s%s", subnetBaseURL(), publicKey)
resp, err := client.Get(url)
@@ -145,7 +145,7 @@ func downloadSubnetPublicKey(client cluster.HTTPClientI) (string, error) {
}
// ParseLicense parses the license with the bundle public key and return it's information
func ParseLicense(client cluster.HTTPClientI, license string) (*licverifier.LicenseInfo, error) {
func ParseLicense(client utils.HTTPClientI, license string) (*licverifier.LicenseInfo, error) {
var publicKeys []string
subnetPubKey, err := downloadSubnetPublicKey(client)

View File

@@ -25,7 +25,8 @@ import (
"io/ioutil"
"net/http"
"github.com/minio/console/cluster"
"github.com/minio/console/pkg/utils"
"github.com/minio/madmin-go"
mc "github.com/minio/mc/cmd"
"github.com/minio/pkg/env"
@@ -68,11 +69,11 @@ func subnetAuthHeaders(authToken string) map[string]string {
return map[string]string{"Authorization": "Bearer " + authToken}
}
func httpDo(client cluster.HTTPClientI, req *http.Request) (*http.Response, error) {
func httpDo(client utils.HTTPClientI, req *http.Request) (*http.Response, error) {
return client.Do(req)
}
func subnetReqDo(client cluster.HTTPClientI, r *http.Request, headers map[string]string) (string, error) {
func subnetReqDo(client utils.HTTPClientI, r *http.Request, headers map[string]string) (string, error) {
for k, v := range headers {
r.Header.Add(k, v)
}
@@ -100,7 +101,7 @@ func subnetReqDo(client cluster.HTTPClientI, r *http.Request, headers map[string
return respStr, fmt.Errorf("Request failed with code %d and error: %s", resp.StatusCode, respStr)
}
func subnetGetReq(client cluster.HTTPClientI, reqURL string, headers map[string]string) (string, error) {
func subnetGetReq(client utils.HTTPClientI, reqURL string, headers map[string]string) (string, error) {
r, e := http.NewRequest(http.MethodGet, reqURL, nil)
if e != nil {
return "", e
@@ -108,7 +109,7 @@ func subnetGetReq(client cluster.HTTPClientI, reqURL string, headers map[string]
return subnetReqDo(client, r, headers)
}
func subnetPostReq(client cluster.HTTPClientI, reqURL string, payload interface{}, headers map[string]string) (string, error) {
func subnetPostReq(client utils.HTTPClientI, reqURL string, payload interface{}, headers map[string]string) (string, error) {
body, e := json.Marshal(payload)
if e != nil {
return "", e

53
pkg/utils/http_client.go Normal file
View File

@@ -0,0 +1,53 @@
// This file is part of MinIO Console Server
// Copyright (c) 2022 MinIO, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
package utils
import (
"io"
"net/http"
)
// HTTPClientI interface with all functions to be implemented
// by mock when testing, it should include all HttpClient respective api calls
// that are used within this project.
type HTTPClientI interface {
Get(url string) (resp *http.Response, err error)
Post(url, contentType string, body io.Reader) (resp *http.Response, err error)
Do(req *http.Request) (*http.Response, error)
}
// HTTPClient Interface implementation
//
// Define the structure of a http client and define the functions that are actually used
type HTTPClient struct {
Client *http.Client
}
// Get implements http.Client.Get()
func (c *HTTPClient) Get(url string) (resp *http.Response, err error) {
return c.Client.Get(url)
}
// Post implements http.Client.Post()
func (c *HTTPClient) Post(url, contentType string, body io.Reader) (resp *http.Response, err error) {
return c.Client.Post(url, contentType, body)
}
// Do implement http.Client.Do()
func (c *HTTPClient) Do(req *http.Request) (*http.Response, error) {
return c.Client.Do(req)
}

51
pkg/utils/version.go Normal file
View File

@@ -0,0 +1,51 @@
// This file is part of MinIO Console Server
// Copyright (c) 2022 MinIO, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
package utils
import (
"errors"
"fmt"
"io/ioutil"
"regexp"
)
var (
ErrCantDetermineMinIOImage = errors.New("can't determine MinIO Image")
)
// getLatestMinIOImage returns the latest docker image for MinIO if found on the internet
func GetLatestMinIOImage(client HTTPClientI) (*string, error) {
resp, err := client.Get("https://dl.min.io/server/minio/release/linux-amd64/")
if err != nil {
return nil, err
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return nil, err
}
var re = regexp.MustCompile(`minio\.(RELEASE.*?Z)"`)
// look for a single match
matches := re.FindAllStringSubmatch(string(body), 1)
for i := range matches {
release := matches[i][1]
dockerImage := fmt.Sprintf("minio/minio:%s", release)
return &dockerImage, nil
}
return nil, ErrCantDetermineMinIOImage
}