mirror of
https://github.com/harness/drone.git
synced 2025-05-31 11:43:15 +00:00
feat: [CDE-530]:add mask secret (#3047)
* truncated sha256 * add hash value for MaskSecret * mark secrets for smc creds * fix nil reference * fix lint * fix unmarshall * implement unmarshall json func * add mask secret
This commit is contained in:
parent
e5456d663f
commit
deddbc8d68
@ -71,7 +71,7 @@ func (g *ServiceImpl) SetupCredentials(
|
||||
) error {
|
||||
script, err := template.GenerateScriptFromTemplate(
|
||||
templateSetupGitCredentials, &template.SetupGitCredentialsPayload{
|
||||
CloneURLWithCreds: resolvedRepoDetails.CloneURL,
|
||||
CloneURLWithCreds: resolvedRepoDetails.CloneURL.Value(),
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf(
|
||||
@ -94,7 +94,7 @@ func (g *ServiceImpl) CloneCode(
|
||||
defaultBaseImage string,
|
||||
gitspaceLogger types.GitspaceLogger,
|
||||
) error {
|
||||
cloneURL, err := url.Parse(resolvedRepoDetails.CloneURL)
|
||||
cloneURL, err := url.Parse(resolvedRepoDetails.CloneURL.Value())
|
||||
if err != nil {
|
||||
return fmt.Errorf(
|
||||
"failed to parse clone url %s: %w", resolvedRepoDetails.CloneURL, err)
|
||||
@ -108,7 +108,7 @@ func (g *ServiceImpl) CloneCode(
|
||||
}
|
||||
if resolvedRepoDetails.ResolvedCredentials.Credentials != nil {
|
||||
data.Email = resolvedRepoDetails.Credentials.Email
|
||||
data.Name = resolvedRepoDetails.Credentials.Name
|
||||
data.Name = resolvedRepoDetails.Credentials.Name.Value()
|
||||
}
|
||||
script, err := template.GenerateScriptFromTemplate(
|
||||
templateCloneCode, data)
|
||||
|
@ -196,11 +196,11 @@ func (s *GitnessSCM) ResolveCredentials(
|
||||
}
|
||||
userInfo := url.UserPassword("harness", jwtToken)
|
||||
modifiedURL.User = userInfo
|
||||
resolvedCredentails.CloneURL = modifiedURL.String()
|
||||
resolvedCredentails.CloneURL = types.NewMaskSecret(modifiedURL.String())
|
||||
credentials := &Credentials{
|
||||
Email: user.Email,
|
||||
Name: user.DisplayName,
|
||||
Password: jwtToken,
|
||||
Name: types.NewMaskSecret(user.DisplayName),
|
||||
Password: types.NewMaskSecret(jwtToken),
|
||||
}
|
||||
resolvedCredentails.Credentials = credentials
|
||||
return resolvedCredentails, nil
|
||||
|
@ -126,7 +126,7 @@ func (s *GenericSCM) ResolveCredentials(
|
||||
) (*ResolvedCredentials, error) {
|
||||
var resolvedCredentials = &ResolvedCredentials{
|
||||
Branch: gitspaceConfig.Branch,
|
||||
CloneURL: gitspaceConfig.CodeRepo.URL,
|
||||
CloneURL: types.NewMaskSecret(gitspaceConfig.CodeRepo.URL),
|
||||
}
|
||||
repoURL, err := url.Parse(gitspaceConfig.CodeRepo.URL)
|
||||
if err != nil {
|
||||
|
@ -70,7 +70,7 @@ func (s *SCM) CheckValidCodeRepo(
|
||||
return nil, fmt.Errorf("failed to resolve repo credentials and URL: %w", err)
|
||||
}
|
||||
|
||||
if branch, err = s.detectBranch(ctx, resolvedCreds.CloneURL); err == nil {
|
||||
if branch, err = s.detectBranch(ctx, resolvedCreds.CloneURL.Value()); err == nil {
|
||||
codeRepositoryResponse.Branch = branch
|
||||
}
|
||||
return codeRepositoryResponse, nil
|
||||
|
@ -43,13 +43,14 @@ type (
|
||||
// by an automated login process.
|
||||
Credentials struct {
|
||||
Email string
|
||||
Name string
|
||||
Password string
|
||||
Name *types.MaskSecret
|
||||
Password *types.MaskSecret
|
||||
}
|
||||
|
||||
ResolvedCredentials struct {
|
||||
Branch string
|
||||
CloneURL string
|
||||
Branch string
|
||||
// CloneURL contains credentials for private repositories in url prefix
|
||||
CloneURL *types.MaskSecret
|
||||
Credentials *Credentials
|
||||
RepoName string
|
||||
}
|
||||
|
73
types/mask_secret.go
Normal file
73
types/mask_secret.go
Normal file
@ -0,0 +1,73 @@
|
||||
// Copyright 2023 Harness, Inc.
|
||||
//
|
||||
// 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 types
|
||||
|
||||
import (
|
||||
"crypto/sha256"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
const maxTruncatedLen = 8
|
||||
|
||||
// MaskSecret is a wrapper to store decrypted secrets in memory. This is help to prevent them
|
||||
// from getting prints in logs and fmt.
|
||||
type MaskSecret struct {
|
||||
value string
|
||||
hashedValue string
|
||||
}
|
||||
|
||||
func NewMaskSecret(val string) *MaskSecret {
|
||||
hash := sha256.New()
|
||||
hash.Write([]byte(val))
|
||||
|
||||
hashedValueStr := fmt.Sprintf("%x", hash.Sum(nil))
|
||||
|
||||
return &MaskSecret{
|
||||
value: val,
|
||||
hashedValue: hashedValueStr[:maxTruncatedLen],
|
||||
}
|
||||
}
|
||||
|
||||
// Value returns the unmasked value of the MaskSecret.
|
||||
// Use cautiously to avoid exposing sensitive data.
|
||||
func (s *MaskSecret) Value() string {
|
||||
if s == nil {
|
||||
return ""
|
||||
}
|
||||
return s.value
|
||||
}
|
||||
|
||||
func (s *MaskSecret) String() string {
|
||||
if s == nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
return s.hashedValue
|
||||
}
|
||||
|
||||
func (s *MaskSecret) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal(s.value)
|
||||
}
|
||||
|
||||
func (s *MaskSecret) UnmarshalJSON(data []byte) error {
|
||||
var input string
|
||||
if err := json.Unmarshal(data, &input); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
s.value = input
|
||||
return nil
|
||||
}
|
@ -81,10 +81,10 @@ type PlatformConnectorSpec struct {
|
||||
type PlatformConnectorAuthSpec struct {
|
||||
AuthType PlatformConnectorAuthType
|
||||
// userName can be empty when userName is encrypted.
|
||||
UserName string
|
||||
UserName *MaskSecret
|
||||
// UserNameRef can be empty when userName is not encrypted
|
||||
UserNameRef string
|
||||
Password string
|
||||
Password *MaskSecret
|
||||
PasswordRef string
|
||||
}
|
||||
|
||||
@ -103,7 +103,7 @@ func (c PlatformConnectorSpec) ExtractRegistryURL() string {
|
||||
|
||||
func (c PlatformConnectorAuthSpec) ExtractUserName() string {
|
||||
if c.AuthType == UserNamePasswordPlatformConnectorAuthType {
|
||||
return c.UserName
|
||||
return c.UserName.Value()
|
||||
}
|
||||
|
||||
return ""
|
||||
@ -127,7 +127,7 @@ func (c PlatformConnectorAuthSpec) ExtractPasswordRef() string {
|
||||
|
||||
func (c PlatformConnectorAuthSpec) ExtractPassword() string {
|
||||
if c.AuthType == UserNamePasswordPlatformConnectorAuthType {
|
||||
return c.Password
|
||||
return c.Password.Value()
|
||||
}
|
||||
|
||||
return ""
|
||||
|
Loading…
x
Reference in New Issue
Block a user