diff --git a/chart-sync/App.go b/chart-sync/App.go
index 312939866..668fcf2ab 100644
--- a/chart-sync/App.go
+++ b/chart-sync/App.go
@@ -3,6 +3,7 @@ package main
import (
"github.com/devtron-labs/chart-sync/internals"
"github.com/devtron-labs/chart-sync/pkg"
+ "github.com/devtron-labs/common-lib/securestore"
"github.com/go-pg/pg"
"github.com/prometheus/client_golang/prometheus/promhttp"
"go.uber.org/zap"
@@ -22,12 +23,17 @@ func NewApp(Logger *zap.SugaredLogger,
db *pg.DB,
syncService pkg.SyncService,
configuration *internals.Configuration) *App {
+ err := securestore.SetEncryptionKey()
+ if err != nil {
+ Logger.Errorw("error in setting encryption key", "err", err)
+ }
return &App{
Logger: Logger,
db: db,
syncService: syncService,
configuration: configuration,
}
+
}
func (app *App) Start() {
diff --git a/chart-sync/env_gen.json b/chart-sync/env_gen.json
index d09dd9336..f27709593 100644
--- a/chart-sync/env_gen.json
+++ b/chart-sync/env_gen.json
@@ -1 +1 @@
-[{"Category":"DEVTRON","Fields":[{"Env":"APP","EnvType":"string","EnvValue":"chart-sync","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"APP_STORE_APPLICATION_VERSIONS_SAVE_CHUNK_SIZE","EnvType":"int","EnvValue":"20","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"APP_SYNC_SHUTDOWN_WAIT_DURATION","EnvType":"int","EnvValue":"120","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"CHART_PROVIDER_ID","EnvType":"string","EnvValue":"*","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"IS_OCI_REGISTRY","EnvType":"bool","EnvValue":"true","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"LOG_LEVEL","EnvType":"int","EnvValue":"0","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"PARALLELISM_LIMIT_FOR_TAG_PROCESSING","EnvType":"int","EnvValue":"0","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"PG_ADDR","EnvType":"string","EnvValue":"127.0.0.1","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"PG_DATABASE","EnvType":"string","EnvValue":"orchestrator","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"PG_EXPORT_PROM_METRICS","EnvType":"bool","EnvValue":"true","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"PG_LOG_ALL_FAILURE_QUERIES","EnvType":"bool","EnvValue":"true","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"PG_LOG_ALL_QUERY","EnvType":"bool","EnvValue":"false","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"PG_LOG_SLOW_QUERY","EnvType":"bool","EnvValue":"true","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"PG_PASSWORD","EnvType":"string","EnvValue":"password","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"PG_PORT","EnvType":"string","EnvValue":"5432","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"PG_QUERY_DUR_THRESHOLD","EnvType":"int64","EnvValue":"5000","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"PG_USER","EnvType":"string","EnvValue":"user","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"PROMETHEUS_MATRIX_PORT","EnvType":"int","EnvValue":"8080","EnvDescription":"","Example":"","Deprecated":"false"}]}]
\ No newline at end of file
+[{"Category":"DEVTRON","Fields":[{"Env":"APP","EnvType":"string","EnvValue":"chart-sync","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"APP_STORE_APPLICATION_VERSIONS_SAVE_CHUNK_SIZE","EnvType":"int","EnvValue":"20","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"APP_SYNC_SHUTDOWN_WAIT_DURATION","EnvType":"int","EnvValue":"120","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"CHART_PROVIDER_ID","EnvType":"string","EnvValue":"*","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"IS_OCI_REGISTRY","EnvType":"bool","EnvValue":"true","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"LOG_LEVEL","EnvType":"int","EnvValue":"0","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"PARALLELISM_LIMIT_FOR_TAG_PROCESSING","EnvType":"int","EnvValue":"0","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"PG_ADDR","EnvType":"string","EnvValue":"127.0.0.1","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"PG_DATABASE","EnvType":"string","EnvValue":"orchestrator","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"PG_EXPORT_PROM_METRICS","EnvType":"bool","EnvValue":"true","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"PG_LOG_ALL_FAILURE_QUERIES","EnvType":"bool","EnvValue":"true","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"PG_LOG_ALL_QUERY","EnvType":"bool","EnvValue":"false","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"PG_LOG_SLOW_QUERY","EnvType":"bool","EnvValue":"true","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"PG_PASSWORD","EnvType":"string","EnvValue":"password","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"PG_PORT","EnvType":"string","EnvValue":"5432","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"PG_QUERY_DUR_THRESHOLD","EnvType":"int64","EnvValue":"5000","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"PG_USER","EnvType":"string","EnvValue":"user","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"PROMETHEUS_MATRIX_PORT","EnvType":"int","EnvValue":"8080","EnvDescription":"","Example":"","Deprecated":"false"}]},{"Category":"POSTGRES","Fields":[{"Env":"CASBIN_DATABASE","EnvType":"string","EnvValue":"casbin","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"PG_READ_TIMEOUT","EnvType":"int64","EnvValue":"30","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"PG_WRITE_TIMEOUT","EnvType":"int64","EnvValue":"30","EnvDescription":"","Example":"","Deprecated":"false"}]}]
\ No newline at end of file
diff --git a/chart-sync/env_gen.md b/chart-sync/env_gen.md
index bc983e60a..b7296c54f 100644
--- a/chart-sync/env_gen.md
+++ b/chart-sync/env_gen.md
@@ -22,3 +22,11 @@
| PG_USER | string |user | | | false |
| PROMETHEUS_MATRIX_PORT | int |8080 | | | false |
+
+## POSTGRES Related Environment Variables
+| Key | Type | Default Value | Description | Example | Deprecated |
+|-------|----------|-------------------|-------------------|-----------------------|------------------|
+ | CASBIN_DATABASE | string |casbin | | | false |
+ | PG_READ_TIMEOUT | int64 |30 | | | false |
+ | PG_WRITE_TIMEOUT | int64 |30 | | | false |
+
diff --git a/chart-sync/go.mod b/chart-sync/go.mod
index 3f70584cf..f7db255bf 100644
--- a/chart-sync/go.mod
+++ b/chart-sync/go.mod
@@ -4,7 +4,7 @@ go 1.24.0
toolchain go1.24.3
-replace github.com/devtron-labs/common-lib => github.com/devtron-labs/devtron-services/common-lib v0.0.0-20250901093002-1be330be4db3
+replace github.com/devtron-labs/common-lib => github.com/devtron-labs/devtron-services/common-lib v0.0.0-20251013041509-9d1c5175da2d
require (
github.com/caarlos0/env v3.5.0+incompatible
diff --git a/chart-sync/go.sum b/chart-sync/go.sum
index 50f0fe981..e45277c8f 100644
--- a/chart-sync/go.sum
+++ b/chart-sync/go.sum
@@ -43,8 +43,8 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
-github.com/devtron-labs/devtron-services/common-lib v0.0.0-20250901093002-1be330be4db3 h1:jCxpB8+6KD29jenB4SLTimCYzsmazBAPKv6637xRT5M=
-github.com/devtron-labs/devtron-services/common-lib v0.0.0-20250901093002-1be330be4db3/go.mod h1:/Ciy9tD9OxZOWBDPIasM448H7uvSo4+ZJiExpfwBZpA=
+github.com/devtron-labs/devtron-services/common-lib v0.0.0-20251013041509-9d1c5175da2d h1:EAGZ+sei6Hl98Hp09HgNcnOIWgI43jcx1q0Mb6V5HdQ=
+github.com/devtron-labs/devtron-services/common-lib v0.0.0-20251013041509-9d1c5175da2d/go.mod h1:/Ciy9tD9OxZOWBDPIasM448H7uvSo4+ZJiExpfwBZpA=
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
github.com/distribution/distribution/v3 v3.0.0 h1:q4R8wemdRQDClzoNNStftB2ZAfqOiN6UX90KJc4HjyM=
diff --git a/chart-sync/internals/sql/DockerArtifactStoreRepository.go b/chart-sync/internals/sql/DockerArtifactStoreRepository.go
index 5094af2b4..b875ea27c 100644
--- a/chart-sync/internals/sql/DockerArtifactStoreRepository.go
+++ b/chart-sync/internals/sql/DockerArtifactStoreRepository.go
@@ -18,6 +18,7 @@
package sql
import (
+ "github.com/devtron-labs/common-lib/securestore"
"github.com/go-pg/pg"
"github.com/go-pg/pg/orm"
)
@@ -41,23 +42,23 @@ type RegistryType string
var OCI_REGISRTY_REPO_TYPE_LIST = []string{OCI_REGISRTY_REPO_TYPE_CONTAINER, OCI_REGISRTY_REPO_TYPE_CHART}
type DockerArtifactStore struct {
- tableName struct{} `sql:"docker_artifact_store" json:",omitempty" pg:",discard_unknown_columns"`
- Id string `sql:"id,pk" json:"id,,omitempty"`
- PluginId string `sql:"plugin_id,notnull" json:"pluginId,omitempty"`
- RegistryURL string `sql:"registry_url" json:"registryUrl,omitempty"`
- RegistryType RegistryType `sql:"registry_type,notnull" json:"registryType,omitempty"`
- IsOCICompliantRegistry bool `sql:"is_oci_compliant_registry,notnull" json:"isOCICompliantRegistry,omitempty"`
- AWSAccessKeyId string `sql:"aws_accesskey_id" json:"awsAccessKeyId,omitempty" `
- AWSSecretAccessKey string `sql:"aws_secret_accesskey" json:"awsSecretAccessKey,omitempty"`
- AWSRegion string `sql:"aws_region" json:"awsRegion,omitempty"`
- Username string `sql:"username" json:"username,omitempty"`
- Password string `sql:"password" json:"password,omitempty"`
- IsDefault bool `sql:"is_default,notnull" json:"isDefault"`
- Connection string `sql:"connection" json:"connection,omitempty"`
- Cert string `sql:"cert" json:"cert,omitempty"`
- Active bool `sql:"active,notnull" json:"active"`
- RemoteConnectionConfigId int `sql:"remote_connection_config_id"`
- CredentialsType string `sql:"credentials_type,notnull"`
+ tableName struct{} `sql:"docker_artifact_store" json:",omitempty" pg:",discard_unknown_columns"`
+ Id string `sql:"id,pk" json:"id,,omitempty"`
+ PluginId string `sql:"plugin_id,notnull" json:"pluginId,omitempty"`
+ RegistryURL string `sql:"registry_url" json:"registryUrl,omitempty"`
+ RegistryType RegistryType `sql:"registry_type,notnull" json:"registryType,omitempty"`
+ IsOCICompliantRegistry bool `sql:"is_oci_compliant_registry,notnull" json:"isOCICompliantRegistry,omitempty"`
+ AWSAccessKeyId string `sql:"aws_accesskey_id" json:"awsAccessKeyId,omitempty" `
+ AWSSecretAccessKey securestore.EncryptedString `sql:"aws_secret_accesskey" json:"awsSecretAccessKey,omitempty"`
+ AWSRegion string `sql:"aws_region" json:"awsRegion,omitempty"`
+ Username string `sql:"username" json:"username,omitempty"`
+ Password securestore.EncryptedString `sql:"password" json:"password,omitempty"`
+ IsDefault bool `sql:"is_default,notnull" json:"isDefault"`
+ Connection string `sql:"connection" json:"connection,omitempty"`
+ Cert string `sql:"cert" json:"cert,omitempty"`
+ Active bool `sql:"active,notnull" json:"active"`
+ RemoteConnectionConfigId int `sql:"remote_connection_config_id"`
+ CredentialsType string `sql:"credentials_type,notnull"`
OCIRegistryConfig []*OCIRegistryConfig
RemoteConnectionConfig *RemoteConnectionConfig
AuditLog
diff --git a/chart-sync/internals/sql/remoteConnectionConfigRepository.go b/chart-sync/internals/sql/remoteConnectionConfigRepository.go
index d93302e7b..28c9ed525 100644
--- a/chart-sync/internals/sql/remoteConnectionConfigRepository.go
+++ b/chart-sync/internals/sql/remoteConnectionConfigRepository.go
@@ -1,20 +1,21 @@
package sql
import (
+ "github.com/devtron-labs/common-lib/securestore"
"github.com/go-pg/pg"
"go.uber.org/zap"
)
type RemoteConnectionConfig struct {
- tableName struct{} `sql:"remote_connection_config" pg:",discard_unknown_columns"`
- Id int `sql:"id,pk"`
- ConnectionMethod string `sql:"connection_method"`
- ProxyUrl string `sql:"proxy_url"`
- SSHServerAddress string `sql:"ssh_server_address"`
- SSHUsername string `sql:"ssh_username"`
- SSHPassword string `sql:"ssh_password"`
- SSHAuthKey string `sql:"ssh_auth_key"`
- Deleted bool `sql:"deleted,notnull"`
+ tableName struct{} `sql:"remote_connection_config" pg:",discard_unknown_columns"`
+ Id int `sql:"id,pk"`
+ ConnectionMethod string `sql:"connection_method"`
+ ProxyUrl string `sql:"proxy_url"`
+ SSHServerAddress string `sql:"ssh_server_address"`
+ SSHUsername string `sql:"ssh_username"`
+ SSHPassword securestore.EncryptedString `sql:"ssh_password"`
+ SSHAuthKey securestore.EncryptedString `sql:"ssh_auth_key"`
+ Deleted bool `sql:"deleted,notnull"`
AuditLog
}
diff --git a/chart-sync/pkg/registry/adapter.go b/chart-sync/pkg/registry/adapter.go
index b81419cb4..5c7adcb24 100644
--- a/chart-sync/pkg/registry/adapter.go
+++ b/chart-sync/pkg/registry/adapter.go
@@ -19,8 +19,8 @@ func NewToRegistryConfig(store *sql.DockerArtifactStore) (*registry.Configuratio
remoteConnectionConfig.SSHTunnelConfig = &bean.SSHTunnelConfig{
SSHServerAddress: store.RemoteConnectionConfig.SSHServerAddress,
SSHUsername: store.RemoteConnectionConfig.SSHUsername,
- SSHPassword: store.RemoteConnectionConfig.SSHPassword,
- SSHAuthKey: store.RemoteConnectionConfig.SSHAuthKey,
+ SSHPassword: store.RemoteConnectionConfig.SSHPassword.String(),
+ SSHAuthKey: store.RemoteConnectionConfig.SSHAuthKey.String(),
}
}
}
@@ -36,9 +36,9 @@ func NewToRegistryConfig(store *sql.DockerArtifactStore) (*registry.Configuratio
RegistryId: store.Id,
RegistryUrl: store.RegistryURL,
Username: store.Username,
- Password: store.Password,
+ Password: store.Password.String(),
AwsAccessKey: store.AWSAccessKeyId,
- AwsSecretKey: store.AWSSecretAccessKey,
+ AwsSecretKey: store.AWSSecretAccessKey.String(),
AwsRegion: store.AWSRegion,
RegistryConnectionType: store.Connection,
RegistryCertificateString: store.Cert,
diff --git a/chart-sync/vendor/github.com/devtron-labs/common-lib/securestore/AttributesRepoDBConnection.go b/chart-sync/vendor/github.com/devtron-labs/common-lib/securestore/AttributesRepoDBConnection.go
new file mode 100644
index 000000000..907d202bd
--- /dev/null
+++ b/chart-sync/vendor/github.com/devtron-labs/common-lib/securestore/AttributesRepoDBConnection.go
@@ -0,0 +1,75 @@
+package securestore
+
+import (
+ "github.com/caarlos0/env"
+ "github.com/devtron-labs/common-lib/utils"
+ "github.com/devtron-labs/common-lib/utils/bean"
+ "github.com/go-pg/pg"
+ "log"
+)
+
+func NewAttributesRepositoryImplForDatabase(databaseName string) (*AttributesRepositoryImpl, error) {
+ dbConn, err := newDbConnection(databaseName)
+ if err != nil {
+ return nil, err
+ }
+ return NewAttributesRepositoryImpl(dbConn), nil
+}
+
+type config struct {
+ Addr string `env:"PG_ADDR" envDefault:"127.0.0.1"`
+ Port string `env:"PG_PORT" envDefault:"5432"`
+ User string `env:"PG_USER" envDefault:""`
+ Password string `env:"PG_PASSWORD" envDefault:"" secretData:"-"`
+ Database string `env:"PG_DATABASE" envDefault:"orchestrator"`
+ ApplicationName string `env:"APP" envDefault:"orchestrator"`
+ bean.PgQueryMonitoringConfig
+ LocalDev bool `env:"RUNTIME_CONFIG_LOCAL_DEV" envDefault:"false"`
+}
+
+func getDbConfig(databaseName string) (*config, error) {
+ cfg := &config{}
+ err := env.Parse(cfg)
+ if err != nil {
+ return cfg, err
+ }
+ monitoringCfg, err := bean.GetPgQueryMonitoringConfig(cfg.ApplicationName)
+ if err != nil {
+ return cfg, err
+ }
+ cfg.PgQueryMonitoringConfig = monitoringCfg
+ if !cfg.LocalDev {
+ cfg.Database = databaseName //overriding database
+ }
+ return cfg, err
+}
+
+func newDbConnection(databaseName string) (*pg.DB, error) {
+ cfg, err := getDbConfig(databaseName)
+ if err != nil {
+ return nil, err
+ }
+ options := pg.Options{
+ Addr: cfg.Addr + ":" + cfg.Port,
+ User: cfg.User,
+ Password: cfg.Password,
+ Database: cfg.Database,
+ ApplicationName: cfg.ApplicationName,
+ }
+ dbConnection := pg.Connect(&options)
+ //check db connection
+ var test string
+ _, err = dbConnection.QueryOne(&test, `SELECT 1`)
+
+ if err != nil {
+ log.Println("error in connecting orchestrator db ", "err", err)
+ return nil, err
+ } else {
+ log.Println("connected with orchestrator db")
+ }
+ //--------------
+ if cfg.LogSlowQuery {
+ dbConnection.OnQueryProcessed(utils.GetPGPostQueryProcessor(cfg.PgQueryMonitoringConfig))
+ }
+ return dbConnection, err
+}
diff --git a/chart-sync/vendor/github.com/devtron-labs/common-lib/securestore/AttributesRepository.go b/chart-sync/vendor/github.com/devtron-labs/common-lib/securestore/AttributesRepository.go
new file mode 100644
index 000000000..eadf7a8f4
--- /dev/null
+++ b/chart-sync/vendor/github.com/devtron-labs/common-lib/securestore/AttributesRepository.go
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 2020-2024. Devtron Inc.
+ */
+
+package securestore
+
+import (
+ sql2 "github.com/devtron-labs/common-lib/utils/sql"
+ "github.com/go-pg/pg"
+ "time"
+)
+
+const ENCRYPTION_KEY string = "encryptionKey" // AES-256 encryption key for sensitive data
+
+type Attributes struct {
+ tableName struct{} `sql:"attributes" pg:",discard_unknown_columns"`
+ Id int `sql:"id,pk"`
+ Key string `sql:"key,notnull"`
+ Value string `sql:"value,notnull"`
+ Active bool `sql:"active, notnull"`
+ sql2.AuditLog
+}
+
+type AttributesRepository interface {
+ Save(model *Attributes, tx *pg.Tx) (*Attributes, error)
+ Update(model *Attributes, tx *pg.Tx) error
+ FindByKey(key string) (*Attributes, error)
+ GetConnection() (dbConnection *pg.DB)
+ SaveEncryptionKeyIfNotExists(value string) error
+ GetEncryptionKey() (string, error)
+}
+
+type AttributesRepositoryImpl struct {
+ dbConnection *pg.DB
+}
+
+func NewAttributesRepositoryImpl(dbConnection *pg.DB) *AttributesRepositoryImpl {
+ return &AttributesRepositoryImpl{dbConnection: dbConnection}
+}
+
+func (impl *AttributesRepositoryImpl) GetConnection() (dbConnection *pg.DB) {
+ return impl.dbConnection
+}
+
+func (repo AttributesRepositoryImpl) Save(model *Attributes, tx *pg.Tx) (*Attributes, error) {
+ err := tx.Insert(model)
+ if err != nil {
+ return model, err
+ }
+ return model, nil
+}
+
+func (repo AttributesRepositoryImpl) Update(model *Attributes, tx *pg.Tx) error {
+ err := tx.Update(model)
+ if err != nil {
+ return err
+ }
+ return nil
+}
+
+func (repo AttributesRepositoryImpl) FindByKey(key string) (*Attributes, error) {
+ model := &Attributes{}
+ err := repo.dbConnection.
+ Model(model).
+ Where("key = ?", key).
+ Where("active = ?", true).
+ Select()
+ if err != nil {
+ return model, err
+ }
+ return model, nil
+}
+
+// SaveEncryptionKeyIfNotExists saves an encryption key in the attributes table if not exists
+func (repo AttributesRepositoryImpl) SaveEncryptionKeyIfNotExists(value string) error {
+ dbConnection := repo.GetConnection()
+ tx, err := dbConnection.Begin()
+ if err != nil {
+ return err
+ }
+ defer tx.Rollback()
+
+ //deleting all keys if exists for safe side
+ _, err = tx.Model(&Attributes{}).Where("key = ?", ENCRYPTION_KEY).Delete()
+ // Create new encryption key entry
+ model := &Attributes{
+ Key: ENCRYPTION_KEY,
+ Value: value,
+ Active: true,
+ AuditLog: sql2.AuditLog{
+ CreatedBy: 1,
+ UpdatedBy: 1,
+ CreatedOn: time.Now(),
+ UpdatedOn: time.Now(),
+ },
+ }
+ _, err = repo.Save(model, tx)
+ if err != nil {
+ return err
+ }
+ return tx.Commit()
+}
+
+// GetEncryptionKey retrieves the active encryption key from the attributes table
+func (repo AttributesRepositoryImpl) GetEncryptionKey() (string, error) {
+ model, err := repo.FindByKey(ENCRYPTION_KEY)
+ if err != nil {
+ return "", err
+ }
+ return model.Value, nil
+}
diff --git a/chart-sync/vendor/github.com/devtron-labs/common-lib/securestore/EncryptionKeyService.go b/chart-sync/vendor/github.com/devtron-labs/common-lib/securestore/EncryptionKeyService.go
new file mode 100644
index 000000000..f8a37acec
--- /dev/null
+++ b/chart-sync/vendor/github.com/devtron-labs/common-lib/securestore/EncryptionKeyService.go
@@ -0,0 +1,136 @@
+/*
+ * Copyright (c) 2024. Devtron Inc.
+ */
+
+package securestore
+
+import (
+ "crypto/rand"
+ "encoding/hex"
+ "fmt"
+ "github.com/go-pg/pg"
+ log "github.com/sirupsen/logrus"
+)
+
+func SetEncryptionKey() error {
+ repo, err := NewAttributesRepositoryImplForDatabase("orchestrator") //hardcoded for orchestrator as need to pick a common key for every service
+ if err != nil {
+ log.Println("error in creating attributes repository", "err", err)
+ return err
+ }
+ encryptionService := NewEncryptionKeyServiceImpl(repo)
+ err = encryptionService.CreateAndStoreEncryptionKey()
+ if err != nil {
+ log.Println("error in creating and storing encryption key", "err", err)
+ return err
+ }
+ return nil
+}
+
+type EncryptionKeyService interface {
+ // CreateAndStoreEncryptionKey generates a new AES-256 encryption key and stores it in the attributes repository
+ CreateAndStoreEncryptionKey() error
+
+ // RotateEncryptionKey generates a new encryption key and stores it (deactivating the old one)
+ RotateEncryptionKey(userId int32) (string, error)
+
+ // GenerateEncryptionKey generates a new AES-256 encryption key (32 bytes)
+ GenerateEncryptionKey() (string, error)
+
+ GetEncryptionKey() (string, error)
+}
+
+type EncryptionKeyServiceImpl struct {
+ attributesRepository AttributesRepository
+}
+
+func NewEncryptionKeyServiceImpl(attributesRepository AttributesRepository) *EncryptionKeyServiceImpl {
+ impl := &EncryptionKeyServiceImpl{
+ attributesRepository: attributesRepository,
+ }
+ return impl
+}
+
+// GenerateEncryptionKey generates a new AES-256 encryption key (32 bytes = 256 bits)
+func (impl *EncryptionKeyServiceImpl) GenerateEncryptionKey() (string, error) {
+ // Generate 32 random bytes for AES-256
+ key := make([]byte, 32)
+ _, err := rand.Read(key)
+ if err != nil {
+ log.Error("error generating random encryption key", "err", err)
+ return "", fmt.Errorf("failed to generate encryption key: %w", err)
+ }
+ // Encode to hex string for storage
+ keyHex := hex.EncodeToString(key)
+ return keyHex, nil
+}
+
+// CreateAndStoreEncryptionKey generates a new AES-256 encryption key and stores it in the attributes repository
+func (impl *EncryptionKeyServiceImpl) CreateAndStoreEncryptionKey() error {
+ // Check if encryption key already exists
+ encryptionKeyModel, err := impl.attributesRepository.FindByKey(ENCRYPTION_KEY)
+ if err != nil && err != pg.ErrNoRows {
+ log.Error("error checking for existing encryption key", "err", err)
+ return err
+ }
+ var encryptionKeyEncoded string
+ if encryptionKeyModel != nil && encryptionKeyModel.Id > 0 && len(encryptionKeyModel.Value) > 0 {
+ encryptionKeyEncoded = encryptionKeyModel.Value
+ log.Println("encryption key already exists", "keyId", encryptionKeyModel.Id)
+ } else {
+ // Generate new encryption key
+ encryptionKeyNew, err := impl.GenerateEncryptionKey()
+ if err != nil {
+ return err
+ }
+ // Store in repository
+ err = impl.attributesRepository.SaveEncryptionKeyIfNotExists(encryptionKeyNew)
+ if err != nil {
+ log.Error("error storing encryption key", "err", err)
+ return fmt.Errorf("failed to store encryption key: %w", err)
+ }
+ encryptionKeyEncoded = encryptionKeyNew
+ log.Println("Successfully created and stored encryption key")
+ }
+
+ encryptionKey, err = hex.DecodeString(encryptionKeyEncoded)
+ if err != nil || len(encryptionKey) != 32 {
+ return fmt.Errorf("encryptionKey is incorrect : %v", err)
+ }
+ return nil
+}
+
+// RotateEncryptionKey generates a new encryption key and stores it (deactivating the old one)
+func (impl *EncryptionKeyServiceImpl) RotateEncryptionKey(userId int32) (string, error) {
+ log.Println("Rotating encryption key", "userId", userId)
+
+ // Generate new encryption key
+ newEncryptionKey, err := impl.GenerateEncryptionKey()
+ if err != nil {
+ return "", err
+ }
+
+ // Store in repository (this will deactivate the old key)
+ err = impl.attributesRepository.SaveEncryptionKeyIfNotExists(newEncryptionKey)
+ if err != nil {
+ log.Error("error rotating encryption key", "err", err)
+ return "", fmt.Errorf("failed to rotate encryption key: %w", err)
+ }
+ //TODO: also need to rotate encryption's already done
+ log.Println("Successfully rotated encryption key", "userId", userId)
+ return newEncryptionKey, nil
+}
+
+// GetEncryptionKey retrieves the active encryption key from the repository
+func (impl *EncryptionKeyServiceImpl) GetEncryptionKey() (string, error) {
+ key, err := impl.attributesRepository.GetEncryptionKey()
+ if err != nil {
+ if err == pg.ErrNoRows {
+ log.Error("encryption key not found in repository")
+ return "", fmt.Errorf("encryption key not found, please create one first")
+ }
+ log.Error("error retrieving encryption key", "err", err)
+ return "", err
+ }
+ return key, nil
+}
diff --git a/chart-sync/vendor/github.com/devtron-labs/common-lib/securestore/common.go b/chart-sync/vendor/github.com/devtron-labs/common-lib/securestore/common.go
new file mode 100644
index 000000000..4444765e3
--- /dev/null
+++ b/chart-sync/vendor/github.com/devtron-labs/common-lib/securestore/common.go
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2024. Devtron Inc.
+ */
+
+package securestore
+
+import (
+ "crypto/aes"
+ "crypto/cipher"
+ "crypto/rand"
+ "encoding/base64"
+ "encoding/json"
+ "errors"
+ "fmt"
+ "github.com/go-pg/pg/types"
+ "io"
+)
+
+var decryptionFailErr = fmt.Errorf("Decryption failed")
+
+func DidDecryptionFail(err error) bool {
+ return errors.Is(err, decryptionFailErr)
+}
+
+var encryptionKey []byte
+
+func encrypt(data []byte) (string, error) {
+ if len(data) == 0 {
+ return "", nil
+ }
+ block, err := aes.NewCipher(encryptionKey)
+ if err != nil {
+ return "", err
+ }
+ aesGCM, err := cipher.NewGCM(block)
+ if err != nil {
+ return "", err
+ }
+ nonce := make([]byte, aesGCM.NonceSize())
+ if _, err := io.ReadFull(rand.Reader, nonce); err != nil {
+ return "", err
+ }
+ ciphertext := aesGCM.Seal(nonce, nonce, data, nil)
+ return base64.StdEncoding.EncodeToString(ciphertext), nil
+}
+
+func decrypt(cipherBase64 string) (string, error) {
+ // Try decrypting (normal encrypted flow)
+ cipherData, err := base64.StdEncoding.DecodeString(cipherBase64)
+ if err == nil {
+ block, err := aes.NewCipher(encryptionKey)
+ if err != nil {
+ return "", err
+ }
+ aesGCM, err := cipher.NewGCM(block)
+ if err != nil {
+ return "", err
+ }
+ nonceSize := aesGCM.NonceSize()
+ if len(cipherData) >= nonceSize {
+ nonce, ciphertext := cipherData[:nonceSize], cipherData[nonceSize:]
+ plainText, err := aesGCM.Open(nil, nonce, ciphertext, nil)
+ if err == nil {
+ return string(plainText), nil // Successfully decrypted
+ }
+ }
+ }
+ return cipherBase64, decryptionFailErr
+}
+
+// AppendValue : can be used for auto encryption of fields but is only supported in go-pg/v10. Not being used anywhere as of now, to be tested when start using.
+func (e EncryptedMap) AppendValue(b []byte, quote int) ([]byte, error) {
+ jsonBytes, err := json.Marshal(e)
+ if err != nil {
+ return nil, err
+ }
+
+ encryptedString, err := encrypt(jsonBytes)
+ if err != nil {
+ return nil, err
+ }
+
+ return types.AppendString(b, encryptedString, quote), nil
+}
diff --git a/chart-sync/vendor/github.com/devtron-labs/common-lib/securestore/map.go b/chart-sync/vendor/github.com/devtron-labs/common-lib/securestore/map.go
new file mode 100644
index 000000000..dd9c25846
--- /dev/null
+++ b/chart-sync/vendor/github.com/devtron-labs/common-lib/securestore/map.go
@@ -0,0 +1,73 @@
+package securestore
+
+import (
+ "encoding/json"
+ "fmt"
+)
+
+type EncryptedMap map[string]string
+
+const (
+ ENCRYPTED_KEY = "encrypted_data"
+)
+
+func EncryptMap(m EncryptedMap) (map[string]string, error) {
+ bytesM, err := json.Marshal(m)
+ if err != nil {
+ return nil, err
+ }
+ encryptedData, err := encrypt(bytesM)
+ if err != nil {
+ return nil, err
+ }
+ return EncryptedMap{ENCRYPTED_KEY: encryptedData}, nil
+}
+
+func decryptMap(mCipher []byte) (map[string]string, error) {
+ var m map[string]string
+ err := json.Unmarshal(mCipher, &m)
+ if err != nil {
+ return nil, err
+ }
+ if len(m[ENCRYPTED_KEY]) > 0 {
+ decryptedMapBytes, err := decrypt(m[ENCRYPTED_KEY])
+ if err != nil && !DidDecryptionFail(err) {
+ return nil, err
+ }
+ if err == nil {
+ var decryptedMap map[string]string
+ err = json.Unmarshal([]byte(decryptedMapBytes), &decryptedMap)
+ if err != nil {
+ return nil, err
+ }
+ return decryptedMap, nil
+ }
+ } else {
+ // Fallback: maybe it's just raw JSON
+ // Validate that it's a valid JSON map[string]string
+ // Neither decrypted nor valid plaintext JSON
+ return m, nil
+ }
+ return nil, fmt.Errorf("decryption failed and data is not valid plaintext JSON")
+}
+
+func (e *EncryptedMap) Scan(value interface{}) error {
+ if value == nil {
+ return nil
+ }
+ var encrypted []byte
+ switch v := value.(type) {
+ case string:
+ encrypted = []byte(v)
+ case []byte:
+ encrypted = v
+ default:
+ return fmt.Errorf("unsupported type: %T", v)
+ }
+ var err error
+ *e, err = decryptMap(encrypted)
+ if err != nil {
+ return err
+ }
+ return nil
+}
diff --git a/chart-sync/vendor/github.com/devtron-labs/common-lib/securestore/strings.go b/chart-sync/vendor/github.com/devtron-labs/common-lib/securestore/strings.go
new file mode 100644
index 000000000..e7c5128b2
--- /dev/null
+++ b/chart-sync/vendor/github.com/devtron-labs/common-lib/securestore/strings.go
@@ -0,0 +1,60 @@
+package securestore
+
+import (
+ "fmt"
+)
+
+type EncryptedString string
+
+func (e *EncryptedString) String() string {
+ return string(*e)
+}
+
+func ToEncryptedString(s string) EncryptedString {
+ return EncryptedString(s)
+}
+
+func EncryptString(data string) (EncryptedString, error) {
+ encryptedStr, err := encrypt([]byte(data))
+ if err != nil {
+ return "", err
+ }
+ return EncryptedString(encryptedStr), nil
+}
+
+func decryptString(cipherBase64 string) (string, error) {
+ decryptedBytes, err := decrypt(cipherBase64)
+ if err != nil && !DidDecryptionFail(err) {
+ return "", err
+ }
+ // Fallback: decrypting failed, considering it as just normal string
+ if DidDecryptionFail(err) {
+ return cipherBase64, nil
+ } else {
+ return decryptedBytes, nil
+ }
+}
+
+func (e *EncryptedString) Scan(value interface{}) error {
+ if value == nil {
+ return nil
+ }
+ var encrypted []byte
+ switch v := value.(type) {
+ case string:
+ encrypted = []byte(v)
+ case []byte:
+ encrypted = v
+ default:
+ return fmt.Errorf("unsupported type: %T", v)
+ }
+ decryptedBytes, err := decryptString(string(encrypted))
+ if err != nil {
+ return err
+ }
+ if decryptedBytes == "" {
+ return nil
+ }
+ *e = EncryptedString(decryptedBytes)
+ return nil
+}
diff --git a/chart-sync/vendor/github.com/devtron-labs/common-lib/utils/sql/AuditLog.go b/chart-sync/vendor/github.com/devtron-labs/common-lib/utils/sql/AuditLog.go
new file mode 100644
index 000000000..fb3a38e79
--- /dev/null
+++ b/chart-sync/vendor/github.com/devtron-labs/common-lib/utils/sql/AuditLog.go
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2020-2024. Devtron 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 sql
+
+import (
+ "time"
+)
+
+type AuditLog struct {
+ CreatedOn time.Time `sql:"created_on,type:timestamptz"`
+ CreatedBy int32 `sql:"created_by,type:integer"`
+ UpdatedOn time.Time `sql:"updated_on,type:timestamptz"`
+ UpdatedBy int32 `sql:"updated_by,type:integer"`
+}
+
+func NewDefaultAuditLog(userId int32) AuditLog {
+ return AuditLog{
+ CreatedOn: time.Now(),
+ CreatedBy: userId,
+ UpdatedOn: time.Now(),
+ UpdatedBy: userId,
+ }
+}
+
+// CreateAuditLog can be used by any repository to create AuditLog for insert operation
+func (model *AuditLog) CreateAuditLog(userId int32) {
+ model.CreatedOn = time.Now()
+ model.UpdatedOn = time.Now()
+ model.CreatedBy = userId
+ model.UpdatedBy = userId
+}
+
+// UpdateAuditLog can be used by any repository to update AuditLog for update operation
+func (model *AuditLog) UpdateAuditLog(userId int32) {
+ model.UpdatedOn = time.Now()
+ model.UpdatedBy = userId
+}
diff --git a/chart-sync/vendor/github.com/devtron-labs/common-lib/utils/sql/TransactionWrapper.go b/chart-sync/vendor/github.com/devtron-labs/common-lib/utils/sql/TransactionWrapper.go
new file mode 100644
index 000000000..3c797e1e1
--- /dev/null
+++ b/chart-sync/vendor/github.com/devtron-labs/common-lib/utils/sql/TransactionWrapper.go
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2024. Devtron 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 sql
+
+import "github.com/go-pg/pg"
+
+type TransactionWrapper interface {
+ StartTx() (*pg.Tx, error)
+ RollbackTx(tx *pg.Tx) error
+ CommitTx(tx *pg.Tx) error
+}
+
+type TransactionUtilImpl struct {
+ dbConnection *pg.DB
+}
+
+func NewTransactionUtilImpl(db *pg.DB) *TransactionUtilImpl {
+ return &TransactionUtilImpl{
+ dbConnection: db,
+ }
+}
+func (impl *TransactionUtilImpl) RollbackTx(tx *pg.Tx) error {
+ return tx.Rollback()
+}
+func (impl *TransactionUtilImpl) CommitTx(tx *pg.Tx) error {
+ return tx.Commit()
+}
+func (impl *TransactionUtilImpl) StartTx() (*pg.Tx, error) {
+ return impl.dbConnection.Begin()
+}
diff --git a/chart-sync/vendor/github.com/devtron-labs/common-lib/utils/sql/connection.go b/chart-sync/vendor/github.com/devtron-labs/common-lib/utils/sql/connection.go
new file mode 100644
index 000000000..fa6858e5d
--- /dev/null
+++ b/chart-sync/vendor/github.com/devtron-labs/common-lib/utils/sql/connection.go
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2020-2024. Devtron 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 sql
+
+import (
+ "github.com/devtron-labs/common-lib/utils"
+ "github.com/devtron-labs/common-lib/utils/bean"
+ "go.uber.org/zap"
+ "reflect"
+ "time"
+
+ "github.com/caarlos0/env"
+ "github.com/go-pg/pg"
+)
+
+// CATEGORY=POSTGRES
+type Config struct {
+ Addr string `env:"PG_ADDR" envDefault:"127.0.0.1" description:"address of postgres service" example:"postgresql-postgresql.devtroncd" deprecated:"false"`
+ Port string `env:"PG_PORT" envDefault:"5432" description:"port of postgresql service" example:"5432"`
+ User string `env:"PG_USER" envDefault:"" description:"user for postgres" example:"postgres"`
+ Password string `env:"PG_PASSWORD" envDefault:"" secretData:"-" description:"password for postgres, associated with PG_USER" example:"confidential ;)"`
+ Database string `env:"PG_DATABASE" envDefault:"orchestrator" description:"postgres database to be made connection with" example:"orchestrator, casbin, git_sensor, lens"`
+ CasbinDatabase string `env:"CASBIN_DATABASE" envDefault:"casbin""`
+ ApplicationName string `env:"APP" envDefault:"orchestrator" description:"Application name"`
+ ReadTimeout int64 `env:"PG_READ_TIMEOUT" envDefault:"30"`
+ WriteTimeout int64 `env:"PG_WRITE_TIMEOUT" envDefault:"30"`
+ bean.PgQueryMonitoringConfig
+}
+
+func GetConfig() (*Config, error) {
+ cfg := &Config{}
+ err := env.Parse(cfg)
+ if err != nil {
+ return cfg, err
+ }
+ monitoringCfg, err := bean.GetPgQueryMonitoringConfig(cfg.ApplicationName)
+ if err != nil {
+ return cfg, err
+ }
+ cfg.PgQueryMonitoringConfig = monitoringCfg
+ return cfg, err
+}
+
+func NewDbConnection(cfg *Config, logger *zap.SugaredLogger) (*pg.DB, error) {
+ options := pg.Options{
+ Addr: cfg.Addr + ":" + cfg.Port,
+ User: cfg.User,
+ Password: cfg.Password,
+ Database: cfg.Database,
+ ApplicationName: cfg.ApplicationName,
+ ReadTimeout: time.Duration(cfg.ReadTimeout) * time.Second,
+ WriteTimeout: time.Duration(cfg.WriteTimeout) * time.Second,
+ }
+ dbConnection := pg.Connect(&options)
+ // check db connection
+ var test string
+ _, err := dbConnection.QueryOne(&test, `SELECT 1`)
+
+ if err != nil {
+ logger.Errorw("error in connecting db ", "db", obfuscateSecretTags(cfg), "err", err)
+ return nil, err
+ } else {
+ logger.Infow("connected with db", "db", obfuscateSecretTags(cfg))
+ }
+
+ // --------------
+ dbConnection.OnQueryProcessed(utils.GetPGPostQueryProcessor(cfg.PgQueryMonitoringConfig))
+ return dbConnection, err
+}
+
+func obfuscateSecretTags(cfg interface{}) interface{} {
+
+ cfgDpl := reflect.New(reflect.ValueOf(cfg).Elem().Type()).Interface()
+ cfgDplElm := reflect.ValueOf(cfgDpl).Elem()
+ t := cfgDplElm.Type()
+ for i := 0; i < t.NumField(); i++ {
+ if _, ok := t.Field(i).Tag.Lookup("secretData"); ok {
+ cfgDplElm.Field(i).SetString("********")
+ } else {
+ cfgDplElm.Field(i).Set(reflect.ValueOf(cfg).Elem().Field(i))
+ }
+ }
+ return cfgDpl
+}
+
+/*type DbConnectionHolder struct {
+ connection *pg.DB
+}
+
+func (holder *DbConnectionHolder) CloseConnection() error {
+ return holder.connection.Close()
+}*/
diff --git a/chart-sync/vendor/github.com/devtron-labs/common-lib/utils/sql/wire_sql.go b/chart-sync/vendor/github.com/devtron-labs/common-lib/utils/sql/wire_sql.go
new file mode 100644
index 000000000..32aee8f5b
--- /dev/null
+++ b/chart-sync/vendor/github.com/devtron-labs/common-lib/utils/sql/wire_sql.go
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2024. Devtron 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 sql
+
+import (
+ "github.com/google/wire"
+)
+
+var PgSqlWireSet = wire.NewSet(
+ GetConfig,
+ NewDbConnection,
+)
diff --git a/chart-sync/vendor/modules.txt b/chart-sync/vendor/modules.txt
index a41fd5861..289298626 100644
--- a/chart-sync/vendor/modules.txt
+++ b/chart-sync/vendor/modules.txt
@@ -95,16 +95,18 @@ github.com/containerd/platforms
# github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc
## explicit
github.com/davecgh/go-spew/spew
-# github.com/devtron-labs/common-lib v0.19.1 => github.com/devtron-labs/devtron-services/common-lib v0.0.0-20250901093002-1be330be4db3
+# github.com/devtron-labs/common-lib v0.19.1 => github.com/devtron-labs/devtron-services/common-lib v0.0.0-20251013041509-9d1c5175da2d
## explicit; go 1.24.0
github.com/devtron-labs/common-lib/constants
github.com/devtron-labs/common-lib/fetchAllEnv
github.com/devtron-labs/common-lib/git-manager/util
github.com/devtron-labs/common-lib/helmLib/registry
+github.com/devtron-labs/common-lib/securestore
github.com/devtron-labs/common-lib/utils
github.com/devtron-labs/common-lib/utils/bean
github.com/devtron-labs/common-lib/utils/http
github.com/devtron-labs/common-lib/utils/remoteConnection/bean
+github.com/devtron-labs/common-lib/utils/sql
# github.com/docker/cli v28.1.1+incompatible
## explicit
github.com/docker/cli/cli/config/types
@@ -967,4 +969,4 @@ sigs.k8s.io/structured-merge-diff/v4/value
sigs.k8s.io/yaml
sigs.k8s.io/yaml/goyaml.v2
sigs.k8s.io/yaml/goyaml.v3
-# github.com/devtron-labs/common-lib => github.com/devtron-labs/devtron-services/common-lib v0.0.0-20250901093002-1be330be4db3
+# github.com/devtron-labs/common-lib => github.com/devtron-labs/devtron-services/common-lib v0.0.0-20251013041509-9d1c5175da2d
diff --git a/chart-sync/wire_gen.go b/chart-sync/wire_gen.go
index 874f69de6..0022efdf4 100644
--- a/chart-sync/wire_gen.go
+++ b/chart-sync/wire_gen.go
@@ -1,6 +1,6 @@
// Code generated by Wire. DO NOT EDIT.
-//go:generate go run github.com/google/wire/cmd/wire
+//go:generate go run -mod=mod github.com/google/wire/cmd/wire
//go:build !wireinject
// +build !wireinject
diff --git a/ci-runner/go.mod b/ci-runner/go.mod
index a47038b06..1ba4eb04e 100644
--- a/ci-runner/go.mod
+++ b/ci-runner/go.mod
@@ -4,7 +4,7 @@ go 1.24.0
toolchain go1.24.3
-replace github.com/devtron-labs/common-lib => github.com/devtron-labs/devtron-services/common-lib v0.0.0-20250901093002-1be330be4db3
+replace github.com/devtron-labs/common-lib => github.com/devtron-labs/devtron-services/common-lib v0.0.0-20251013041509-9d1c5175da2d
require (
github.com/Knetic/govaluate v3.0.0+incompatible
diff --git a/ci-runner/go.sum b/ci-runner/go.sum
index 989602349..6c6eaf1eb 100644
--- a/ci-runner/go.sum
+++ b/ci-runner/go.sum
@@ -114,8 +114,8 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
-github.com/devtron-labs/devtron-services/common-lib v0.0.0-20250901093002-1be330be4db3 h1:jCxpB8+6KD29jenB4SLTimCYzsmazBAPKv6637xRT5M=
-github.com/devtron-labs/devtron-services/common-lib v0.0.0-20250901093002-1be330be4db3/go.mod h1:/Ciy9tD9OxZOWBDPIasM448H7uvSo4+ZJiExpfwBZpA=
+github.com/devtron-labs/devtron-services/common-lib v0.0.0-20251013041509-9d1c5175da2d h1:EAGZ+sei6Hl98Hp09HgNcnOIWgI43jcx1q0Mb6V5HdQ=
+github.com/devtron-labs/devtron-services/common-lib v0.0.0-20251013041509-9d1c5175da2d/go.mod h1:/Ciy9tD9OxZOWBDPIasM448H7uvSo4+ZJiExpfwBZpA=
github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk=
github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E=
github.com/docker/cli v28.1.1+incompatible h1:eyUemzeI45DY7eDPuwUcmDyDj1pM98oD5MdSpiItp8k=
diff --git a/ci-runner/vendor/modules.txt b/ci-runner/vendor/modules.txt
index adcc96a6d..81b865a92 100644
--- a/ci-runner/vendor/modules.txt
+++ b/ci-runner/vendor/modules.txt
@@ -298,7 +298,7 @@ github.com/cncf/xds/go/xds/type/v3
# github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc
## explicit
github.com/davecgh/go-spew/spew
-# github.com/devtron-labs/common-lib v0.19.1 => github.com/devtron-labs/devtron-services/common-lib v0.0.0-20250901093002-1be330be4db3
+# github.com/devtron-labs/common-lib v0.19.1 => github.com/devtron-labs/devtron-services/common-lib v0.0.0-20251013041509-9d1c5175da2d
## explicit; go 1.24.0
github.com/devtron-labs/common-lib/blob-storage
github.com/devtron-labs/common-lib/constants
@@ -1198,4 +1198,4 @@ sigs.k8s.io/structured-merge-diff/v4/value
## explicit; go 1.12
sigs.k8s.io/yaml
sigs.k8s.io/yaml/goyaml.v2
-# github.com/devtron-labs/common-lib => github.com/devtron-labs/devtron-services/common-lib v0.0.0-20250901093002-1be330be4db3
+# github.com/devtron-labs/common-lib => github.com/devtron-labs/devtron-services/common-lib v0.0.0-20251013041509-9d1c5175da2d
diff --git a/common-lib/securestore/AttributesRepoDBConnection.go b/common-lib/securestore/AttributesRepoDBConnection.go
new file mode 100644
index 000000000..907d202bd
--- /dev/null
+++ b/common-lib/securestore/AttributesRepoDBConnection.go
@@ -0,0 +1,75 @@
+package securestore
+
+import (
+ "github.com/caarlos0/env"
+ "github.com/devtron-labs/common-lib/utils"
+ "github.com/devtron-labs/common-lib/utils/bean"
+ "github.com/go-pg/pg"
+ "log"
+)
+
+func NewAttributesRepositoryImplForDatabase(databaseName string) (*AttributesRepositoryImpl, error) {
+ dbConn, err := newDbConnection(databaseName)
+ if err != nil {
+ return nil, err
+ }
+ return NewAttributesRepositoryImpl(dbConn), nil
+}
+
+type config struct {
+ Addr string `env:"PG_ADDR" envDefault:"127.0.0.1"`
+ Port string `env:"PG_PORT" envDefault:"5432"`
+ User string `env:"PG_USER" envDefault:""`
+ Password string `env:"PG_PASSWORD" envDefault:"" secretData:"-"`
+ Database string `env:"PG_DATABASE" envDefault:"orchestrator"`
+ ApplicationName string `env:"APP" envDefault:"orchestrator"`
+ bean.PgQueryMonitoringConfig
+ LocalDev bool `env:"RUNTIME_CONFIG_LOCAL_DEV" envDefault:"false"`
+}
+
+func getDbConfig(databaseName string) (*config, error) {
+ cfg := &config{}
+ err := env.Parse(cfg)
+ if err != nil {
+ return cfg, err
+ }
+ monitoringCfg, err := bean.GetPgQueryMonitoringConfig(cfg.ApplicationName)
+ if err != nil {
+ return cfg, err
+ }
+ cfg.PgQueryMonitoringConfig = monitoringCfg
+ if !cfg.LocalDev {
+ cfg.Database = databaseName //overriding database
+ }
+ return cfg, err
+}
+
+func newDbConnection(databaseName string) (*pg.DB, error) {
+ cfg, err := getDbConfig(databaseName)
+ if err != nil {
+ return nil, err
+ }
+ options := pg.Options{
+ Addr: cfg.Addr + ":" + cfg.Port,
+ User: cfg.User,
+ Password: cfg.Password,
+ Database: cfg.Database,
+ ApplicationName: cfg.ApplicationName,
+ }
+ dbConnection := pg.Connect(&options)
+ //check db connection
+ var test string
+ _, err = dbConnection.QueryOne(&test, `SELECT 1`)
+
+ if err != nil {
+ log.Println("error in connecting orchestrator db ", "err", err)
+ return nil, err
+ } else {
+ log.Println("connected with orchestrator db")
+ }
+ //--------------
+ if cfg.LogSlowQuery {
+ dbConnection.OnQueryProcessed(utils.GetPGPostQueryProcessor(cfg.PgQueryMonitoringConfig))
+ }
+ return dbConnection, err
+}
diff --git a/common-lib/securestore/AttributesRepository.go b/common-lib/securestore/AttributesRepository.go
new file mode 100644
index 000000000..eadf7a8f4
--- /dev/null
+++ b/common-lib/securestore/AttributesRepository.go
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 2020-2024. Devtron Inc.
+ */
+
+package securestore
+
+import (
+ sql2 "github.com/devtron-labs/common-lib/utils/sql"
+ "github.com/go-pg/pg"
+ "time"
+)
+
+const ENCRYPTION_KEY string = "encryptionKey" // AES-256 encryption key for sensitive data
+
+type Attributes struct {
+ tableName struct{} `sql:"attributes" pg:",discard_unknown_columns"`
+ Id int `sql:"id,pk"`
+ Key string `sql:"key,notnull"`
+ Value string `sql:"value,notnull"`
+ Active bool `sql:"active, notnull"`
+ sql2.AuditLog
+}
+
+type AttributesRepository interface {
+ Save(model *Attributes, tx *pg.Tx) (*Attributes, error)
+ Update(model *Attributes, tx *pg.Tx) error
+ FindByKey(key string) (*Attributes, error)
+ GetConnection() (dbConnection *pg.DB)
+ SaveEncryptionKeyIfNotExists(value string) error
+ GetEncryptionKey() (string, error)
+}
+
+type AttributesRepositoryImpl struct {
+ dbConnection *pg.DB
+}
+
+func NewAttributesRepositoryImpl(dbConnection *pg.DB) *AttributesRepositoryImpl {
+ return &AttributesRepositoryImpl{dbConnection: dbConnection}
+}
+
+func (impl *AttributesRepositoryImpl) GetConnection() (dbConnection *pg.DB) {
+ return impl.dbConnection
+}
+
+func (repo AttributesRepositoryImpl) Save(model *Attributes, tx *pg.Tx) (*Attributes, error) {
+ err := tx.Insert(model)
+ if err != nil {
+ return model, err
+ }
+ return model, nil
+}
+
+func (repo AttributesRepositoryImpl) Update(model *Attributes, tx *pg.Tx) error {
+ err := tx.Update(model)
+ if err != nil {
+ return err
+ }
+ return nil
+}
+
+func (repo AttributesRepositoryImpl) FindByKey(key string) (*Attributes, error) {
+ model := &Attributes{}
+ err := repo.dbConnection.
+ Model(model).
+ Where("key = ?", key).
+ Where("active = ?", true).
+ Select()
+ if err != nil {
+ return model, err
+ }
+ return model, nil
+}
+
+// SaveEncryptionKeyIfNotExists saves an encryption key in the attributes table if not exists
+func (repo AttributesRepositoryImpl) SaveEncryptionKeyIfNotExists(value string) error {
+ dbConnection := repo.GetConnection()
+ tx, err := dbConnection.Begin()
+ if err != nil {
+ return err
+ }
+ defer tx.Rollback()
+
+ //deleting all keys if exists for safe side
+ _, err = tx.Model(&Attributes{}).Where("key = ?", ENCRYPTION_KEY).Delete()
+ // Create new encryption key entry
+ model := &Attributes{
+ Key: ENCRYPTION_KEY,
+ Value: value,
+ Active: true,
+ AuditLog: sql2.AuditLog{
+ CreatedBy: 1,
+ UpdatedBy: 1,
+ CreatedOn: time.Now(),
+ UpdatedOn: time.Now(),
+ },
+ }
+ _, err = repo.Save(model, tx)
+ if err != nil {
+ return err
+ }
+ return tx.Commit()
+}
+
+// GetEncryptionKey retrieves the active encryption key from the attributes table
+func (repo AttributesRepositoryImpl) GetEncryptionKey() (string, error) {
+ model, err := repo.FindByKey(ENCRYPTION_KEY)
+ if err != nil {
+ return "", err
+ }
+ return model.Value, nil
+}
diff --git a/common-lib/securestore/EncryptionKeyService.go b/common-lib/securestore/EncryptionKeyService.go
new file mode 100644
index 000000000..f8a37acec
--- /dev/null
+++ b/common-lib/securestore/EncryptionKeyService.go
@@ -0,0 +1,136 @@
+/*
+ * Copyright (c) 2024. Devtron Inc.
+ */
+
+package securestore
+
+import (
+ "crypto/rand"
+ "encoding/hex"
+ "fmt"
+ "github.com/go-pg/pg"
+ log "github.com/sirupsen/logrus"
+)
+
+func SetEncryptionKey() error {
+ repo, err := NewAttributesRepositoryImplForDatabase("orchestrator") //hardcoded for orchestrator as need to pick a common key for every service
+ if err != nil {
+ log.Println("error in creating attributes repository", "err", err)
+ return err
+ }
+ encryptionService := NewEncryptionKeyServiceImpl(repo)
+ err = encryptionService.CreateAndStoreEncryptionKey()
+ if err != nil {
+ log.Println("error in creating and storing encryption key", "err", err)
+ return err
+ }
+ return nil
+}
+
+type EncryptionKeyService interface {
+ // CreateAndStoreEncryptionKey generates a new AES-256 encryption key and stores it in the attributes repository
+ CreateAndStoreEncryptionKey() error
+
+ // RotateEncryptionKey generates a new encryption key and stores it (deactivating the old one)
+ RotateEncryptionKey(userId int32) (string, error)
+
+ // GenerateEncryptionKey generates a new AES-256 encryption key (32 bytes)
+ GenerateEncryptionKey() (string, error)
+
+ GetEncryptionKey() (string, error)
+}
+
+type EncryptionKeyServiceImpl struct {
+ attributesRepository AttributesRepository
+}
+
+func NewEncryptionKeyServiceImpl(attributesRepository AttributesRepository) *EncryptionKeyServiceImpl {
+ impl := &EncryptionKeyServiceImpl{
+ attributesRepository: attributesRepository,
+ }
+ return impl
+}
+
+// GenerateEncryptionKey generates a new AES-256 encryption key (32 bytes = 256 bits)
+func (impl *EncryptionKeyServiceImpl) GenerateEncryptionKey() (string, error) {
+ // Generate 32 random bytes for AES-256
+ key := make([]byte, 32)
+ _, err := rand.Read(key)
+ if err != nil {
+ log.Error("error generating random encryption key", "err", err)
+ return "", fmt.Errorf("failed to generate encryption key: %w", err)
+ }
+ // Encode to hex string for storage
+ keyHex := hex.EncodeToString(key)
+ return keyHex, nil
+}
+
+// CreateAndStoreEncryptionKey generates a new AES-256 encryption key and stores it in the attributes repository
+func (impl *EncryptionKeyServiceImpl) CreateAndStoreEncryptionKey() error {
+ // Check if encryption key already exists
+ encryptionKeyModel, err := impl.attributesRepository.FindByKey(ENCRYPTION_KEY)
+ if err != nil && err != pg.ErrNoRows {
+ log.Error("error checking for existing encryption key", "err", err)
+ return err
+ }
+ var encryptionKeyEncoded string
+ if encryptionKeyModel != nil && encryptionKeyModel.Id > 0 && len(encryptionKeyModel.Value) > 0 {
+ encryptionKeyEncoded = encryptionKeyModel.Value
+ log.Println("encryption key already exists", "keyId", encryptionKeyModel.Id)
+ } else {
+ // Generate new encryption key
+ encryptionKeyNew, err := impl.GenerateEncryptionKey()
+ if err != nil {
+ return err
+ }
+ // Store in repository
+ err = impl.attributesRepository.SaveEncryptionKeyIfNotExists(encryptionKeyNew)
+ if err != nil {
+ log.Error("error storing encryption key", "err", err)
+ return fmt.Errorf("failed to store encryption key: %w", err)
+ }
+ encryptionKeyEncoded = encryptionKeyNew
+ log.Println("Successfully created and stored encryption key")
+ }
+
+ encryptionKey, err = hex.DecodeString(encryptionKeyEncoded)
+ if err != nil || len(encryptionKey) != 32 {
+ return fmt.Errorf("encryptionKey is incorrect : %v", err)
+ }
+ return nil
+}
+
+// RotateEncryptionKey generates a new encryption key and stores it (deactivating the old one)
+func (impl *EncryptionKeyServiceImpl) RotateEncryptionKey(userId int32) (string, error) {
+ log.Println("Rotating encryption key", "userId", userId)
+
+ // Generate new encryption key
+ newEncryptionKey, err := impl.GenerateEncryptionKey()
+ if err != nil {
+ return "", err
+ }
+
+ // Store in repository (this will deactivate the old key)
+ err = impl.attributesRepository.SaveEncryptionKeyIfNotExists(newEncryptionKey)
+ if err != nil {
+ log.Error("error rotating encryption key", "err", err)
+ return "", fmt.Errorf("failed to rotate encryption key: %w", err)
+ }
+ //TODO: also need to rotate encryption's already done
+ log.Println("Successfully rotated encryption key", "userId", userId)
+ return newEncryptionKey, nil
+}
+
+// GetEncryptionKey retrieves the active encryption key from the repository
+func (impl *EncryptionKeyServiceImpl) GetEncryptionKey() (string, error) {
+ key, err := impl.attributesRepository.GetEncryptionKey()
+ if err != nil {
+ if err == pg.ErrNoRows {
+ log.Error("encryption key not found in repository")
+ return "", fmt.Errorf("encryption key not found, please create one first")
+ }
+ log.Error("error retrieving encryption key", "err", err)
+ return "", err
+ }
+ return key, nil
+}
diff --git a/common-lib/securestore/common.go b/common-lib/securestore/common.go
new file mode 100644
index 000000000..4444765e3
--- /dev/null
+++ b/common-lib/securestore/common.go
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2024. Devtron Inc.
+ */
+
+package securestore
+
+import (
+ "crypto/aes"
+ "crypto/cipher"
+ "crypto/rand"
+ "encoding/base64"
+ "encoding/json"
+ "errors"
+ "fmt"
+ "github.com/go-pg/pg/types"
+ "io"
+)
+
+var decryptionFailErr = fmt.Errorf("Decryption failed")
+
+func DidDecryptionFail(err error) bool {
+ return errors.Is(err, decryptionFailErr)
+}
+
+var encryptionKey []byte
+
+func encrypt(data []byte) (string, error) {
+ if len(data) == 0 {
+ return "", nil
+ }
+ block, err := aes.NewCipher(encryptionKey)
+ if err != nil {
+ return "", err
+ }
+ aesGCM, err := cipher.NewGCM(block)
+ if err != nil {
+ return "", err
+ }
+ nonce := make([]byte, aesGCM.NonceSize())
+ if _, err := io.ReadFull(rand.Reader, nonce); err != nil {
+ return "", err
+ }
+ ciphertext := aesGCM.Seal(nonce, nonce, data, nil)
+ return base64.StdEncoding.EncodeToString(ciphertext), nil
+}
+
+func decrypt(cipherBase64 string) (string, error) {
+ // Try decrypting (normal encrypted flow)
+ cipherData, err := base64.StdEncoding.DecodeString(cipherBase64)
+ if err == nil {
+ block, err := aes.NewCipher(encryptionKey)
+ if err != nil {
+ return "", err
+ }
+ aesGCM, err := cipher.NewGCM(block)
+ if err != nil {
+ return "", err
+ }
+ nonceSize := aesGCM.NonceSize()
+ if len(cipherData) >= nonceSize {
+ nonce, ciphertext := cipherData[:nonceSize], cipherData[nonceSize:]
+ plainText, err := aesGCM.Open(nil, nonce, ciphertext, nil)
+ if err == nil {
+ return string(plainText), nil // Successfully decrypted
+ }
+ }
+ }
+ return cipherBase64, decryptionFailErr
+}
+
+// AppendValue : can be used for auto encryption of fields but is only supported in go-pg/v10. Not being used anywhere as of now, to be tested when start using.
+func (e EncryptedMap) AppendValue(b []byte, quote int) ([]byte, error) {
+ jsonBytes, err := json.Marshal(e)
+ if err != nil {
+ return nil, err
+ }
+
+ encryptedString, err := encrypt(jsonBytes)
+ if err != nil {
+ return nil, err
+ }
+
+ return types.AppendString(b, encryptedString, quote), nil
+}
diff --git a/common-lib/securestore/map.go b/common-lib/securestore/map.go
new file mode 100644
index 000000000..dd9c25846
--- /dev/null
+++ b/common-lib/securestore/map.go
@@ -0,0 +1,73 @@
+package securestore
+
+import (
+ "encoding/json"
+ "fmt"
+)
+
+type EncryptedMap map[string]string
+
+const (
+ ENCRYPTED_KEY = "encrypted_data"
+)
+
+func EncryptMap(m EncryptedMap) (map[string]string, error) {
+ bytesM, err := json.Marshal(m)
+ if err != nil {
+ return nil, err
+ }
+ encryptedData, err := encrypt(bytesM)
+ if err != nil {
+ return nil, err
+ }
+ return EncryptedMap{ENCRYPTED_KEY: encryptedData}, nil
+}
+
+func decryptMap(mCipher []byte) (map[string]string, error) {
+ var m map[string]string
+ err := json.Unmarshal(mCipher, &m)
+ if err != nil {
+ return nil, err
+ }
+ if len(m[ENCRYPTED_KEY]) > 0 {
+ decryptedMapBytes, err := decrypt(m[ENCRYPTED_KEY])
+ if err != nil && !DidDecryptionFail(err) {
+ return nil, err
+ }
+ if err == nil {
+ var decryptedMap map[string]string
+ err = json.Unmarshal([]byte(decryptedMapBytes), &decryptedMap)
+ if err != nil {
+ return nil, err
+ }
+ return decryptedMap, nil
+ }
+ } else {
+ // Fallback: maybe it's just raw JSON
+ // Validate that it's a valid JSON map[string]string
+ // Neither decrypted nor valid plaintext JSON
+ return m, nil
+ }
+ return nil, fmt.Errorf("decryption failed and data is not valid plaintext JSON")
+}
+
+func (e *EncryptedMap) Scan(value interface{}) error {
+ if value == nil {
+ return nil
+ }
+ var encrypted []byte
+ switch v := value.(type) {
+ case string:
+ encrypted = []byte(v)
+ case []byte:
+ encrypted = v
+ default:
+ return fmt.Errorf("unsupported type: %T", v)
+ }
+ var err error
+ *e, err = decryptMap(encrypted)
+ if err != nil {
+ return err
+ }
+ return nil
+}
diff --git a/common-lib/securestore/strings.go b/common-lib/securestore/strings.go
new file mode 100644
index 000000000..e7c5128b2
--- /dev/null
+++ b/common-lib/securestore/strings.go
@@ -0,0 +1,60 @@
+package securestore
+
+import (
+ "fmt"
+)
+
+type EncryptedString string
+
+func (e *EncryptedString) String() string {
+ return string(*e)
+}
+
+func ToEncryptedString(s string) EncryptedString {
+ return EncryptedString(s)
+}
+
+func EncryptString(data string) (EncryptedString, error) {
+ encryptedStr, err := encrypt([]byte(data))
+ if err != nil {
+ return "", err
+ }
+ return EncryptedString(encryptedStr), nil
+}
+
+func decryptString(cipherBase64 string) (string, error) {
+ decryptedBytes, err := decrypt(cipherBase64)
+ if err != nil && !DidDecryptionFail(err) {
+ return "", err
+ }
+ // Fallback: decrypting failed, considering it as just normal string
+ if DidDecryptionFail(err) {
+ return cipherBase64, nil
+ } else {
+ return decryptedBytes, nil
+ }
+}
+
+func (e *EncryptedString) Scan(value interface{}) error {
+ if value == nil {
+ return nil
+ }
+ var encrypted []byte
+ switch v := value.(type) {
+ case string:
+ encrypted = []byte(v)
+ case []byte:
+ encrypted = v
+ default:
+ return fmt.Errorf("unsupported type: %T", v)
+ }
+ decryptedBytes, err := decryptString(string(encrypted))
+ if err != nil {
+ return err
+ }
+ if decryptedBytes == "" {
+ return nil
+ }
+ *e = EncryptedString(decryptedBytes)
+ return nil
+}
diff --git a/git-sensor/api/GrpcHandler.go b/git-sensor/api/GrpcHandler.go
index 454714331..1a6e249b8 100644
--- a/git-sensor/api/GrpcHandler.go
+++ b/git-sensor/api/GrpcHandler.go
@@ -18,6 +18,7 @@ package api
import (
"context"
+ "github.com/devtron-labs/common-lib/securestore"
"github.com/devtron-labs/git-sensor/internals/sql"
"github.com/devtron-labs/git-sensor/pkg"
"github.com/devtron-labs/git-sensor/pkg/git"
@@ -77,9 +78,9 @@ func (impl *GrpcHandlerImpl) SaveGitProvider(ctx context.Context, req *pb.GitPro
Name: req.Name,
Url: req.Url,
UserName: req.UserName,
- Password: req.Password,
- AccessToken: req.AccessToken,
- SshPrivateKey: req.SshPrivateKey,
+ Password: securestore.ToEncryptedString(req.Password),
+ AccessToken: securestore.ToEncryptedString(req.AccessToken),
+ SshPrivateKey: securestore.ToEncryptedString(req.SshPrivateKey),
AuthMode: sql.AuthMode(req.AuthMode),
Active: req.Active,
CaCert: req.CaCert,
diff --git a/git-sensor/app/App.go b/git-sensor/app/App.go
index 636a224e9..94146279f 100644
--- a/git-sensor/app/App.go
+++ b/git-sensor/app/App.go
@@ -24,6 +24,7 @@ import (
constants "github.com/devtron-labs/common-lib/constants"
pubsub "github.com/devtron-labs/common-lib/pubsub-lib"
"github.com/devtron-labs/common-lib/pubsub-lib/metrics"
+ "github.com/devtron-labs/common-lib/securestore"
"github.com/devtron-labs/git-sensor/api"
"github.com/devtron-labs/git-sensor/bean"
"github.com/devtron-labs/git-sensor/internals/middleware"
@@ -59,6 +60,10 @@ type App struct {
}
func NewApp(MuxRouter *api.MuxRouter, Logger *zap.SugaredLogger, impl *git.GitWatcherImpl, db *pg.DB, pubSubClient *pubsub.PubSubClientServiceImpl, GrpcControllerImpl *api.GrpcHandlerImpl) *App {
+ err := securestore.SetEncryptionKey()
+ if err != nil {
+ Logger.Errorw("error in setting encryption key", "err", err)
+ }
return &App{
MuxRouter: MuxRouter,
Logger: Logger,
diff --git a/git-sensor/env_gen.json b/git-sensor/env_gen.json
index 2a7cbdb4f..95f60cc11 100644
--- a/git-sensor/env_gen.json
+++ b/git-sensor/env_gen.json
@@ -1 +1 @@
-[{"Category":"DEVTRON","Fields":[{"Env":"ANALYTICS_DEBUG","EnvType":"bool","EnvValue":"false","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"APP","EnvType":"string","EnvValue":"git-sensor","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"CLI_CMD_TIMEOUT_GLOBAL_SECONDS","EnvType":"int","EnvValue":"900","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"CLI_CMD_TIMEOUT_JSON","EnvType":"string","EnvValue":"","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"COMMIT_STATS_TIMEOUT_IN_SEC","EnvType":"int","EnvValue":"2","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"CONSUMER_CONFIG_JSON","EnvType":"string","EnvValue":"","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"DEFAULT_LOG_TIME_LIMIT","EnvType":"int64","EnvValue":"1","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"ENABLE_FILE_STATS","EnvType":"bool","EnvValue":"false","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"ENABLE_STATSVIZ","EnvType":"bool","EnvValue":"false","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"GIT_HISTORY_COUNT","EnvType":"int","EnvValue":"15","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"GOGIT_TIMEOUT_SECONDS","EnvType":"int","EnvValue":"10","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"LOG_LEVEL","EnvType":"int","EnvValue":"0","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"MIN_LIMIT_FOR_PVC","EnvType":"int","EnvValue":"1","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"NATS_MSG_ACK_WAIT_IN_SECS","EnvType":"int","EnvValue":"120","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"NATS_MSG_BUFFER_SIZE","EnvType":"int","EnvValue":"-1","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"NATS_MSG_MAX_AGE","EnvType":"int","EnvValue":"86400","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"NATS_MSG_PROCESSING_BATCH_SIZE","EnvType":"int","EnvValue":"1","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"NATS_MSG_REPLICAS","EnvType":"int","EnvValue":"0","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"NATS_SERVER_HOST","EnvType":"string","EnvValue":"nats://devtron-nats.devtroncd:4222","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"PG_ADDR","EnvType":"string","EnvValue":"127.0.0.1","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"PG_DATABASE","EnvType":"string","EnvValue":"git_sensor","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"PG_EXPORT_PROM_METRICS","EnvType":"bool","EnvValue":"true","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"PG_LOG_ALL_FAILURE_QUERIES","EnvType":"bool","EnvValue":"true","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"PG_LOG_ALL_QUERY","EnvType":"bool","EnvValue":"false","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"PG_LOG_SLOW_QUERY","EnvType":"bool","EnvValue":"true","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"PG_PASSWORD","EnvType":"string","EnvValue":"","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"PG_PORT","EnvType":"string","EnvValue":"5432","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"PG_QUERY_DUR_THRESHOLD","EnvType":"int64","EnvValue":"5000","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"PG_USER","EnvType":"string","EnvValue":"","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"POLL_DURATION","EnvType":"int","EnvValue":"2","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"POLL_WORKER","EnvType":"int","EnvValue":"5","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"SERVER_GRPC_PORT","EnvType":"int","EnvValue":"8081","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"SERVER_REST_PORT","EnvType":"int","EnvValue":"8080","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"STREAM_CONFIG_JSON","EnvType":"string","EnvValue":"","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"USE_GIT_CLI","EnvType":"bool","EnvValue":"false","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"USE_GIT_CLI_ANALYTICS","EnvType":"bool","EnvValue":"false","EnvDescription":"","Example":"","Deprecated":"false"}]}]
\ No newline at end of file
+[{"Category":"DEVTRON","Fields":[{"Env":"ANALYTICS_DEBUG","EnvType":"bool","EnvValue":"false","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"APP","EnvType":"string","EnvValue":"git-sensor","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"CLI_CMD_TIMEOUT_GLOBAL_SECONDS","EnvType":"int","EnvValue":"900","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"CLI_CMD_TIMEOUT_JSON","EnvType":"string","EnvValue":"","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"COMMIT_STATS_TIMEOUT_IN_SEC","EnvType":"int","EnvValue":"2","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"CONSUMER_CONFIG_JSON","EnvType":"string","EnvValue":"","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"DEFAULT_LOG_TIME_LIMIT","EnvType":"int64","EnvValue":"1","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"ENABLE_FILE_STATS","EnvType":"bool","EnvValue":"false","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"ENABLE_STATSVIZ","EnvType":"bool","EnvValue":"false","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"GIT_HISTORY_COUNT","EnvType":"int","EnvValue":"15","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"GOGIT_TIMEOUT_SECONDS","EnvType":"int","EnvValue":"10","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"LOG_LEVEL","EnvType":"int","EnvValue":"0","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"MIN_LIMIT_FOR_PVC","EnvType":"int","EnvValue":"1","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"NATS_MSG_ACK_WAIT_IN_SECS","EnvType":"int","EnvValue":"120","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"NATS_MSG_BUFFER_SIZE","EnvType":"int","EnvValue":"-1","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"NATS_MSG_MAX_AGE","EnvType":"int","EnvValue":"86400","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"NATS_MSG_PROCESSING_BATCH_SIZE","EnvType":"int","EnvValue":"1","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"NATS_MSG_REPLICAS","EnvType":"int","EnvValue":"0","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"NATS_SERVER_HOST","EnvType":"string","EnvValue":"nats://devtron-nats.devtroncd:4222","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"PG_ADDR","EnvType":"string","EnvValue":"127.0.0.1","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"PG_DATABASE","EnvType":"string","EnvValue":"git_sensor","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"PG_EXPORT_PROM_METRICS","EnvType":"bool","EnvValue":"true","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"PG_LOG_ALL_FAILURE_QUERIES","EnvType":"bool","EnvValue":"true","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"PG_LOG_ALL_QUERY","EnvType":"bool","EnvValue":"false","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"PG_LOG_SLOW_QUERY","EnvType":"bool","EnvValue":"true","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"PG_PASSWORD","EnvType":"string","EnvValue":"","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"PG_PORT","EnvType":"string","EnvValue":"5432","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"PG_QUERY_DUR_THRESHOLD","EnvType":"int64","EnvValue":"5000","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"PG_USER","EnvType":"string","EnvValue":"","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"POLL_DURATION","EnvType":"int","EnvValue":"2","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"POLL_WORKER","EnvType":"int","EnvValue":"5","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"SERVER_GRPC_PORT","EnvType":"int","EnvValue":"8081","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"SERVER_REST_PORT","EnvType":"int","EnvValue":"8080","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"STREAM_CONFIG_JSON","EnvType":"string","EnvValue":"","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"USE_GIT_CLI","EnvType":"bool","EnvValue":"false","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"USE_GIT_CLI_ANALYTICS","EnvType":"bool","EnvValue":"false","EnvDescription":"","Example":"","Deprecated":"false"}]},{"Category":"POSTGRES","Fields":[{"Env":"CASBIN_DATABASE","EnvType":"string","EnvValue":"casbin","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"PG_READ_TIMEOUT","EnvType":"int64","EnvValue":"30","EnvDescription":"","Example":"","Deprecated":"false"},{"Env":"PG_WRITE_TIMEOUT","EnvType":"int64","EnvValue":"30","EnvDescription":"","Example":"","Deprecated":"false"}]}]
\ No newline at end of file
diff --git a/git-sensor/env_gen.md b/git-sensor/env_gen.md
index b43f8137d..61987d549 100644
--- a/git-sensor/env_gen.md
+++ b/git-sensor/env_gen.md
@@ -40,3 +40,11 @@
| USE_GIT_CLI | bool |false | | | false |
| USE_GIT_CLI_ANALYTICS | bool |false | | | false |
+
+## POSTGRES Related Environment Variables
+| Key | Type | Default Value | Description | Example | Deprecated |
+|-------|----------|-------------------|-------------------|-----------------------|------------------|
+ | CASBIN_DATABASE | string |casbin | | | false |
+ | PG_READ_TIMEOUT | int64 |30 | | | false |
+ | PG_WRITE_TIMEOUT | int64 |30 | | | false |
+
diff --git a/git-sensor/go.mod b/git-sensor/go.mod
index d77b1cbc7..1e66f54e8 100644
--- a/git-sensor/go.mod
+++ b/git-sensor/go.mod
@@ -4,26 +4,26 @@ go 1.24.0
toolchain go1.24.3
-replace github.com/devtron-labs/common-lib => github.com/devtron-labs/devtron-services/common-lib v0.0.0-20250901093002-1be330be4db3
+replace github.com/devtron-labs/common-lib => github.com/devtron-labs/devtron-services/common-lib v0.0.0-20251013041509-9d1c5175da2d
require (
github.com/caarlos0/env v3.5.0+incompatible
- github.com/devtron-labs/common-lib v0.19.1
+ github.com/devtron-labs/common-lib v0.0.0
github.com/devtron-labs/protos v0.0.3-0.20250323220609-ecf8a0f7305e
github.com/gammazero/workerpool v1.1.3
- github.com/go-git/go-git/v5 v5.16.0
+ github.com/go-git/go-git/v5 v5.13.2
github.com/go-pg/pg v6.15.1+incompatible
github.com/google/uuid v1.6.0
github.com/google/wire v0.6.0
- github.com/gorilla/handlers v1.5.2
+ github.com/gorilla/handlers v1.4.2
github.com/gorilla/mux v1.8.1
github.com/gorilla/schema v1.4.1
- github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.3.2
+ github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.0.1
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0
github.com/prometheus/client_golang v1.22.0
github.com/robfig/cron/v3 v3.0.1
github.com/stretchr/testify v1.10.0
- github.com/tidwall/gjson v1.18.0
+ github.com/tidwall/gjson v1.9.3
go.uber.org/zap v1.27.0
golang.org/x/sys v0.33.0
google.golang.org/grpc v1.72.2
@@ -32,22 +32,21 @@ require (
)
require (
- dario.cat/mergo v1.0.2 // indirect
+ dario.cat/mergo v1.0.0 // indirect
github.com/Microsoft/go-winio v0.6.2 // indirect
- github.com/ProtonMail/go-crypto v1.3.0 // indirect
+ github.com/ProtonMail/go-crypto v1.1.5 // indirect
github.com/arl/statsviz v0.6.0 // indirect
github.com/beorn7/perks v1.0.1 // indirect
github.com/cespare/xxhash/v2 v2.3.0 // indirect
- github.com/cloudflare/circl v1.6.1 // indirect
- github.com/cyphar/filepath-securejoin v0.4.1 // indirect
+ github.com/cloudflare/circl v1.3.7 // indirect
+ github.com/cyphar/filepath-securejoin v0.3.6 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/docker/cli v28.1.1+incompatible // indirect
github.com/emirpasic/gods v1.18.1 // indirect
- github.com/felixge/httpsnoop v1.0.4 // indirect
github.com/gammazero/deque v1.0.0 // indirect
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect
github.com/go-git/go-billy/v5 v5.6.2 // indirect
- github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 // indirect
+ github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/golang/protobuf v1.5.4 // indirect
github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674 // indirect
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect
@@ -66,10 +65,10 @@ require (
github.com/prometheus/procfs v0.16.1 // indirect
github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 // indirect
github.com/sirupsen/logrus v1.9.3 // indirect
- github.com/skeema/knownhosts v1.3.1 // indirect
+ github.com/skeema/knownhosts v1.3.0 // indirect
github.com/stretchr/objx v0.5.2 // indirect
github.com/tidwall/match v1.1.1 // indirect
- github.com/tidwall/pretty v1.2.1 // indirect
+ github.com/tidwall/pretty v1.2.0 // indirect
github.com/xanzy/ssh-agent v0.3.3 // indirect
go.uber.org/multierr v1.11.0 // indirect
golang.org/x/crypto v0.38.0 // indirect
diff --git a/git-sensor/go.sum b/git-sensor/go.sum
index 163eedaf1..6d1cc2c47 100644
--- a/git-sensor/go.sum
+++ b/git-sensor/go.sum
@@ -1,10 +1,10 @@
-dario.cat/mergo v1.0.2 h1:85+piFYR1tMbRrLcDwR18y4UKJ3aH1Tbzi24VRW1TK8=
-dario.cat/mergo v1.0.2/go.mod h1:E/hbnu0NxMFBjpMIE34DRGLWqDy0g5FuKDhCb31ngxA=
+dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk=
+dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk=
github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY=
github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY=
github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU=
-github.com/ProtonMail/go-crypto v1.3.0 h1:ILq8+Sf5If5DCpHQp4PbZdS1J7HDFRXz/+xKBiRGFrw=
-github.com/ProtonMail/go-crypto v1.3.0/go.mod h1:9whxjD8Rbs29b4XWbB8irEcE8KHMqaR2e7GWU1R+/PE=
+github.com/ProtonMail/go-crypto v1.1.5 h1:eoAQfK2dwL+tFSFpr7TbOaPNUbPiJj4fLYwwGE1FQO4=
+github.com/ProtonMail/go-crypto v1.1.5/go.mod h1:rA3QumHc/FZ8pAHreoekgiAbzpNsfQAosU5td4SnOrE=
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFIImctFaOjnTIavg87rW78vTPkQqLI8=
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4=
github.com/arl/statsviz v0.6.0 h1:jbW1QJkEYQkufd//4NDYRSNBpwJNrdzPahF7ZmoGdyE=
@@ -17,27 +17,25 @@ github.com/caarlos0/env v3.5.0+incompatible h1:Yy0UN8o9Wtr/jGHZDpCBLpNrzcFLLM2yi
github.com/caarlos0/env v3.5.0+incompatible/go.mod h1:tdCsowwCzMLdkqRYDlHpZCp2UooDD3MspDBjZ2AD02Y=
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
-github.com/cloudflare/circl v1.6.1 h1:zqIqSPIndyBh1bjLVVDHMPpVKqp8Su/V+6MeDzzQBQ0=
-github.com/cloudflare/circl v1.6.1/go.mod h1:uddAzsPgqdMAYatqJ0lsjX1oECcQLIlRpzZh3pJrofs=
+github.com/cloudflare/circl v1.3.7 h1:qlCDlTPz2n9fu58M0Nh1J/JzcFpfgkFHHX3O35r5vcU=
+github.com/cloudflare/circl v1.3.7/go.mod h1:sRTcRWXGLrKw6yIGJ+l7amYJFfAXbZG0kBSc8r4zxgA=
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
-github.com/cyphar/filepath-securejoin v0.4.1 h1:JyxxyPEaktOD+GAnqIqTf9A8tHyAG22rowi7HkoSU1s=
-github.com/cyphar/filepath-securejoin v0.4.1/go.mod h1:Sdj7gXlvMcPZsbhwhQ33GguGLDGQL7h7bg04C/+u9jI=
+github.com/cyphar/filepath-securejoin v0.3.6 h1:4d9N5ykBnSp5Xn2JkhocYDkOpURL/18CYMpo6xB9uWM=
+github.com/cyphar/filepath-securejoin v0.3.6/go.mod h1:Sdj7gXlvMcPZsbhwhQ33GguGLDGQL7h7bg04C/+u9jI=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
-github.com/devtron-labs/devtron-services/common-lib v0.0.0-20250901093002-1be330be4db3 h1:jCxpB8+6KD29jenB4SLTimCYzsmazBAPKv6637xRT5M=
-github.com/devtron-labs/devtron-services/common-lib v0.0.0-20250901093002-1be330be4db3/go.mod h1:/Ciy9tD9OxZOWBDPIasM448H7uvSo4+ZJiExpfwBZpA=
+github.com/devtron-labs/devtron-services/common-lib v0.0.0-20251013041509-9d1c5175da2d h1:EAGZ+sei6Hl98Hp09HgNcnOIWgI43jcx1q0Mb6V5HdQ=
+github.com/devtron-labs/devtron-services/common-lib v0.0.0-20251013041509-9d1c5175da2d/go.mod h1:/Ciy9tD9OxZOWBDPIasM448H7uvSo4+ZJiExpfwBZpA=
github.com/devtron-labs/protos v0.0.3-0.20250323220609-ecf8a0f7305e h1:U6UdYbW8a7xn5IzFPd8cywjVVPfutGJCudjePAfL/Hs=
github.com/devtron-labs/protos v0.0.3-0.20250323220609-ecf8a0f7305e/go.mod h1:1TqULGlTey+VNhAu/ag7NJuUvByJemkqodsc9L5PHJk=
github.com/docker/cli v28.1.1+incompatible h1:eyUemzeI45DY7eDPuwUcmDyDj1pM98oD5MdSpiItp8k=
github.com/docker/cli v28.1.1+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
-github.com/elazarl/goproxy v1.7.2 h1:Y2o6urb7Eule09PjlhQRGNsqRfPmYI3KKQLFpCAV3+o=
-github.com/elazarl/goproxy v1.7.2/go.mod h1:82vkLNir0ALaW14Rc399OTTjyNREgmdL2cVoIbS6XaE=
+github.com/elazarl/goproxy v1.4.0 h1:4GyuSbFa+s26+3rmYNSuUVsx+HgPrV1bk1jXI0l9wjM=
+github.com/elazarl/goproxy v1.4.0/go.mod h1:X/5W/t+gzDyLfHW4DrMdpjqYjpXsURlBt9lpBDxZZZQ=
github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc=
github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ=
-github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=
-github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k=
github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0=
@@ -53,16 +51,16 @@ github.com/go-git/go-billy/v5 v5.6.2 h1:6Q86EsPXMa7c3YZ3aLAQsMA0VlWmy43r6FHqa/UN
github.com/go-git/go-billy/v5 v5.6.2/go.mod h1:rcFC2rAsp/erv7CMz9GczHcuD0D32fWzH+MJAU+jaUU=
github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399 h1:eMje31YglSBqCdIqdhKBW8lokaMrL3uTkpGYlE2OOT4=
github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399/go.mod h1:1OCfN199q1Jm3HZlxleg+Dw/mwps2Wbk9frAWm+4FII=
-github.com/go-git/go-git/v5 v5.16.0 h1:k3kuOEpkc0DeY7xlL6NaaNg39xdgQbtH5mwCafHO9AQ=
-github.com/go-git/go-git/v5 v5.16.0/go.mod h1:4Ge4alE/5gPs30F2H1esi2gPd69R0C39lolkucHBOp8=
+github.com/go-git/go-git/v5 v5.13.2 h1:7O7xvsK7K+rZPKW6AQR1YyNhfywkv7B8/FsP3ki6Zv0=
+github.com/go-git/go-git/v5 v5.13.2/go.mod h1:hWdW5P4YZRjmpGHwRH2v3zkWcNl6HeXaXQEMGb3NJ9A=
github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
github.com/go-pg/pg v6.15.1+incompatible h1:vO4P9WoCi+i4qomgcBXWlKgDk4GcHAqDAOIfkEpi7B4=
github.com/go-pg/pg v6.15.1+incompatible/go.mod h1:a2oXow+aFOrvwcKs3eIA0lNFmMilrxK2sOkB5NWe0vA=
-github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 h1:f+oWsMOmNPc8JmEHVZIycC7hBoQxHH9pNKQORJNozsQ=
-github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8/go.mod h1:wcDNUvekVysuuOpQKo3191zZyTpiI6se1N1ULghS0sw=
+github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE=
+github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
@@ -73,16 +71,16 @@ github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/wire v0.6.0 h1:HBkoIh4BdSxoyo9PveV8giw7ZsaBOvzWKfcg/6MrVwI=
github.com/google/wire v0.6.0/go.mod h1:F4QhpQ9EDIdJ1Mbop/NZBRB+5yrR6qg3BnctaoUk6NA=
-github.com/gorilla/handlers v1.5.2 h1:cLTUSsNkgcwhgRqvCNmdbRWG0A3N4F+M2nWKdScwyEE=
-github.com/gorilla/handlers v1.5.2/go.mod h1:dX+xVpaxdSw+q0Qek8SSsl3dfMk3jNddUkMzo0GtH0w=
+github.com/gorilla/handlers v1.4.2 h1:0QniY0USkHQ1RGCLfKxeNHK9bkDHGRYGNDFBCS+YARg=
+github.com/gorilla/handlers v1.4.2/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ=
github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY=
github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ=
github.com/gorilla/schema v1.4.1 h1:jUg5hUjCSDZpNGLuXQOgIWGdlgrIdYvgQ0wZtdK1M3E=
github.com/gorilla/schema v1.4.1/go.mod h1:Dg5SSm5PV60mhF2NFaTV1xuYYj8tV8NOPRo4FggUMnM=
github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674 h1:JeSE6pjso5THxAzdVpqr6/geYxZytqFMBCOtn/ujyeo=
github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674/go.mod h1:r4w70xmWCQKmi1ONH4KIaBptdivuRPyosB9RmPlGEwA=
-github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.3.2 h1:sGm2vDRFUrQJO/Veii4h4zG2vvqG6uWNkBHSTqXOZk0=
-github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.3.2/go.mod h1:wd1YpapPLivG6nQgbf7ZkG1hhSOXDhhn4MLTknx2aAc=
+github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.0.1 h1:HcUWd006luQPljE73d5sk+/VgYPGUReEVz2y1/qylwY=
+github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.0.1/go.mod h1:w9Y7gY31krpLmrVU5ZPG9H7l9fZuRu5/3R3S3FMtVQ4=
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 h1:Ovs26xHkKqVztRpIrF/92BcuyuQ/YW4NSIpoGtfXNho=
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A=
@@ -134,15 +132,15 @@ github.com/prometheus/procfs v0.16.1 h1:hZ15bTNuirocR6u0JZ6BAHHmwS1p8B4P6MRqxtzM
github.com/prometheus/procfs v0.16.1/go.mod h1:teAbpZRB1iIAJYREa1LsoWUXykVXA1KlTmWl8x/U+Is=
github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs=
github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro=
-github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=
-github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=
+github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8=
+github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4=
github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 h1:n661drycOFuPLCN3Uc8sB6B/s6Z4t2xvBgU1htSHuq8=
github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4=
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
-github.com/skeema/knownhosts v1.3.1 h1:X2osQ+RAjK76shCbvhHHHVl3ZlgDm8apHEHFqRjnBY8=
-github.com/skeema/knownhosts v1.3.1/go.mod h1:r7KTdC8l4uxWRyK2TpQZ/1o5HaSzh06ePQNxPwTcfiY=
+github.com/skeema/knownhosts v1.3.0 h1:AM+y0rI04VksttfwjkSTNQorvGqmwATnvnAHpSgc0LY=
+github.com/skeema/knownhosts v1.3.0/go.mod h1:sPINvnADmT/qYH1kfv+ePMmOBTH6Tbl7b5LvTDjFK7M=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY=
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
@@ -151,13 +149,12 @@ github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81P
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
-github.com/tidwall/gjson v1.18.0 h1:FIDeeyB800efLX89e5a8Y0BNH+LOngJyGrIWxG2FKQY=
-github.com/tidwall/gjson v1.18.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
+github.com/tidwall/gjson v1.9.3 h1:hqzS9wAHMO+KVBBkLxYdkEeeFHuqr95GfClRLKlgK0E=
+github.com/tidwall/gjson v1.9.3/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA=
github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
+github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs=
github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
-github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4=
-github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM=
github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
diff --git a/git-sensor/internals/sql/GitProviderRepository.go b/git-sensor/internals/sql/GitProviderRepository.go
index d16aaa7e9..f1e493455 100644
--- a/git-sensor/internals/sql/GitProviderRepository.go
+++ b/git-sensor/internals/sql/GitProviderRepository.go
@@ -16,7 +16,10 @@
package sql
-import "github.com/go-pg/pg"
+import (
+ "github.com/devtron-labs/common-lib/securestore"
+ "github.com/go-pg/pg"
+)
type AuthMode string
@@ -28,20 +31,20 @@ const (
)
type GitProvider struct {
- tableName struct{} `sql:"git_provider"`
- Id int `sql:"id,pk"`
- Name string `sql:"name,notnull"`
- Url string `sql:"url,notnull"`
- UserName string `sql:"user_name"`
- Password string `sql:"password"`
- SshPrivateKey string `sql:"ssh_private_key"`
- AccessToken string `sql:"access_token"`
- AuthMode AuthMode `sql:"auth_mode,notnull"`
- Active bool `sql:"active,notnull"`
- TlsCert string `sql:"tls_cert"`
- TlsKey string `sql:"tls_key"`
- CaCert string `sql:"ca_cert"`
- EnableTLSVerification bool `sql:"enable_tls_verification"`
+ tableName struct{} `sql:"git_provider"`
+ Id int `sql:"id,pk"`
+ Name string `sql:"name,notnull"`
+ Url string `sql:"url,notnull"`
+ UserName string `sql:"user_name"`
+ Password securestore.EncryptedString `sql:"password"`
+ SshPrivateKey securestore.EncryptedString `sql:"ssh_private_key"`
+ AccessToken securestore.EncryptedString `sql:"access_token"`
+ AuthMode AuthMode `sql:"auth_mode,notnull"`
+ Active bool `sql:"active,notnull"`
+ TlsCert string `sql:"tls_cert"`
+ TlsKey string `sql:"tls_key"`
+ CaCert string `sql:"ca_cert"`
+ EnableTLSVerification bool `sql:"enable_tls_verification"`
//models.AuditLog
}
@@ -61,11 +64,13 @@ func NewGitProviderRepositoryImpl(dbConnection *pg.DB) *GitProviderRepositoryImp
}
func (impl GitProviderRepositoryImpl) Save(provider *GitProvider) error {
+ //not doing encryption here as fields are already encrypted in orch and send as it is here
_, err := impl.dbConnection.Model(provider).Insert()
return err
}
func (impl GitProviderRepositoryImpl) Update(provider *GitProvider) error {
+ //not doing encryption here as fields are already encrypted in orch and send as it is here
_, err := impl.dbConnection.Model(provider).WherePK().Update()
return err
}
diff --git a/git-sensor/pkg/RepoManages.go b/git-sensor/pkg/RepoManages.go
index 90a448727..67e65e43f 100644
--- a/git-sensor/pkg/RepoManages.go
+++ b/git-sensor/pkg/RepoManages.go
@@ -182,7 +182,7 @@ func (impl RepoManagerImpl) InactivateWebhookDataMappingForPipelineMaterials(old
func (impl RepoManagerImpl) updateCommitsInPipelineMaterial(gitCtx git.GitContext,
material *sql.GitMaterial, pipelineMaterial *sql.CiPipelineMaterial) *sql.CiPipelineMaterial {
- gitCtx = gitCtx.WithCredentials(material.GitProvider.UserName, material.GitProvider.Password).
+ gitCtx = gitCtx.WithCredentials(material.GitProvider.UserName, material.GitProvider.Password.String()).
WithTLSData(material.GitProvider.CaCert, material.GitProvider.TlsKey, material.GitProvider.TlsCert, material.GitProvider.EnableTLSVerification)
fetchCount := impl.configuration.GitHistoryCount
@@ -248,7 +248,7 @@ func (impl RepoManagerImpl) SaveGitProvider(provider *sql.GitProvider) (*sql.Git
}
if (err == nil) && (provider.AuthMode == sql.AUTH_MODE_SSH) {
- err = git.CreateOrUpdateSshPrivateKeyOnDisk(provider.Id, provider.SshPrivateKey)
+ err = git.CreateOrUpdateSshPrivateKeyOnDisk(provider.Id, provider.SshPrivateKey.String())
if err != nil {
impl.logger.Errorw("error in creating/updating ssh private key ", "err", err)
}
@@ -393,7 +393,7 @@ func (impl RepoManagerImpl) checkoutMaterial(gitCtx git.GitContext, material *sq
checkoutLocationForFetching := impl.repositoryManager.GetCheckoutLocation(gitCtx, material, gitProvider.Url, checkoutPath)
- errMsg, err := impl.repositoryManager.Add(gitCtx, material.GitProviderId, checkoutPath, material.Url, gitProvider.AuthMode, gitProvider.SshPrivateKey)
+ errMsg, err := impl.repositoryManager.Add(gitCtx, material.GitProviderId, checkoutPath, material.Url, gitProvider.AuthMode, gitProvider.SshPrivateKey.String())
if err != nil {
impl.logger.Errorw("error encountered in adding git repo", "materialId", material.Id, "err", err, "errMsg", errMsg)
material.CheckoutStatus = false
@@ -800,7 +800,7 @@ func (impl RepoManagerImpl) GetCommitMetadataForPipelineMaterial(gitCtx git.GitC
return nil, err
}
- gitCtx = gitCtx.WithCredentials(gitMaterial.GitProvider.UserName, gitMaterial.GitProvider.Password).
+ gitCtx = gitCtx.WithCredentials(gitMaterial.GitProvider.UserName, gitMaterial.GitProvider.Password.String()).
WithTLSData(gitMaterial.GitProvider.CaCert, gitMaterial.GitProvider.TlsKey, gitMaterial.GitProvider.TlsCert, gitMaterial.GitProvider.EnableTLSVerification) // validate checkout status of gitMaterial
if !gitMaterial.CheckoutStatus {
impl.logger.Errorw("checkout not success", "gitMaterialId", gitMaterialId)
@@ -859,7 +859,7 @@ func (impl RepoManagerImpl) GetReleaseChanges(gitCtx git.GitContext, request *Re
impl.locker.ReturnLocker(gitMaterial.Id)
}()
- gitCtx = gitCtx.WithCredentials(gitMaterial.GitProvider.UserName, gitMaterial.GitProvider.Password).
+ gitCtx = gitCtx.WithCredentials(gitMaterial.GitProvider.UserName, gitMaterial.GitProvider.Password.String()).
WithTLSData(gitMaterial.GitProvider.CaCert, gitMaterial.GitProvider.TlsKey, gitMaterial.GitProvider.TlsCert, gitMaterial.GitProvider.EnableTLSVerification)
gitChanges, err := impl.repositoryManagerAnalytics.ChangesSinceByRepositoryForAnalytics(gitCtx, gitMaterial.CheckoutLocation, request.OldCommit, request.NewCommit)
diff --git a/git-sensor/pkg/git/Util.go b/git-sensor/pkg/git/Util.go
index 2b96e6eee..d067b1bac 100644
--- a/git-sensor/pkg/git/Util.go
+++ b/git-sensor/pkg/git/Util.go
@@ -72,10 +72,10 @@ func GetCheckoutPath(url string, cloneLocation string) string {
func GetUserNamePassword(gitProvider *sql.GitProvider) (userName, password string, err error) {
switch gitProvider.AuthMode {
case sql.AUTH_MODE_USERNAME_PASSWORD:
- return gitProvider.UserName, gitProvider.Password, nil
+ return gitProvider.UserName, gitProvider.Password.String(), nil
case sql.AUTH_MODE_ACCESS_TOKEN:
- return gitProvider.UserName, gitProvider.AccessToken, nil
+ return gitProvider.UserName, gitProvider.AccessToken.String(), nil
case sql.AUTH_MODE_ANONYMOUS:
return "", "", nil
case sql.AUTH_MODE_SSH:
diff --git a/git-sensor/pkg/git/Watcher.go b/git-sensor/pkg/git/Watcher.go
index c0ff1d51a..19f811263 100644
--- a/git-sensor/pkg/git/Watcher.go
+++ b/git-sensor/pkg/git/Watcher.go
@@ -201,7 +201,7 @@ func (impl *GitWatcherImpl) handleSshKeyCreationAndRetry(gitCtx GitContext, mate
return false, nil, errMsg, err
}
}
- _, errMsg, err = impl.repositoryManager.CreateSshFileIfNotExistsAndConfigureSshCommand(gitCtx, location, gitProvider.Id, gitProvider.SshPrivateKey)
+ _, errMsg, err = impl.repositoryManager.CreateSshFileIfNotExistsAndConfigureSshCommand(gitCtx, location, gitProvider.Id, gitProvider.SshPrivateKey.String())
if err != nil {
impl.logger.Errorw("error in creating/configuring ssh private key on disk ", "repo", material.Url, "gitProviderId", gitProvider.Id, "errMsg", errMsg, "err", err)
return false, nil, errMsg, err
diff --git a/git-sensor/vendor/dario.cat/mergo/.gitignore b/git-sensor/vendor/dario.cat/mergo/.gitignore
index 45ad0f1ae..529c3412b 100644
--- a/git-sensor/vendor/dario.cat/mergo/.gitignore
+++ b/git-sensor/vendor/dario.cat/mergo/.gitignore
@@ -13,9 +13,6 @@
# Output of the go coverage tool, specifically when used with LiteIDE
*.out
-# Golang/Intellij
-.idea
-
# Project-local glide cache, RE: https://github.com/Masterminds/glide/issues/736
.glide/
diff --git a/git-sensor/vendor/dario.cat/mergo/FUNDING.json b/git-sensor/vendor/dario.cat/mergo/FUNDING.json
deleted file mode 100644
index 0585e1fe1..000000000
--- a/git-sensor/vendor/dario.cat/mergo/FUNDING.json
+++ /dev/null
@@ -1,7 +0,0 @@
-{
- "drips": {
- "ethereum": {
- "ownedBy": "0x6160020e7102237aC41bdb156e94401692D76930"
- }
- }
-}
diff --git a/git-sensor/vendor/dario.cat/mergo/README.md b/git-sensor/vendor/dario.cat/mergo/README.md
index 0e4a59afd..7d0cf9f32 100644
--- a/git-sensor/vendor/dario.cat/mergo/README.md
+++ b/git-sensor/vendor/dario.cat/mergo/README.md
@@ -44,21 +44,13 @@ Also a lovely [comune](http://en.wikipedia.org/wiki/Mergo) (municipality) in the
## Status
-Mergo is stable and frozen, ready for production. Check a short list of the projects using at large scale it [here](https://github.com/imdario/mergo#mergo-in-the-wild).
-
-No new features are accepted. They will be considered for a future v2 that improves the implementation and fixes bugs for corner cases.
+It is ready for production use. [It is used in several projects by Docker, Google, The Linux Foundation, VMWare, Shopify, Microsoft, etc](https://github.com/imdario/mergo#mergo-in-the-wild).
### Important notes
#### 1.0.0
-In [1.0.0](//github.com/imdario/mergo/releases/tag/1.0.0) Mergo moves to a vanity URL `dario.cat/mergo`. No more v1 versions will be released.
-
-If the vanity URL is causing issues in your project due to a dependency pulling Mergo - it isn't a direct dependency in your project - it is recommended to use [replace](https://github.com/golang/go/wiki/Modules#when-should-i-use-the-replace-directive) to pin the version to the last one with the old import URL:
-
-```
-replace github.com/imdario/mergo => github.com/imdario/mergo v0.3.16
-```
+In [1.0.0](//github.com/imdario/mergo/releases/tag/1.0.0) Mergo moves to a vanity URL `dario.cat/mergo`.
#### 0.3.9
@@ -72,23 +64,55 @@ If you were using Mergo before April 6th, 2015, please check your project works
If Mergo is useful to you, consider buying me a coffee, a beer, or making a monthly donation to allow me to keep building great free software. :heart_eyes:
+
### Mergo in the wild
-Mergo is used by [thousands](https://deps.dev/go/dario.cat%2Fmergo/v1.0.0/dependents) [of](https://deps.dev/go/github.com%2Fimdario%2Fmergo/v0.3.16/dependents) [projects](https://deps.dev/go/github.com%2Fimdario%2Fmergo/v0.3.12), including:
-
-* [containerd/containerd](https://github.com/containerd/containerd)
-* [datadog/datadog-agent](https://github.com/datadog/datadog-agent)
-* [docker/cli/](https://github.com/docker/cli/)
-* [goreleaser/goreleaser](https://github.com/goreleaser/goreleaser)
-* [go-micro/go-micro](https://github.com/go-micro/go-micro)
-* [grafana/loki](https://github.com/grafana/loki)
-* [masterminds/sprig](github.com/Masterminds/sprig)
-* [moby/moby](https://github.com/moby/moby)
-* [slackhq/nebula](https://github.com/slackhq/nebula)
-* [volcano-sh/volcano](https://github.com/volcano-sh/volcano)
+- [moby/moby](https://github.com/moby/moby)
+- [kubernetes/kubernetes](https://github.com/kubernetes/kubernetes)
+- [vmware/dispatch](https://github.com/vmware/dispatch)
+- [Shopify/themekit](https://github.com/Shopify/themekit)
+- [imdario/zas](https://github.com/imdario/zas)
+- [matcornic/hermes](https://github.com/matcornic/hermes)
+- [OpenBazaar/openbazaar-go](https://github.com/OpenBazaar/openbazaar-go)
+- [kataras/iris](https://github.com/kataras/iris)
+- [michaelsauter/crane](https://github.com/michaelsauter/crane)
+- [go-task/task](https://github.com/go-task/task)
+- [sensu/uchiwa](https://github.com/sensu/uchiwa)
+- [ory/hydra](https://github.com/ory/hydra)
+- [sisatech/vcli](https://github.com/sisatech/vcli)
+- [dairycart/dairycart](https://github.com/dairycart/dairycart)
+- [projectcalico/felix](https://github.com/projectcalico/felix)
+- [resin-os/balena](https://github.com/resin-os/balena)
+- [go-kivik/kivik](https://github.com/go-kivik/kivik)
+- [Telefonica/govice](https://github.com/Telefonica/govice)
+- [supergiant/supergiant](supergiant/supergiant)
+- [SergeyTsalkov/brooce](https://github.com/SergeyTsalkov/brooce)
+- [soniah/dnsmadeeasy](https://github.com/soniah/dnsmadeeasy)
+- [ohsu-comp-bio/funnel](https://github.com/ohsu-comp-bio/funnel)
+- [EagerIO/Stout](https://github.com/EagerIO/Stout)
+- [lynndylanhurley/defsynth-api](https://github.com/lynndylanhurley/defsynth-api)
+- [russross/canvasassignments](https://github.com/russross/canvasassignments)
+- [rdegges/cryptly-api](https://github.com/rdegges/cryptly-api)
+- [casualjim/exeggutor](https://github.com/casualjim/exeggutor)
+- [divshot/gitling](https://github.com/divshot/gitling)
+- [RWJMurphy/gorl](https://github.com/RWJMurphy/gorl)
+- [andrerocker/deploy42](https://github.com/andrerocker/deploy42)
+- [elwinar/rambler](https://github.com/elwinar/rambler)
+- [tmaiaroto/gopartman](https://github.com/tmaiaroto/gopartman)
+- [jfbus/impressionist](https://github.com/jfbus/impressionist)
+- [Jmeyering/zealot](https://github.com/Jmeyering/zealot)
+- [godep-migrator/rigger-host](https://github.com/godep-migrator/rigger-host)
+- [Dronevery/MultiwaySwitch-Go](https://github.com/Dronevery/MultiwaySwitch-Go)
+- [thoas/picfit](https://github.com/thoas/picfit)
+- [mantasmatelis/whooplist-server](https://github.com/mantasmatelis/whooplist-server)
+- [jnuthong/item_search](https://github.com/jnuthong/item_search)
+- [bukalapak/snowboard](https://github.com/bukalapak/snowboard)
+- [containerssh/containerssh](https://github.com/containerssh/containerssh)
+- [goreleaser/goreleaser](https://github.com/goreleaser/goreleaser)
+- [tjpnz/structbot](https://github.com/tjpnz/structbot)
## Install
@@ -117,39 +141,6 @@ if err := mergo.Merge(&dst, src, mergo.WithOverride); err != nil {
}
```
-If you need to override pointers, so the source pointer's value is assigned to the destination's pointer, you must use `WithoutDereference`:
-
-```go
-package main
-
-import (
- "fmt"
-
- "dario.cat/mergo"
-)
-
-type Foo struct {
- A *string
- B int64
-}
-
-func main() {
- first := "first"
- second := "second"
- src := Foo{
- A: &first,
- B: 2,
- }
-
- dest := Foo{
- A: &second,
- B: 1,
- }
-
- mergo.Merge(&dest, src, mergo.WithOverride, mergo.WithoutDereference)
-}
-```
-
Additionally, you can map a `map[string]interface{}` to a struct (and otherwise, from struct to map), following the same restrictions as in `Merge()`. Keys are capitalized to find each corresponding exported field.
```go
@@ -190,6 +181,10 @@ func main() {
}
```
+Note: if test are failing due missing package, please execute:
+
+ go get gopkg.in/yaml.v3
+
### Transformers
Transformers allow to merge specific types differently than in the default behavior. In other words, now you can customize how some types are merged. For example, `time.Time` is a struct; it doesn't have zero value but IsZero can return true because it has fields with zero value. How can we merge a non-zero `time.Time`?
diff --git a/git-sensor/vendor/dario.cat/mergo/SECURITY.md b/git-sensor/vendor/dario.cat/mergo/SECURITY.md
index 3788fcc1c..a5de61f77 100644
--- a/git-sensor/vendor/dario.cat/mergo/SECURITY.md
+++ b/git-sensor/vendor/dario.cat/mergo/SECURITY.md
@@ -4,8 +4,8 @@
| Version | Supported |
| ------- | ------------------ |
-| 1.x.x | :white_check_mark: |
-| < 1.0 | :x: |
+| 0.3.x | :white_check_mark: |
+| < 0.3 | :x: |
## Security contact information
diff --git a/git-sensor/vendor/dario.cat/mergo/map.go b/git-sensor/vendor/dario.cat/mergo/map.go
index 759b4f74f..b50d5c2a4 100644
--- a/git-sensor/vendor/dario.cat/mergo/map.go
+++ b/git-sensor/vendor/dario.cat/mergo/map.go
@@ -58,7 +58,7 @@ func deepMap(dst, src reflect.Value, visited map[uintptr]*visit, depth int, conf
}
fieldName := field.Name
fieldName = changeInitialCase(fieldName, unicode.ToLower)
- if _, ok := dstMap[fieldName]; !ok || (!isEmptyValue(reflect.ValueOf(src.Field(i).Interface()), !config.ShouldNotDereference) && overwrite) || config.overwriteWithEmptyValue {
+ if v, ok := dstMap[fieldName]; !ok || (isEmptyValue(reflect.ValueOf(v), !config.ShouldNotDereference) || overwrite) {
dstMap[fieldName] = src.Field(i).Interface()
}
}
diff --git a/git-sensor/vendor/dario.cat/mergo/merge.go b/git-sensor/vendor/dario.cat/mergo/merge.go
index fd47c95b2..0ef9b2138 100644
--- a/git-sensor/vendor/dario.cat/mergo/merge.go
+++ b/git-sensor/vendor/dario.cat/mergo/merge.go
@@ -269,7 +269,7 @@ func deepMerge(dst, src reflect.Value, visited map[uintptr]*visit, depth int, co
if err = deepMerge(dst.Elem(), src.Elem(), visited, depth+1, config); err != nil {
return
}
- } else if src.Elem().Kind() != reflect.Struct {
+ } else {
if overwriteWithEmptySrc || (overwrite && !src.IsNil()) || dst.IsNil() {
dst.Set(src)
}
diff --git a/git-sensor/vendor/github.com/ProtonMail/go-crypto/openpgp/errors/errors.go b/git-sensor/vendor/github.com/ProtonMail/go-crypto/openpgp/errors/errors.go
index 2e341507a..0eb3937b3 100644
--- a/git-sensor/vendor/github.com/ProtonMail/go-crypto/openpgp/errors/errors.go
+++ b/git-sensor/vendor/github.com/ProtonMail/go-crypto/openpgp/errors/errors.go
@@ -6,7 +6,6 @@
package errors // import "github.com/ProtonMail/go-crypto/openpgp/errors"
import (
- "fmt"
"strconv"
)
@@ -179,32 +178,3 @@ type ErrMalformedMessage string
func (dke ErrMalformedMessage) Error() string {
return "openpgp: malformed message " + string(dke)
}
-
-type messageTooLargeError int
-
-func (e messageTooLargeError) Error() string {
- return "openpgp: decompressed message size exceeds provided limit"
-}
-
-// ErrMessageTooLarge is returned if the read data from
-// a compressed packet exceeds the provided limit.
-var ErrMessageTooLarge error = messageTooLargeError(0)
-
-// ErrEncryptionKeySelection is returned if encryption key selection fails (v2 API).
-type ErrEncryptionKeySelection struct {
- PrimaryKeyId string
- PrimaryKeyErr error
- EncSelectionKeyId *string
- EncSelectionErr error
-}
-
-func (eks ErrEncryptionKeySelection) Error() string {
- prefix := fmt.Sprintf("openpgp: key selection for primary key %s:", eks.PrimaryKeyId)
- if eks.PrimaryKeyErr != nil {
- return fmt.Sprintf("%s invalid primary key: %s", prefix, eks.PrimaryKeyErr)
- }
- if eks.EncSelectionKeyId != nil {
- return fmt.Sprintf("%s invalid encryption key %s: %s", prefix, *eks.EncSelectionKeyId, eks.EncSelectionErr)
- }
- return fmt.Sprintf("%s no encryption key: %s", prefix, eks.EncSelectionErr)
-}
diff --git a/git-sensor/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/aead_config.go b/git-sensor/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/aead_config.go
index ef100d372..fec41a0e7 100644
--- a/git-sensor/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/aead_config.go
+++ b/git-sensor/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/aead_config.go
@@ -37,7 +37,7 @@ func (conf *AEADConfig) Mode() AEADMode {
// ChunkSizeByte returns the byte indicating the chunk size. The effective
// chunk size is computed with the formula uint64(1) << (chunkSizeByte + 6)
-// limit chunkSizeByte to 16 which equals to 2^22 = 4 MiB
+// limit to 16 = 4 MiB
// https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-07.html#section-5.13.2
func (conf *AEADConfig) ChunkSizeByte() byte {
if conf == nil || conf.ChunkSize == 0 {
@@ -49,8 +49,8 @@ func (conf *AEADConfig) ChunkSizeByte() byte {
switch {
case exponent < 6:
exponent = 6
- case exponent > 22:
- exponent = 22
+ case exponent > 16:
+ exponent = 16
}
return byte(exponent - 6)
diff --git a/git-sensor/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/compressed.go b/git-sensor/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/compressed.go
index 931f55a4e..0bcb38cac 100644
--- a/git-sensor/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/compressed.go
+++ b/git-sensor/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/compressed.go
@@ -98,16 +98,6 @@ func (c *Compressed) parse(r io.Reader) error {
return err
}
-// LimitedBodyReader wraps the provided body reader with a limiter that restricts
-// the number of bytes read to the specified limit.
-// If limit is nil, the reader is unbounded.
-func (c *Compressed) LimitedBodyReader(limit *int64) io.Reader {
- if limit == nil {
- return c.Body
- }
- return &LimitReader{R: c.Body, N: *limit}
-}
-
// compressedWriterCloser represents the serialized compression stream
// header and the compressor. Its Close() method ensures that both the
// compressor and serialized stream header are closed. Its Write()
@@ -169,24 +159,3 @@ func SerializeCompressed(w io.WriteCloser, algo CompressionAlgo, cc *Compression
return
}
-
-// LimitReader is an io.Reader that fails with MessageToLarge if read bytes exceed N.
-type LimitReader struct {
- R io.Reader // underlying reader
- N int64 // max bytes allowed
-}
-
-func (l *LimitReader) Read(p []byte) (int, error) {
- if l.N <= 0 {
- return 0, errors.ErrMessageTooLarge
- }
-
- n, err := l.R.Read(p)
- l.N -= int64(n)
-
- if err == nil && l.N <= 0 {
- err = errors.ErrMessageTooLarge
- }
-
- return n, err
-}
diff --git a/git-sensor/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/config.go b/git-sensor/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/config.go
index 30167ed9d..8bf8e6e51 100644
--- a/git-sensor/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/config.go
+++ b/git-sensor/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/config.go
@@ -173,16 +173,6 @@ type Config struct {
// weaknesses in the hash algo, potentially hindering e.g. some chosen-prefix attacks.
// The default behavior, when the config or flag is nil, is to enable the feature.
NonDeterministicSignaturesViaNotation *bool
-
- // InsecureAllowAllKeyFlagsWhenMissing determines how a key without valid key flags is handled.
- // When set to true, a key without flags is treated as if all flags are enabled.
- // This behavior is consistent with GPG.
- InsecureAllowAllKeyFlagsWhenMissing bool
-
- // MaxDecompressedMessageSize specifies the maximum number of bytes that can be
- // read from a compressed packet. This serves as an upper limit to prevent
- // excessively large decompressed messages.
- MaxDecompressedMessageSize *int64
}
func (c *Config) Random() io.Reader {
@@ -413,20 +403,6 @@ func (c *Config) RandomizeSignaturesViaNotation() bool {
return *c.NonDeterministicSignaturesViaNotation
}
-func (c *Config) AllowAllKeyFlagsWhenMissing() bool {
- if c == nil {
- return false
- }
- return c.InsecureAllowAllKeyFlagsWhenMissing
-}
-
-func (c *Config) DecompressedMessageSizeLimit() *int64 {
- if c == nil {
- return nil
- }
- return c.MaxDecompressedMessageSize
-}
-
// BoolPointer is a helper function to set a boolean pointer in the Config.
// e.g., config.CheckPacketSequence = BoolPointer(true)
func BoolPointer(value bool) *bool {
diff --git a/git-sensor/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/public_key.go b/git-sensor/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/public_key.go
index e2813396e..f8da781bb 100644
--- a/git-sensor/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/public_key.go
+++ b/git-sensor/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/public_key.go
@@ -1048,17 +1048,12 @@ func (pk *PublicKey) VerifyDirectKeySignature(sig *Signature) (err error) {
// KeyIdString returns the public key's fingerprint in capital hex
// (e.g. "6C7EE1B8621CC013").
func (pk *PublicKey) KeyIdString() string {
- return fmt.Sprintf("%016X", pk.KeyId)
+ return fmt.Sprintf("%X", pk.Fingerprint[12:20])
}
// KeyIdShortString returns the short form of public key's fingerprint
// in capital hex, as shown by gpg --list-keys (e.g. "621CC013").
-// This function will return the full key id for v5 and v6 keys
-// since the short key id is undefined for them.
func (pk *PublicKey) KeyIdShortString() string {
- if pk.Version >= 5 {
- return pk.KeyIdString()
- }
return fmt.Sprintf("%X", pk.Fingerprint[16:20])
}
diff --git a/git-sensor/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/signature.go b/git-sensor/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/signature.go
index 84dd3b86f..3a4b366d8 100644
--- a/git-sensor/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/signature.go
+++ b/git-sensor/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/signature.go
@@ -1288,9 +1288,7 @@ func (sig *Signature) buildSubpackets(issuer PublicKey) (subpackets []outputSubp
if sig.IssuerKeyId != nil && sig.Version == 4 {
keyId := make([]byte, 8)
binary.BigEndian.PutUint64(keyId, *sig.IssuerKeyId)
- // Note: making this critical breaks RPM <=4.16.
- // See: https://github.com/ProtonMail/go-crypto/issues/263
- subpackets = append(subpackets, outputSubpacket{true, issuerSubpacket, false, keyId})
+ subpackets = append(subpackets, outputSubpacket{true, issuerSubpacket, true, keyId})
}
// Notation Data
for _, notation := range sig.Notations {
diff --git a/git-sensor/vendor/github.com/ProtonMail/go-crypto/openpgp/read.go b/git-sensor/vendor/github.com/ProtonMail/go-crypto/openpgp/read.go
index 5578797ed..e6dd9b5fd 100644
--- a/git-sensor/vendor/github.com/ProtonMail/go-crypto/openpgp/read.go
+++ b/git-sensor/vendor/github.com/ProtonMail/go-crypto/openpgp/read.go
@@ -259,7 +259,7 @@ FindLiteralData:
}
switch p := p.(type) {
case *packet.Compressed:
- if err := packets.Push(p.LimitedBodyReader(config.DecompressedMessageSizeLimit())); err != nil {
+ if err := packets.Push(p.Body); err != nil {
return nil, err
}
case *packet.OnePassSignature:
diff --git a/git-sensor/vendor/github.com/ProtonMail/go-crypto/openpgp/write.go b/git-sensor/vendor/github.com/ProtonMail/go-crypto/openpgp/write.go
index 84bc27d83..b0f6ef7b0 100644
--- a/git-sensor/vendor/github.com/ProtonMail/go-crypto/openpgp/write.go
+++ b/git-sensor/vendor/github.com/ProtonMail/go-crypto/openpgp/write.go
@@ -253,12 +253,34 @@ func writeAndSign(payload io.WriteCloser, candidateHashes []uint8, signed *Entit
}
var hash crypto.Hash
- var salt []byte
- if signer != nil {
- if hash, err = selectHash(candidateHashes, config.Hash(), signer); err != nil {
- return nil, err
+ for _, hashId := range candidateHashes {
+ if h, ok := algorithm.HashIdToHash(hashId); ok && h.Available() {
+ hash = h
+ break
+ }
+ }
+
+ // If the hash specified by config is a candidate, we'll use that.
+ if configuredHash := config.Hash(); configuredHash.Available() {
+ for _, hashId := range candidateHashes {
+ if h, ok := algorithm.HashIdToHash(hashId); ok && h == configuredHash {
+ hash = h
+ break
+ }
+ }
+ }
+
+ if hash == 0 {
+ hashId := candidateHashes[0]
+ name, ok := algorithm.HashIdToString(hashId)
+ if !ok {
+ name = "#" + strconv.Itoa(int(hashId))
}
+ return nil, errors.InvalidArgumentError("cannot encrypt because no candidate hash functions are compiled in. (Wanted " + name + " in this case.)")
+ }
+ var salt []byte
+ if signer != nil {
var opsVersion = 3
if signer.Version == 6 {
opsVersion = signer.Version
@@ -536,34 +558,13 @@ func (s signatureWriter) Close() error {
return s.encryptedData.Close()
}
-func selectHashForSigningKey(config *packet.Config, signer *packet.PublicKey) crypto.Hash {
- acceptableHashes := acceptableHashesToWrite(signer)
- hash, ok := algorithm.HashToHashId(config.Hash())
- if !ok {
- return config.Hash()
- }
- for _, acceptableHashes := range acceptableHashes {
- if acceptableHashes == hash {
- return config.Hash()
- }
- }
- if len(acceptableHashes) > 0 {
- defaultAcceptedHash, ok := algorithm.HashIdToHash(acceptableHashes[0])
- if ok {
- return defaultAcceptedHash
- }
- }
- return config.Hash()
-}
-
func createSignaturePacket(signer *packet.PublicKey, sigType packet.SignatureType, config *packet.Config) *packet.Signature {
sigLifetimeSecs := config.SigLifetime()
- hash := selectHashForSigningKey(config, signer)
return &packet.Signature{
Version: signer.Version,
SigType: sigType,
PubKeyAlgo: signer.PubKeyAlgo,
- Hash: hash,
+ Hash: config.Hash(),
CreationTime: config.Now(),
IssuerKeyId: &signer.KeyId,
IssuerFingerprint: signer.Fingerprint,
@@ -617,74 +618,3 @@ func handleCompression(compressed io.WriteCloser, candidateCompression []uint8,
}
return data, nil
}
-
-// selectHash selects the preferred hash given the candidateHashes and the configuredHash
-func selectHash(candidateHashes []byte, configuredHash crypto.Hash, signer *packet.PrivateKey) (hash crypto.Hash, err error) {
- acceptableHashes := acceptableHashesToWrite(&signer.PublicKey)
- candidateHashes = intersectPreferences(acceptableHashes, candidateHashes)
-
- for _, hashId := range candidateHashes {
- if h, ok := algorithm.HashIdToHash(hashId); ok && h.Available() {
- hash = h
- break
- }
- }
-
- // If the hash specified by config is a candidate, we'll use that.
- if configuredHash.Available() {
- for _, hashId := range candidateHashes {
- if h, ok := algorithm.HashIdToHash(hashId); ok && h == configuredHash {
- hash = h
- break
- }
- }
- }
-
- if hash == 0 {
- if len(acceptableHashes) > 0 {
- if h, ok := algorithm.HashIdToHash(acceptableHashes[0]); ok {
- hash = h
- } else {
- return 0, errors.UnsupportedError("no candidate hash functions are compiled in.")
- }
- } else {
- return 0, errors.UnsupportedError("no candidate hash functions are compiled in.")
- }
- }
- return
-}
-
-func acceptableHashesToWrite(singingKey *packet.PublicKey) []uint8 {
- switch singingKey.PubKeyAlgo {
- case packet.PubKeyAlgoEd448:
- return []uint8{
- hashToHashId(crypto.SHA512),
- hashToHashId(crypto.SHA3_512),
- }
- case packet.PubKeyAlgoECDSA, packet.PubKeyAlgoEdDSA:
- if curve, err := singingKey.Curve(); err == nil {
- if curve == packet.Curve448 ||
- curve == packet.CurveNistP521 ||
- curve == packet.CurveBrainpoolP512 {
- return []uint8{
- hashToHashId(crypto.SHA512),
- hashToHashId(crypto.SHA3_512),
- }
- } else if curve == packet.CurveBrainpoolP384 ||
- curve == packet.CurveNistP384 {
- return []uint8{
- hashToHashId(crypto.SHA384),
- hashToHashId(crypto.SHA512),
- hashToHashId(crypto.SHA3_512),
- }
- }
- }
- }
- return []uint8{
- hashToHashId(crypto.SHA256),
- hashToHashId(crypto.SHA384),
- hashToHashId(crypto.SHA512),
- hashToHashId(crypto.SHA3_256),
- hashToHashId(crypto.SHA3_512),
- }
-}
diff --git a/git-sensor/vendor/github.com/cloudflare/circl/dh/x25519/curve_amd64.s b/git-sensor/vendor/github.com/cloudflare/circl/dh/x25519/curve_amd64.s
index ce9f06289..b7723185b 100644
--- a/git-sensor/vendor/github.com/cloudflare/circl/dh/x25519/curve_amd64.s
+++ b/git-sensor/vendor/github.com/cloudflare/circl/dh/x25519/curve_amd64.s
@@ -1,5 +1,4 @@
-//go:build amd64 && !purego
-// +build amd64,!purego
+// +build amd64
#include "textflag.h"
diff --git a/git-sensor/vendor/github.com/cloudflare/circl/dh/x448/curve_amd64.s b/git-sensor/vendor/github.com/cloudflare/circl/dh/x448/curve_amd64.s
index ed33ba3d0..810aa9e64 100644
--- a/git-sensor/vendor/github.com/cloudflare/circl/dh/x448/curve_amd64.s
+++ b/git-sensor/vendor/github.com/cloudflare/circl/dh/x448/curve_amd64.s
@@ -1,5 +1,4 @@
-//go:build amd64 && !purego
-// +build amd64,!purego
+// +build amd64
#include "textflag.h"
diff --git a/git-sensor/vendor/github.com/cloudflare/circl/ecc/goldilocks/curve.go b/git-sensor/vendor/github.com/cloudflare/circl/ecc/goldilocks/curve.go
index 1f165141a..5a939100d 100644
--- a/git-sensor/vendor/github.com/cloudflare/circl/ecc/goldilocks/curve.go
+++ b/git-sensor/vendor/github.com/cloudflare/circl/ecc/goldilocks/curve.go
@@ -18,9 +18,6 @@ func (Curve) Identity() *Point {
func (Curve) IsOnCurve(P *Point) bool {
x2, y2, t, t2, z2 := &fp.Elt{}, &fp.Elt{}, &fp.Elt{}, &fp.Elt{}, &fp.Elt{}
rhs, lhs := &fp.Elt{}, &fp.Elt{}
- // Check z != 0
- eq0 := !fp.IsZero(&P.z)
-
fp.Mul(t, &P.ta, &P.tb) // t = ta*tb
fp.Sqr(x2, &P.x) // x^2
fp.Sqr(y2, &P.y) // y^2
@@ -30,14 +27,13 @@ func (Curve) IsOnCurve(P *Point) bool {
fp.Mul(rhs, t2, ¶mD) // dt^2
fp.Add(rhs, rhs, z2) // z^2 + dt^2
fp.Sub(lhs, lhs, rhs) // x^2 + y^2 - (z^2 + dt^2)
- eq1 := fp.IsZero(lhs)
+ eq0 := fp.IsZero(lhs)
fp.Mul(lhs, &P.x, &P.y) // xy
fp.Mul(rhs, t, &P.z) // tz
fp.Sub(lhs, lhs, rhs) // xy - tz
- eq2 := fp.IsZero(lhs)
-
- return eq0 && eq1 && eq2
+ eq1 := fp.IsZero(lhs)
+ return eq0 && eq1
}
// Generator returns the generator point.
diff --git a/git-sensor/vendor/github.com/cloudflare/circl/internal/conv/conv.go b/git-sensor/vendor/github.com/cloudflare/circl/internal/conv/conv.go
index 3fd0df496..649a8e931 100644
--- a/git-sensor/vendor/github.com/cloudflare/circl/internal/conv/conv.go
+++ b/git-sensor/vendor/github.com/cloudflare/circl/internal/conv/conv.go
@@ -5,8 +5,6 @@ import (
"fmt"
"math/big"
"strings"
-
- "golang.org/x/crypto/cryptobyte"
)
// BytesLe2Hex returns an hexadecimal string of a number stored in a
@@ -140,34 +138,3 @@ func BigInt2Uint64Le(z []uint64, x *big.Int) {
z[i] = 0
}
}
-
-// MarshalBinary encodes a value into a byte array in a format readable by UnmarshalBinary.
-func MarshalBinary(v cryptobyte.MarshalingValue) ([]byte, error) {
- const DefaultSize = 32
- b := cryptobyte.NewBuilder(make([]byte, 0, DefaultSize))
- b.AddValue(v)
- return b.Bytes()
-}
-
-// MarshalBinaryLen encodes a value into an array of n bytes in a format readable by UnmarshalBinary.
-func MarshalBinaryLen(v cryptobyte.MarshalingValue, length uint) ([]byte, error) {
- b := cryptobyte.NewFixedBuilder(make([]byte, 0, length))
- b.AddValue(v)
- return b.Bytes()
-}
-
-// A UnmarshalingValue decodes itself from a cryptobyte.String and advances the pointer.
-// It reports whether the read was successful.
-type UnmarshalingValue interface {
- Unmarshal(*cryptobyte.String) bool
-}
-
-// UnmarshalBinary recovers a value from a byte array.
-// It returns an error if the read was unsuccessful.
-func UnmarshalBinary(v UnmarshalingValue, data []byte) (err error) {
- s := cryptobyte.String(data)
- if data == nil || !v.Unmarshal(&s) || !s.Empty() {
- err = fmt.Errorf("cannot read %T from input string", v)
- }
- return
-}
diff --git a/git-sensor/vendor/github.com/cloudflare/circl/math/fp25519/fp_amd64.s b/git-sensor/vendor/github.com/cloudflare/circl/math/fp25519/fp_amd64.s
index 1fcc2dee1..5c4aeddec 100644
--- a/git-sensor/vendor/github.com/cloudflare/circl/math/fp25519/fp_amd64.s
+++ b/git-sensor/vendor/github.com/cloudflare/circl/math/fp25519/fp_amd64.s
@@ -1,5 +1,4 @@
-//go:build amd64 && !purego
-// +build amd64,!purego
+// +build amd64
#include "textflag.h"
#include "fp_amd64.h"
diff --git a/git-sensor/vendor/github.com/cloudflare/circl/math/fp448/fp_amd64.s b/git-sensor/vendor/github.com/cloudflare/circl/math/fp448/fp_amd64.s
index 3f1f07c98..435addf5e 100644
--- a/git-sensor/vendor/github.com/cloudflare/circl/math/fp448/fp_amd64.s
+++ b/git-sensor/vendor/github.com/cloudflare/circl/math/fp448/fp_amd64.s
@@ -1,5 +1,4 @@
-//go:build amd64 && !purego
-// +build amd64,!purego
+// +build amd64
#include "textflag.h"
#include "fp_amd64.h"
diff --git a/git-sensor/vendor/github.com/cloudflare/circl/math/integer.go b/git-sensor/vendor/github.com/cloudflare/circl/math/integer.go
deleted file mode 100644
index 9c80c23b5..000000000
--- a/git-sensor/vendor/github.com/cloudflare/circl/math/integer.go
+++ /dev/null
@@ -1,16 +0,0 @@
-package math
-
-import "math/bits"
-
-// NextPow2 finds the next power of two (N=2^k, k>=0) greater than n.
-// If n is already a power of two, then this function returns n, and log2(n).
-func NextPow2(n uint) (N uint, k uint) {
- if bits.OnesCount(n) == 1 {
- k = uint(bits.TrailingZeros(n))
- N = n
- } else {
- k = uint(bits.Len(n))
- N = uint(1) << k
- }
- return
-}
diff --git a/git-sensor/vendor/github.com/cloudflare/circl/sign/ed25519/point.go b/git-sensor/vendor/github.com/cloudflare/circl/sign/ed25519/point.go
index d1c3b146b..374a69503 100644
--- a/git-sensor/vendor/github.com/cloudflare/circl/sign/ed25519/point.go
+++ b/git-sensor/vendor/github.com/cloudflare/circl/sign/ed25519/point.go
@@ -164,7 +164,7 @@ func (P *pointR1) isEqual(Q *pointR1) bool {
fp.Mul(r, r, &P.z)
fp.Sub(l, l, r)
b = b && fp.IsZero(l)
- return b && !fp.IsZero(&P.z) && !fp.IsZero(&Q.z)
+ return b
}
func (P *pointR3) neg() {
diff --git a/git-sensor/vendor/github.com/cloudflare/circl/sign/ed448/ed448.go b/git-sensor/vendor/github.com/cloudflare/circl/sign/ed448/ed448.go
index c368b181b..324bd8f33 100644
--- a/git-sensor/vendor/github.com/cloudflare/circl/sign/ed448/ed448.go
+++ b/git-sensor/vendor/github.com/cloudflare/circl/sign/ed448/ed448.go
@@ -206,7 +206,7 @@ func newKeyFromSeed(privateKey, seed []byte) {
func signAll(signature []byte, privateKey PrivateKey, message, ctx []byte, preHash bool) {
if len(ctx) > ContextMaxSize {
- panic(fmt.Errorf("ed448: bad context length: %v", len(ctx)))
+ panic(fmt.Errorf("ed448: bad context length: " + strconv.Itoa(len(ctx))))
}
H := sha3.NewShake256()
diff --git a/git-sensor/vendor/github.com/cloudflare/circl/sign/sign.go b/git-sensor/vendor/github.com/cloudflare/circl/sign/sign.go
index 557d6f096..13b20fa4b 100644
--- a/git-sensor/vendor/github.com/cloudflare/circl/sign/sign.go
+++ b/git-sensor/vendor/github.com/cloudflare/circl/sign/sign.go
@@ -107,7 +107,4 @@ var (
// ErrContextNotSupported is the error used if a context is not
// supported.
ErrContextNotSupported = errors.New("context not supported")
-
- // ErrContextTooLong is the error used if the context string is too long.
- ErrContextTooLong = errors.New("context string too long")
)
diff --git a/git-sensor/vendor/github.com/cyphar/filepath-securejoin/CHANGELOG.md b/git-sensor/vendor/github.com/cyphar/filepath-securejoin/CHANGELOG.md
index ca0e3c62c..cb1252b53 100644
--- a/git-sensor/vendor/github.com/cyphar/filepath-securejoin/CHANGELOG.md
+++ b/git-sensor/vendor/github.com/cyphar/filepath-securejoin/CHANGELOG.md
@@ -6,51 +6,6 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
## [Unreleased] ##
-## [0.4.1] - 2025-01-28 ##
-
-### Fixed ###
-- The restrictions added for `root` paths passed to `SecureJoin` in 0.4.0 was
- found to be too strict and caused some regressions when folks tried to
- update, so this restriction has been relaxed to only return an error if the
- path contains a `..` component. We still recommend users use `filepath.Clean`
- (and even `filepath.EvalSymlinks`) on the `root` path they are using, but at
- least you will no longer be punished for "trivial" unclean paths.
-
-## [0.4.0] - 2025-01-13 ##
-
-### Breaking ####
-- `SecureJoin(VFS)` will now return an error if the provided `root` is not a
- `filepath.Clean`'d path.
-
- While it is ultimately the responsibility of the caller to ensure the root is
- a safe path to use, passing a path like `/symlink/..` as a root would result
- in the `SecureJoin`'d path being placed in `/` even though `/symlink/..`
- might be a different directory, and so we should more strongly discourage
- such usage.
-
- All major users of `securejoin.SecureJoin` already ensure that the paths they
- provide are safe (and this is ultimately a question of user error), but
- removing this foot-gun is probably a good idea. Of course, this is
- necessarily a breaking API change (though we expect no real users to be
- affected by it).
-
- Thanks to [Erik Sjölund](https://github.com/eriksjolund), who initially
- reported this issue as a possible security issue.
-
-- `MkdirAll` and `MkdirHandle` now take an `os.FileMode`-style mode argument
- instead of a raw `unix.S_*`-style mode argument, which may cause compile-time
- type errors depending on how you use `filepath-securejoin`. For most users,
- there will be no change in behaviour aside from the type change (as the
- bottom `0o777` bits are the same in both formats, and most users are probably
- only using those bits).
-
- However, if you were using `unix.S_ISVTX` to set the sticky bit with
- `MkdirAll(Handle)` you will need to switch to `os.ModeSticky` otherwise you
- will get a runtime error with this update. In addition, the error message you
- will get from passing `unix.S_ISUID` and `unix.S_ISGID` will be different as
- they are treated as invalid bits now (note that previously passing said bits
- was also an error).
-
## [0.3.6] - 2024-12-17 ##
### Compatibility ###
@@ -238,9 +193,7 @@ This is our first release of `github.com/cyphar/filepath-securejoin`,
containing a full implementation with a coverage of 93.5% (the only missing
cases are the error cases, which are hard to mocktest at the moment).
-[Unreleased]: https://github.com/cyphar/filepath-securejoin/compare/v0.4.1...HEAD
-[0.4.1]: https://github.com/cyphar/filepath-securejoin/compare/v0.4.0...v0.4.1
-[0.4.0]: https://github.com/cyphar/filepath-securejoin/compare/v0.3.6...v0.4.0
+[Unreleased]: https://github.com/cyphar/filepath-securejoin/compare/v0.3.6...HEAD
[0.3.6]: https://github.com/cyphar/filepath-securejoin/compare/v0.3.5...v0.3.6
[0.3.5]: https://github.com/cyphar/filepath-securejoin/compare/v0.3.4...v0.3.5
[0.3.4]: https://github.com/cyphar/filepath-securejoin/compare/v0.3.3...v0.3.4
diff --git a/git-sensor/vendor/github.com/cyphar/filepath-securejoin/VERSION b/git-sensor/vendor/github.com/cyphar/filepath-securejoin/VERSION
index 267577d47..449d7e73a 100644
--- a/git-sensor/vendor/github.com/cyphar/filepath-securejoin/VERSION
+++ b/git-sensor/vendor/github.com/cyphar/filepath-securejoin/VERSION
@@ -1 +1 @@
-0.4.1
+0.3.6
diff --git a/git-sensor/vendor/github.com/cyphar/filepath-securejoin/join.go b/git-sensor/vendor/github.com/cyphar/filepath-securejoin/join.go
index e6634d477..e0ee3f2b5 100644
--- a/git-sensor/vendor/github.com/cyphar/filepath-securejoin/join.go
+++ b/git-sensor/vendor/github.com/cyphar/filepath-securejoin/join.go
@@ -1,5 +1,5 @@
// Copyright (C) 2014-2015 Docker Inc & Go Authors. All rights reserved.
-// Copyright (C) 2017-2025 SUSE LLC. All rights reserved.
+// Copyright (C) 2017-2024 SUSE LLC. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
@@ -24,31 +24,6 @@ func IsNotExist(err error) bool {
return errors.Is(err, os.ErrNotExist) || errors.Is(err, syscall.ENOTDIR) || errors.Is(err, syscall.ENOENT)
}
-// errUnsafeRoot is returned if the user provides SecureJoinVFS with a path
-// that contains ".." components.
-var errUnsafeRoot = errors.New("root path provided to SecureJoin contains '..' components")
-
-// stripVolume just gets rid of the Windows volume included in a path. Based on
-// some godbolt tests, the Go compiler is smart enough to make this a no-op on
-// Linux.
-func stripVolume(path string) string {
- return path[len(filepath.VolumeName(path)):]
-}
-
-// hasDotDot checks if the path contains ".." components in a platform-agnostic
-// way.
-func hasDotDot(path string) bool {
- // If we are on Windows, strip any volume letters. It turns out that
- // C:..\foo may (or may not) be a valid pathname and we need to handle that
- // leading "..".
- path = stripVolume(path)
- // Look for "/../" in the path, but we need to handle leading and trailing
- // ".."s by adding separators. Doing this with filepath.Separator is ugly
- // so just convert to Unix-style "/" first.
- path = filepath.ToSlash(path)
- return strings.Contains("/"+path+"/", "/../")
-}
-
// SecureJoinVFS joins the two given path components (similar to [filepath.Join]) except
// that the returned path is guaranteed to be scoped inside the provided root
// path (when evaluated). Any symbolic links in the path are evaluated with the
@@ -71,22 +46,7 @@ func hasDotDot(path string) bool {
// provided via direct input or when evaluating symlinks. Therefore:
//
// "C:\Temp" + "D:\path\to\file.txt" results in "C:\Temp\path\to\file.txt"
-//
-// If the provided root is not [filepath.Clean] then an error will be returned,
-// as such root paths are bordering on somewhat unsafe and using such paths is
-// not best practice. We also strongly suggest that any root path is first
-// fully resolved using [filepath.EvalSymlinks] or otherwise constructed to
-// avoid containing symlink components. Of course, the root also *must not* be
-// attacker-controlled.
func SecureJoinVFS(root, unsafePath string, vfs VFS) (string, error) {
- // The root path must not contain ".." components, otherwise when we join
- // the subpath we will end up with a weird path. We could work around this
- // in other ways but users shouldn't be giving us non-lexical root paths in
- // the first place.
- if hasDotDot(root) {
- return "", errUnsafeRoot
- }
-
// Use the os.* VFS implementation if none was specified.
if vfs == nil {
vfs = osVFS{}
@@ -99,10 +59,9 @@ func SecureJoinVFS(root, unsafePath string, vfs VFS) (string, error) {
linksWalked int
)
for remainingPath != "" {
- // On Windows, if we managed to end up at a path referencing a volume,
- // drop the volume to make sure we don't end up with broken paths or
- // escaping the root volume.
- remainingPath = stripVolume(remainingPath)
+ if v := filepath.VolumeName(remainingPath); v != "" {
+ remainingPath = remainingPath[len(v):]
+ }
// Get the next path component.
var part string
diff --git a/git-sensor/vendor/github.com/cyphar/filepath-securejoin/mkdir_linux.go b/git-sensor/vendor/github.com/cyphar/filepath-securejoin/mkdir_linux.go
index a17ae3b03..5e559bb7a 100644
--- a/git-sensor/vendor/github.com/cyphar/filepath-securejoin/mkdir_linux.go
+++ b/git-sensor/vendor/github.com/cyphar/filepath-securejoin/mkdir_linux.go
@@ -21,33 +21,6 @@ var (
errPossibleAttack = errors.New("possible attack detected")
)
-// modePermExt is like os.ModePerm except that it also includes the set[ug]id
-// and sticky bits.
-const modePermExt = os.ModePerm | os.ModeSetuid | os.ModeSetgid | os.ModeSticky
-
-//nolint:cyclop // this function needs to handle a lot of cases
-func toUnixMode(mode os.FileMode) (uint32, error) {
- sysMode := uint32(mode.Perm())
- if mode&os.ModeSetuid != 0 {
- sysMode |= unix.S_ISUID
- }
- if mode&os.ModeSetgid != 0 {
- sysMode |= unix.S_ISGID
- }
- if mode&os.ModeSticky != 0 {
- sysMode |= unix.S_ISVTX
- }
- // We don't allow file type bits.
- if mode&os.ModeType != 0 {
- return 0, fmt.Errorf("%w %+.3o (%s): type bits not permitted", errInvalidMode, mode, mode)
- }
- // We don't allow other unknown modes.
- if mode&^modePermExt != 0 || sysMode&unix.S_IFMT != 0 {
- return 0, fmt.Errorf("%w %+.3o (%s): unknown mode bits", errInvalidMode, mode, mode)
- }
- return sysMode, nil
-}
-
// MkdirAllHandle is equivalent to [MkdirAll], except that it is safer to use
// in two respects:
//
@@ -66,17 +39,17 @@ func toUnixMode(mode os.FileMode) (uint32, error) {
// a brand new lookup of unsafePath (such as with [SecureJoin] or openat2) after
// doing [MkdirAll]. If you intend to open the directory after creating it, you
// should use MkdirAllHandle.
-func MkdirAllHandle(root *os.File, unsafePath string, mode os.FileMode) (_ *os.File, Err error) {
- unixMode, err := toUnixMode(mode)
- if err != nil {
- return nil, err
+func MkdirAllHandle(root *os.File, unsafePath string, mode int) (_ *os.File, Err error) {
+ // Make sure there are no os.FileMode bits set.
+ if mode&^0o7777 != 0 {
+ return nil, fmt.Errorf("%w for mkdir 0o%.3o", errInvalidMode, mode)
}
// On Linux, mkdirat(2) (and os.Mkdir) silently ignore the suid and sgid
// bits. We could also silently ignore them but since we have very few
// users it seems more prudent to return an error so users notice that
// these bits will not be set.
- if unixMode&^0o1777 != 0 {
- return nil, fmt.Errorf("%w for mkdir %+.3o: suid and sgid are ignored by mkdir", errInvalidMode, mode)
+ if mode&^0o1777 != 0 {
+ return nil, fmt.Errorf("%w for mkdir 0o%.3o: suid and sgid are ignored by mkdir", errInvalidMode, mode)
}
// Try to open as much of the path as possible.
@@ -131,6 +104,9 @@ func MkdirAllHandle(root *os.File, unsafePath string, mode os.FileMode) (_ *os.F
return nil, fmt.Errorf("%w: yet-to-be-created path %q contains '..' components", unix.ENOENT, remainingPath)
}
+ // Make sure the mode doesn't have any type bits.
+ mode &^= unix.S_IFMT
+
// Create the remaining components.
for _, part := range remainingParts {
switch part {
@@ -147,7 +123,7 @@ func MkdirAllHandle(root *os.File, unsafePath string, mode os.FileMode) (_ *os.F
// directory at the same time as us. In that case, just continue on as
// if we created it (if the created inode is not a directory, the
// following open call will fail).
- if err := unix.Mkdirat(int(currentDir.Fd()), part, unixMode); err != nil && !errors.Is(err, unix.EEXIST) {
+ if err := unix.Mkdirat(int(currentDir.Fd()), part, uint32(mode)); err != nil && !errors.Is(err, unix.EEXIST) {
err = &os.PathError{Op: "mkdirat", Path: currentDir.Name() + "/" + part, Err: err}
// Make the error a bit nicer if the directory is dead.
if deadErr := isDeadInode(currentDir); deadErr != nil {
@@ -220,7 +196,10 @@ func MkdirAllHandle(root *os.File, unsafePath string, mode os.FileMode) (_ *os.F
// If you plan to open the directory after you have created it or want to use
// an open directory handle as the root, you should use [MkdirAllHandle] instead.
// This function is a wrapper around [MkdirAllHandle].
-func MkdirAll(root, unsafePath string, mode os.FileMode) error {
+//
+// NOTE: The mode argument must be set the unix mode bits (unix.S_I...), not
+// the Go generic mode bits ([os.FileMode]...).
+func MkdirAll(root, unsafePath string, mode int) error {
rootDir, err := os.OpenFile(root, unix.O_PATH|unix.O_DIRECTORY|unix.O_CLOEXEC, 0)
if err != nil {
return err
diff --git a/git-sensor/vendor/github.com/devtron-labs/common-lib/securestore/AttributesRepoDBConnection.go b/git-sensor/vendor/github.com/devtron-labs/common-lib/securestore/AttributesRepoDBConnection.go
new file mode 100644
index 000000000..907d202bd
--- /dev/null
+++ b/git-sensor/vendor/github.com/devtron-labs/common-lib/securestore/AttributesRepoDBConnection.go
@@ -0,0 +1,75 @@
+package securestore
+
+import (
+ "github.com/caarlos0/env"
+ "github.com/devtron-labs/common-lib/utils"
+ "github.com/devtron-labs/common-lib/utils/bean"
+ "github.com/go-pg/pg"
+ "log"
+)
+
+func NewAttributesRepositoryImplForDatabase(databaseName string) (*AttributesRepositoryImpl, error) {
+ dbConn, err := newDbConnection(databaseName)
+ if err != nil {
+ return nil, err
+ }
+ return NewAttributesRepositoryImpl(dbConn), nil
+}
+
+type config struct {
+ Addr string `env:"PG_ADDR" envDefault:"127.0.0.1"`
+ Port string `env:"PG_PORT" envDefault:"5432"`
+ User string `env:"PG_USER" envDefault:""`
+ Password string `env:"PG_PASSWORD" envDefault:"" secretData:"-"`
+ Database string `env:"PG_DATABASE" envDefault:"orchestrator"`
+ ApplicationName string `env:"APP" envDefault:"orchestrator"`
+ bean.PgQueryMonitoringConfig
+ LocalDev bool `env:"RUNTIME_CONFIG_LOCAL_DEV" envDefault:"false"`
+}
+
+func getDbConfig(databaseName string) (*config, error) {
+ cfg := &config{}
+ err := env.Parse(cfg)
+ if err != nil {
+ return cfg, err
+ }
+ monitoringCfg, err := bean.GetPgQueryMonitoringConfig(cfg.ApplicationName)
+ if err != nil {
+ return cfg, err
+ }
+ cfg.PgQueryMonitoringConfig = monitoringCfg
+ if !cfg.LocalDev {
+ cfg.Database = databaseName //overriding database
+ }
+ return cfg, err
+}
+
+func newDbConnection(databaseName string) (*pg.DB, error) {
+ cfg, err := getDbConfig(databaseName)
+ if err != nil {
+ return nil, err
+ }
+ options := pg.Options{
+ Addr: cfg.Addr + ":" + cfg.Port,
+ User: cfg.User,
+ Password: cfg.Password,
+ Database: cfg.Database,
+ ApplicationName: cfg.ApplicationName,
+ }
+ dbConnection := pg.Connect(&options)
+ //check db connection
+ var test string
+ _, err = dbConnection.QueryOne(&test, `SELECT 1`)
+
+ if err != nil {
+ log.Println("error in connecting orchestrator db ", "err", err)
+ return nil, err
+ } else {
+ log.Println("connected with orchestrator db")
+ }
+ //--------------
+ if cfg.LogSlowQuery {
+ dbConnection.OnQueryProcessed(utils.GetPGPostQueryProcessor(cfg.PgQueryMonitoringConfig))
+ }
+ return dbConnection, err
+}
diff --git a/git-sensor/vendor/github.com/devtron-labs/common-lib/securestore/AttributesRepository.go b/git-sensor/vendor/github.com/devtron-labs/common-lib/securestore/AttributesRepository.go
new file mode 100644
index 000000000..eadf7a8f4
--- /dev/null
+++ b/git-sensor/vendor/github.com/devtron-labs/common-lib/securestore/AttributesRepository.go
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 2020-2024. Devtron Inc.
+ */
+
+package securestore
+
+import (
+ sql2 "github.com/devtron-labs/common-lib/utils/sql"
+ "github.com/go-pg/pg"
+ "time"
+)
+
+const ENCRYPTION_KEY string = "encryptionKey" // AES-256 encryption key for sensitive data
+
+type Attributes struct {
+ tableName struct{} `sql:"attributes" pg:",discard_unknown_columns"`
+ Id int `sql:"id,pk"`
+ Key string `sql:"key,notnull"`
+ Value string `sql:"value,notnull"`
+ Active bool `sql:"active, notnull"`
+ sql2.AuditLog
+}
+
+type AttributesRepository interface {
+ Save(model *Attributes, tx *pg.Tx) (*Attributes, error)
+ Update(model *Attributes, tx *pg.Tx) error
+ FindByKey(key string) (*Attributes, error)
+ GetConnection() (dbConnection *pg.DB)
+ SaveEncryptionKeyIfNotExists(value string) error
+ GetEncryptionKey() (string, error)
+}
+
+type AttributesRepositoryImpl struct {
+ dbConnection *pg.DB
+}
+
+func NewAttributesRepositoryImpl(dbConnection *pg.DB) *AttributesRepositoryImpl {
+ return &AttributesRepositoryImpl{dbConnection: dbConnection}
+}
+
+func (impl *AttributesRepositoryImpl) GetConnection() (dbConnection *pg.DB) {
+ return impl.dbConnection
+}
+
+func (repo AttributesRepositoryImpl) Save(model *Attributes, tx *pg.Tx) (*Attributes, error) {
+ err := tx.Insert(model)
+ if err != nil {
+ return model, err
+ }
+ return model, nil
+}
+
+func (repo AttributesRepositoryImpl) Update(model *Attributes, tx *pg.Tx) error {
+ err := tx.Update(model)
+ if err != nil {
+ return err
+ }
+ return nil
+}
+
+func (repo AttributesRepositoryImpl) FindByKey(key string) (*Attributes, error) {
+ model := &Attributes{}
+ err := repo.dbConnection.
+ Model(model).
+ Where("key = ?", key).
+ Where("active = ?", true).
+ Select()
+ if err != nil {
+ return model, err
+ }
+ return model, nil
+}
+
+// SaveEncryptionKeyIfNotExists saves an encryption key in the attributes table if not exists
+func (repo AttributesRepositoryImpl) SaveEncryptionKeyIfNotExists(value string) error {
+ dbConnection := repo.GetConnection()
+ tx, err := dbConnection.Begin()
+ if err != nil {
+ return err
+ }
+ defer tx.Rollback()
+
+ //deleting all keys if exists for safe side
+ _, err = tx.Model(&Attributes{}).Where("key = ?", ENCRYPTION_KEY).Delete()
+ // Create new encryption key entry
+ model := &Attributes{
+ Key: ENCRYPTION_KEY,
+ Value: value,
+ Active: true,
+ AuditLog: sql2.AuditLog{
+ CreatedBy: 1,
+ UpdatedBy: 1,
+ CreatedOn: time.Now(),
+ UpdatedOn: time.Now(),
+ },
+ }
+ _, err = repo.Save(model, tx)
+ if err != nil {
+ return err
+ }
+ return tx.Commit()
+}
+
+// GetEncryptionKey retrieves the active encryption key from the attributes table
+func (repo AttributesRepositoryImpl) GetEncryptionKey() (string, error) {
+ model, err := repo.FindByKey(ENCRYPTION_KEY)
+ if err != nil {
+ return "", err
+ }
+ return model.Value, nil
+}
diff --git a/git-sensor/vendor/github.com/devtron-labs/common-lib/securestore/EncryptionKeyService.go b/git-sensor/vendor/github.com/devtron-labs/common-lib/securestore/EncryptionKeyService.go
new file mode 100644
index 000000000..f8a37acec
--- /dev/null
+++ b/git-sensor/vendor/github.com/devtron-labs/common-lib/securestore/EncryptionKeyService.go
@@ -0,0 +1,136 @@
+/*
+ * Copyright (c) 2024. Devtron Inc.
+ */
+
+package securestore
+
+import (
+ "crypto/rand"
+ "encoding/hex"
+ "fmt"
+ "github.com/go-pg/pg"
+ log "github.com/sirupsen/logrus"
+)
+
+func SetEncryptionKey() error {
+ repo, err := NewAttributesRepositoryImplForDatabase("orchestrator") //hardcoded for orchestrator as need to pick a common key for every service
+ if err != nil {
+ log.Println("error in creating attributes repository", "err", err)
+ return err
+ }
+ encryptionService := NewEncryptionKeyServiceImpl(repo)
+ err = encryptionService.CreateAndStoreEncryptionKey()
+ if err != nil {
+ log.Println("error in creating and storing encryption key", "err", err)
+ return err
+ }
+ return nil
+}
+
+type EncryptionKeyService interface {
+ // CreateAndStoreEncryptionKey generates a new AES-256 encryption key and stores it in the attributes repository
+ CreateAndStoreEncryptionKey() error
+
+ // RotateEncryptionKey generates a new encryption key and stores it (deactivating the old one)
+ RotateEncryptionKey(userId int32) (string, error)
+
+ // GenerateEncryptionKey generates a new AES-256 encryption key (32 bytes)
+ GenerateEncryptionKey() (string, error)
+
+ GetEncryptionKey() (string, error)
+}
+
+type EncryptionKeyServiceImpl struct {
+ attributesRepository AttributesRepository
+}
+
+func NewEncryptionKeyServiceImpl(attributesRepository AttributesRepository) *EncryptionKeyServiceImpl {
+ impl := &EncryptionKeyServiceImpl{
+ attributesRepository: attributesRepository,
+ }
+ return impl
+}
+
+// GenerateEncryptionKey generates a new AES-256 encryption key (32 bytes = 256 bits)
+func (impl *EncryptionKeyServiceImpl) GenerateEncryptionKey() (string, error) {
+ // Generate 32 random bytes for AES-256
+ key := make([]byte, 32)
+ _, err := rand.Read(key)
+ if err != nil {
+ log.Error("error generating random encryption key", "err", err)
+ return "", fmt.Errorf("failed to generate encryption key: %w", err)
+ }
+ // Encode to hex string for storage
+ keyHex := hex.EncodeToString(key)
+ return keyHex, nil
+}
+
+// CreateAndStoreEncryptionKey generates a new AES-256 encryption key and stores it in the attributes repository
+func (impl *EncryptionKeyServiceImpl) CreateAndStoreEncryptionKey() error {
+ // Check if encryption key already exists
+ encryptionKeyModel, err := impl.attributesRepository.FindByKey(ENCRYPTION_KEY)
+ if err != nil && err != pg.ErrNoRows {
+ log.Error("error checking for existing encryption key", "err", err)
+ return err
+ }
+ var encryptionKeyEncoded string
+ if encryptionKeyModel != nil && encryptionKeyModel.Id > 0 && len(encryptionKeyModel.Value) > 0 {
+ encryptionKeyEncoded = encryptionKeyModel.Value
+ log.Println("encryption key already exists", "keyId", encryptionKeyModel.Id)
+ } else {
+ // Generate new encryption key
+ encryptionKeyNew, err := impl.GenerateEncryptionKey()
+ if err != nil {
+ return err
+ }
+ // Store in repository
+ err = impl.attributesRepository.SaveEncryptionKeyIfNotExists(encryptionKeyNew)
+ if err != nil {
+ log.Error("error storing encryption key", "err", err)
+ return fmt.Errorf("failed to store encryption key: %w", err)
+ }
+ encryptionKeyEncoded = encryptionKeyNew
+ log.Println("Successfully created and stored encryption key")
+ }
+
+ encryptionKey, err = hex.DecodeString(encryptionKeyEncoded)
+ if err != nil || len(encryptionKey) != 32 {
+ return fmt.Errorf("encryptionKey is incorrect : %v", err)
+ }
+ return nil
+}
+
+// RotateEncryptionKey generates a new encryption key and stores it (deactivating the old one)
+func (impl *EncryptionKeyServiceImpl) RotateEncryptionKey(userId int32) (string, error) {
+ log.Println("Rotating encryption key", "userId", userId)
+
+ // Generate new encryption key
+ newEncryptionKey, err := impl.GenerateEncryptionKey()
+ if err != nil {
+ return "", err
+ }
+
+ // Store in repository (this will deactivate the old key)
+ err = impl.attributesRepository.SaveEncryptionKeyIfNotExists(newEncryptionKey)
+ if err != nil {
+ log.Error("error rotating encryption key", "err", err)
+ return "", fmt.Errorf("failed to rotate encryption key: %w", err)
+ }
+ //TODO: also need to rotate encryption's already done
+ log.Println("Successfully rotated encryption key", "userId", userId)
+ return newEncryptionKey, nil
+}
+
+// GetEncryptionKey retrieves the active encryption key from the repository
+func (impl *EncryptionKeyServiceImpl) GetEncryptionKey() (string, error) {
+ key, err := impl.attributesRepository.GetEncryptionKey()
+ if err != nil {
+ if err == pg.ErrNoRows {
+ log.Error("encryption key not found in repository")
+ return "", fmt.Errorf("encryption key not found, please create one first")
+ }
+ log.Error("error retrieving encryption key", "err", err)
+ return "", err
+ }
+ return key, nil
+}
diff --git a/git-sensor/vendor/github.com/devtron-labs/common-lib/securestore/common.go b/git-sensor/vendor/github.com/devtron-labs/common-lib/securestore/common.go
new file mode 100644
index 000000000..4444765e3
--- /dev/null
+++ b/git-sensor/vendor/github.com/devtron-labs/common-lib/securestore/common.go
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2024. Devtron Inc.
+ */
+
+package securestore
+
+import (
+ "crypto/aes"
+ "crypto/cipher"
+ "crypto/rand"
+ "encoding/base64"
+ "encoding/json"
+ "errors"
+ "fmt"
+ "github.com/go-pg/pg/types"
+ "io"
+)
+
+var decryptionFailErr = fmt.Errorf("Decryption failed")
+
+func DidDecryptionFail(err error) bool {
+ return errors.Is(err, decryptionFailErr)
+}
+
+var encryptionKey []byte
+
+func encrypt(data []byte) (string, error) {
+ if len(data) == 0 {
+ return "", nil
+ }
+ block, err := aes.NewCipher(encryptionKey)
+ if err != nil {
+ return "", err
+ }
+ aesGCM, err := cipher.NewGCM(block)
+ if err != nil {
+ return "", err
+ }
+ nonce := make([]byte, aesGCM.NonceSize())
+ if _, err := io.ReadFull(rand.Reader, nonce); err != nil {
+ return "", err
+ }
+ ciphertext := aesGCM.Seal(nonce, nonce, data, nil)
+ return base64.StdEncoding.EncodeToString(ciphertext), nil
+}
+
+func decrypt(cipherBase64 string) (string, error) {
+ // Try decrypting (normal encrypted flow)
+ cipherData, err := base64.StdEncoding.DecodeString(cipherBase64)
+ if err == nil {
+ block, err := aes.NewCipher(encryptionKey)
+ if err != nil {
+ return "", err
+ }
+ aesGCM, err := cipher.NewGCM(block)
+ if err != nil {
+ return "", err
+ }
+ nonceSize := aesGCM.NonceSize()
+ if len(cipherData) >= nonceSize {
+ nonce, ciphertext := cipherData[:nonceSize], cipherData[nonceSize:]
+ plainText, err := aesGCM.Open(nil, nonce, ciphertext, nil)
+ if err == nil {
+ return string(plainText), nil // Successfully decrypted
+ }
+ }
+ }
+ return cipherBase64, decryptionFailErr
+}
+
+// AppendValue : can be used for auto encryption of fields but is only supported in go-pg/v10. Not being used anywhere as of now, to be tested when start using.
+func (e EncryptedMap) AppendValue(b []byte, quote int) ([]byte, error) {
+ jsonBytes, err := json.Marshal(e)
+ if err != nil {
+ return nil, err
+ }
+
+ encryptedString, err := encrypt(jsonBytes)
+ if err != nil {
+ return nil, err
+ }
+
+ return types.AppendString(b, encryptedString, quote), nil
+}
diff --git a/git-sensor/vendor/github.com/devtron-labs/common-lib/securestore/map.go b/git-sensor/vendor/github.com/devtron-labs/common-lib/securestore/map.go
new file mode 100644
index 000000000..dd9c25846
--- /dev/null
+++ b/git-sensor/vendor/github.com/devtron-labs/common-lib/securestore/map.go
@@ -0,0 +1,73 @@
+package securestore
+
+import (
+ "encoding/json"
+ "fmt"
+)
+
+type EncryptedMap map[string]string
+
+const (
+ ENCRYPTED_KEY = "encrypted_data"
+)
+
+func EncryptMap(m EncryptedMap) (map[string]string, error) {
+ bytesM, err := json.Marshal(m)
+ if err != nil {
+ return nil, err
+ }
+ encryptedData, err := encrypt(bytesM)
+ if err != nil {
+ return nil, err
+ }
+ return EncryptedMap{ENCRYPTED_KEY: encryptedData}, nil
+}
+
+func decryptMap(mCipher []byte) (map[string]string, error) {
+ var m map[string]string
+ err := json.Unmarshal(mCipher, &m)
+ if err != nil {
+ return nil, err
+ }
+ if len(m[ENCRYPTED_KEY]) > 0 {
+ decryptedMapBytes, err := decrypt(m[ENCRYPTED_KEY])
+ if err != nil && !DidDecryptionFail(err) {
+ return nil, err
+ }
+ if err == nil {
+ var decryptedMap map[string]string
+ err = json.Unmarshal([]byte(decryptedMapBytes), &decryptedMap)
+ if err != nil {
+ return nil, err
+ }
+ return decryptedMap, nil
+ }
+ } else {
+ // Fallback: maybe it's just raw JSON
+ // Validate that it's a valid JSON map[string]string
+ // Neither decrypted nor valid plaintext JSON
+ return m, nil
+ }
+ return nil, fmt.Errorf("decryption failed and data is not valid plaintext JSON")
+}
+
+func (e *EncryptedMap) Scan(value interface{}) error {
+ if value == nil {
+ return nil
+ }
+ var encrypted []byte
+ switch v := value.(type) {
+ case string:
+ encrypted = []byte(v)
+ case []byte:
+ encrypted = v
+ default:
+ return fmt.Errorf("unsupported type: %T", v)
+ }
+ var err error
+ *e, err = decryptMap(encrypted)
+ if err != nil {
+ return err
+ }
+ return nil
+}
diff --git a/git-sensor/vendor/github.com/devtron-labs/common-lib/securestore/strings.go b/git-sensor/vendor/github.com/devtron-labs/common-lib/securestore/strings.go
new file mode 100644
index 000000000..e7c5128b2
--- /dev/null
+++ b/git-sensor/vendor/github.com/devtron-labs/common-lib/securestore/strings.go
@@ -0,0 +1,60 @@
+package securestore
+
+import (
+ "fmt"
+)
+
+type EncryptedString string
+
+func (e *EncryptedString) String() string {
+ return string(*e)
+}
+
+func ToEncryptedString(s string) EncryptedString {
+ return EncryptedString(s)
+}
+
+func EncryptString(data string) (EncryptedString, error) {
+ encryptedStr, err := encrypt([]byte(data))
+ if err != nil {
+ return "", err
+ }
+ return EncryptedString(encryptedStr), nil
+}
+
+func decryptString(cipherBase64 string) (string, error) {
+ decryptedBytes, err := decrypt(cipherBase64)
+ if err != nil && !DidDecryptionFail(err) {
+ return "", err
+ }
+ // Fallback: decrypting failed, considering it as just normal string
+ if DidDecryptionFail(err) {
+ return cipherBase64, nil
+ } else {
+ return decryptedBytes, nil
+ }
+}
+
+func (e *EncryptedString) Scan(value interface{}) error {
+ if value == nil {
+ return nil
+ }
+ var encrypted []byte
+ switch v := value.(type) {
+ case string:
+ encrypted = []byte(v)
+ case []byte:
+ encrypted = v
+ default:
+ return fmt.Errorf("unsupported type: %T", v)
+ }
+ decryptedBytes, err := decryptString(string(encrypted))
+ if err != nil {
+ return err
+ }
+ if decryptedBytes == "" {
+ return nil
+ }
+ *e = EncryptedString(decryptedBytes)
+ return nil
+}
diff --git a/git-sensor/vendor/github.com/devtron-labs/common-lib/utils/sql/AuditLog.go b/git-sensor/vendor/github.com/devtron-labs/common-lib/utils/sql/AuditLog.go
new file mode 100644
index 000000000..fb3a38e79
--- /dev/null
+++ b/git-sensor/vendor/github.com/devtron-labs/common-lib/utils/sql/AuditLog.go
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2020-2024. Devtron 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 sql
+
+import (
+ "time"
+)
+
+type AuditLog struct {
+ CreatedOn time.Time `sql:"created_on,type:timestamptz"`
+ CreatedBy int32 `sql:"created_by,type:integer"`
+ UpdatedOn time.Time `sql:"updated_on,type:timestamptz"`
+ UpdatedBy int32 `sql:"updated_by,type:integer"`
+}
+
+func NewDefaultAuditLog(userId int32) AuditLog {
+ return AuditLog{
+ CreatedOn: time.Now(),
+ CreatedBy: userId,
+ UpdatedOn: time.Now(),
+ UpdatedBy: userId,
+ }
+}
+
+// CreateAuditLog can be used by any repository to create AuditLog for insert operation
+func (model *AuditLog) CreateAuditLog(userId int32) {
+ model.CreatedOn = time.Now()
+ model.UpdatedOn = time.Now()
+ model.CreatedBy = userId
+ model.UpdatedBy = userId
+}
+
+// UpdateAuditLog can be used by any repository to update AuditLog for update operation
+func (model *AuditLog) UpdateAuditLog(userId int32) {
+ model.UpdatedOn = time.Now()
+ model.UpdatedBy = userId
+}
diff --git a/git-sensor/vendor/github.com/devtron-labs/common-lib/utils/sql/TransactionWrapper.go b/git-sensor/vendor/github.com/devtron-labs/common-lib/utils/sql/TransactionWrapper.go
new file mode 100644
index 000000000..3c797e1e1
--- /dev/null
+++ b/git-sensor/vendor/github.com/devtron-labs/common-lib/utils/sql/TransactionWrapper.go
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2024. Devtron 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 sql
+
+import "github.com/go-pg/pg"
+
+type TransactionWrapper interface {
+ StartTx() (*pg.Tx, error)
+ RollbackTx(tx *pg.Tx) error
+ CommitTx(tx *pg.Tx) error
+}
+
+type TransactionUtilImpl struct {
+ dbConnection *pg.DB
+}
+
+func NewTransactionUtilImpl(db *pg.DB) *TransactionUtilImpl {
+ return &TransactionUtilImpl{
+ dbConnection: db,
+ }
+}
+func (impl *TransactionUtilImpl) RollbackTx(tx *pg.Tx) error {
+ return tx.Rollback()
+}
+func (impl *TransactionUtilImpl) CommitTx(tx *pg.Tx) error {
+ return tx.Commit()
+}
+func (impl *TransactionUtilImpl) StartTx() (*pg.Tx, error) {
+ return impl.dbConnection.Begin()
+}
diff --git a/git-sensor/vendor/github.com/devtron-labs/common-lib/utils/sql/connection.go b/git-sensor/vendor/github.com/devtron-labs/common-lib/utils/sql/connection.go
new file mode 100644
index 000000000..fa6858e5d
--- /dev/null
+++ b/git-sensor/vendor/github.com/devtron-labs/common-lib/utils/sql/connection.go
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2020-2024. Devtron 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 sql
+
+import (
+ "github.com/devtron-labs/common-lib/utils"
+ "github.com/devtron-labs/common-lib/utils/bean"
+ "go.uber.org/zap"
+ "reflect"
+ "time"
+
+ "github.com/caarlos0/env"
+ "github.com/go-pg/pg"
+)
+
+// CATEGORY=POSTGRES
+type Config struct {
+ Addr string `env:"PG_ADDR" envDefault:"127.0.0.1" description:"address of postgres service" example:"postgresql-postgresql.devtroncd" deprecated:"false"`
+ Port string `env:"PG_PORT" envDefault:"5432" description:"port of postgresql service" example:"5432"`
+ User string `env:"PG_USER" envDefault:"" description:"user for postgres" example:"postgres"`
+ Password string `env:"PG_PASSWORD" envDefault:"" secretData:"-" description:"password for postgres, associated with PG_USER" example:"confidential ;)"`
+ Database string `env:"PG_DATABASE" envDefault:"orchestrator" description:"postgres database to be made connection with" example:"orchestrator, casbin, git_sensor, lens"`
+ CasbinDatabase string `env:"CASBIN_DATABASE" envDefault:"casbin""`
+ ApplicationName string `env:"APP" envDefault:"orchestrator" description:"Application name"`
+ ReadTimeout int64 `env:"PG_READ_TIMEOUT" envDefault:"30"`
+ WriteTimeout int64 `env:"PG_WRITE_TIMEOUT" envDefault:"30"`
+ bean.PgQueryMonitoringConfig
+}
+
+func GetConfig() (*Config, error) {
+ cfg := &Config{}
+ err := env.Parse(cfg)
+ if err != nil {
+ return cfg, err
+ }
+ monitoringCfg, err := bean.GetPgQueryMonitoringConfig(cfg.ApplicationName)
+ if err != nil {
+ return cfg, err
+ }
+ cfg.PgQueryMonitoringConfig = monitoringCfg
+ return cfg, err
+}
+
+func NewDbConnection(cfg *Config, logger *zap.SugaredLogger) (*pg.DB, error) {
+ options := pg.Options{
+ Addr: cfg.Addr + ":" + cfg.Port,
+ User: cfg.User,
+ Password: cfg.Password,
+ Database: cfg.Database,
+ ApplicationName: cfg.ApplicationName,
+ ReadTimeout: time.Duration(cfg.ReadTimeout) * time.Second,
+ WriteTimeout: time.Duration(cfg.WriteTimeout) * time.Second,
+ }
+ dbConnection := pg.Connect(&options)
+ // check db connection
+ var test string
+ _, err := dbConnection.QueryOne(&test, `SELECT 1`)
+
+ if err != nil {
+ logger.Errorw("error in connecting db ", "db", obfuscateSecretTags(cfg), "err", err)
+ return nil, err
+ } else {
+ logger.Infow("connected with db", "db", obfuscateSecretTags(cfg))
+ }
+
+ // --------------
+ dbConnection.OnQueryProcessed(utils.GetPGPostQueryProcessor(cfg.PgQueryMonitoringConfig))
+ return dbConnection, err
+}
+
+func obfuscateSecretTags(cfg interface{}) interface{} {
+
+ cfgDpl := reflect.New(reflect.ValueOf(cfg).Elem().Type()).Interface()
+ cfgDplElm := reflect.ValueOf(cfgDpl).Elem()
+ t := cfgDplElm.Type()
+ for i := 0; i < t.NumField(); i++ {
+ if _, ok := t.Field(i).Tag.Lookup("secretData"); ok {
+ cfgDplElm.Field(i).SetString("********")
+ } else {
+ cfgDplElm.Field(i).Set(reflect.ValueOf(cfg).Elem().Field(i))
+ }
+ }
+ return cfgDpl
+}
+
+/*type DbConnectionHolder struct {
+ connection *pg.DB
+}
+
+func (holder *DbConnectionHolder) CloseConnection() error {
+ return holder.connection.Close()
+}*/
diff --git a/git-sensor/vendor/github.com/devtron-labs/common-lib/utils/sql/wire_sql.go b/git-sensor/vendor/github.com/devtron-labs/common-lib/utils/sql/wire_sql.go
new file mode 100644
index 000000000..32aee8f5b
--- /dev/null
+++ b/git-sensor/vendor/github.com/devtron-labs/common-lib/utils/sql/wire_sql.go
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2024. Devtron 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 sql
+
+import (
+ "github.com/google/wire"
+)
+
+var PgSqlWireSet = wire.NewSet(
+ GetConfig,
+ NewDbConnection,
+)
diff --git a/git-sensor/vendor/github.com/felixge/httpsnoop/.gitignore b/git-sensor/vendor/github.com/felixge/httpsnoop/.gitignore
deleted file mode 100644
index e69de29bb..000000000
diff --git a/git-sensor/vendor/github.com/felixge/httpsnoop/LICENSE.txt b/git-sensor/vendor/github.com/felixge/httpsnoop/LICENSE.txt
deleted file mode 100644
index e028b46a9..000000000
--- a/git-sensor/vendor/github.com/felixge/httpsnoop/LICENSE.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-Copyright (c) 2016 Felix Geisendörfer (felix@debuggable.com)
-
- Permission is hereby granted, free of charge, to any person obtaining a copy
- of this software and associated documentation files (the "Software"), to deal
- in the Software without restriction, including without limitation the rights
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- copies of the Software, and to permit persons to whom the Software is
- furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in
- all copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- THE SOFTWARE.
diff --git a/git-sensor/vendor/github.com/felixge/httpsnoop/Makefile b/git-sensor/vendor/github.com/felixge/httpsnoop/Makefile
deleted file mode 100644
index 4e12afdd9..000000000
--- a/git-sensor/vendor/github.com/felixge/httpsnoop/Makefile
+++ /dev/null
@@ -1,10 +0,0 @@
-.PHONY: ci generate clean
-
-ci: clean generate
- go test -race -v ./...
-
-generate:
- go generate .
-
-clean:
- rm -rf *_generated*.go
diff --git a/git-sensor/vendor/github.com/felixge/httpsnoop/README.md b/git-sensor/vendor/github.com/felixge/httpsnoop/README.md
deleted file mode 100644
index cf6b42f3d..000000000
--- a/git-sensor/vendor/github.com/felixge/httpsnoop/README.md
+++ /dev/null
@@ -1,95 +0,0 @@
-# httpsnoop
-
-Package httpsnoop provides an easy way to capture http related metrics (i.e.
-response time, bytes written, and http status code) from your application's
-http.Handlers.
-
-Doing this requires non-trivial wrapping of the http.ResponseWriter interface,
-which is also exposed for users interested in a more low-level API.
-
-[](https://pkg.go.dev/github.com/felixge/httpsnoop)
-[](https://github.com/felixge/httpsnoop/actions/workflows/main.yaml)
-
-## Usage Example
-
-```go
-// myH is your app's http handler, perhaps a http.ServeMux or similar.
-var myH http.Handler
-// wrappedH wraps myH in order to log every request.
-wrappedH := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- m := httpsnoop.CaptureMetrics(myH, w, r)
- log.Printf(
- "%s %s (code=%d dt=%s written=%d)",
- r.Method,
- r.URL,
- m.Code,
- m.Duration,
- m.Written,
- )
-})
-http.ListenAndServe(":8080", wrappedH)
-```
-
-## Why this package exists
-
-Instrumenting an application's http.Handler is surprisingly difficult.
-
-However if you google for e.g. "capture ResponseWriter status code" you'll find
-lots of advise and code examples that suggest it to be a fairly trivial
-undertaking. Unfortunately everything I've seen so far has a high chance of
-breaking your application.
-
-The main problem is that a `http.ResponseWriter` often implements additional
-interfaces such as `http.Flusher`, `http.CloseNotifier`, `http.Hijacker`, `http.Pusher`, and
-`io.ReaderFrom`. So the naive approach of just wrapping `http.ResponseWriter`
-in your own struct that also implements the `http.ResponseWriter` interface
-will hide the additional interfaces mentioned above. This has a high change of
-introducing subtle bugs into any non-trivial application.
-
-Another approach I've seen people take is to return a struct that implements
-all of the interfaces above. However, that's also problematic, because it's
-difficult to fake some of these interfaces behaviors when the underlying
-`http.ResponseWriter` doesn't have an implementation. It's also dangerous,
-because an application may choose to operate differently, merely because it
-detects the presence of these additional interfaces.
-
-This package solves this problem by checking which additional interfaces a
-`http.ResponseWriter` implements, returning a wrapped version implementing the
-exact same set of interfaces.
-
-Additionally this package properly handles edge cases such as `WriteHeader` not
-being called, or called more than once, as well as concurrent calls to
-`http.ResponseWriter` methods, and even calls happening after the wrapped
-`ServeHTTP` has already returned.
-
-Unfortunately this package is not perfect either. It's possible that it is
-still missing some interfaces provided by the go core (let me know if you find
-one), and it won't work for applications adding their own interfaces into the
-mix. You can however use `httpsnoop.Unwrap(w)` to access the underlying
-`http.ResponseWriter` and type-assert the result to its other interfaces.
-
-However, hopefully the explanation above has sufficiently scared you of rolling
-your own solution to this problem. httpsnoop may still break your application,
-but at least it tries to avoid it as much as possible.
-
-Anyway, the real problem here is that smuggling additional interfaces inside
-`http.ResponseWriter` is a problematic design choice, but it probably goes as
-deep as the Go language specification itself. But that's okay, I still prefer
-Go over the alternatives ;).
-
-## Performance
-
-```
-BenchmarkBaseline-8 20000 94912 ns/op
-BenchmarkCaptureMetrics-8 20000 95461 ns/op
-```
-
-As you can see, using `CaptureMetrics` on a vanilla http.Handler introduces an
-overhead of ~500 ns per http request on my machine. However, the margin of
-error appears to be larger than that, therefor it should be reasonable to
-assume that the overhead introduced by `CaptureMetrics` is absolutely
-negligible.
-
-## License
-
-MIT
diff --git a/git-sensor/vendor/github.com/felixge/httpsnoop/capture_metrics.go b/git-sensor/vendor/github.com/felixge/httpsnoop/capture_metrics.go
deleted file mode 100644
index bec7b71b3..000000000
--- a/git-sensor/vendor/github.com/felixge/httpsnoop/capture_metrics.go
+++ /dev/null
@@ -1,86 +0,0 @@
-package httpsnoop
-
-import (
- "io"
- "net/http"
- "time"
-)
-
-// Metrics holds metrics captured from CaptureMetrics.
-type Metrics struct {
- // Code is the first http response code passed to the WriteHeader func of
- // the ResponseWriter. If no such call is made, a default code of 200 is
- // assumed instead.
- Code int
- // Duration is the time it took to execute the handler.
- Duration time.Duration
- // Written is the number of bytes successfully written by the Write or
- // ReadFrom function of the ResponseWriter. ResponseWriters may also write
- // data to their underlaying connection directly (e.g. headers), but those
- // are not tracked. Therefor the number of Written bytes will usually match
- // the size of the response body.
- Written int64
-}
-
-// CaptureMetrics wraps the given hnd, executes it with the given w and r, and
-// returns the metrics it captured from it.
-func CaptureMetrics(hnd http.Handler, w http.ResponseWriter, r *http.Request) Metrics {
- return CaptureMetricsFn(w, func(ww http.ResponseWriter) {
- hnd.ServeHTTP(ww, r)
- })
-}
-
-// CaptureMetricsFn wraps w and calls fn with the wrapped w and returns the
-// resulting metrics. This is very similar to CaptureMetrics (which is just
-// sugar on top of this func), but is a more usable interface if your
-// application doesn't use the Go http.Handler interface.
-func CaptureMetricsFn(w http.ResponseWriter, fn func(http.ResponseWriter)) Metrics {
- m := Metrics{Code: http.StatusOK}
- m.CaptureMetrics(w, fn)
- return m
-}
-
-// CaptureMetrics wraps w and calls fn with the wrapped w and updates
-// Metrics m with the resulting metrics. This is similar to CaptureMetricsFn,
-// but allows one to customize starting Metrics object.
-func (m *Metrics) CaptureMetrics(w http.ResponseWriter, fn func(http.ResponseWriter)) {
- var (
- start = time.Now()
- headerWritten bool
- hooks = Hooks{
- WriteHeader: func(next WriteHeaderFunc) WriteHeaderFunc {
- return func(code int) {
- next(code)
-
- if !(code >= 100 && code <= 199) && !headerWritten {
- m.Code = code
- headerWritten = true
- }
- }
- },
-
- Write: func(next WriteFunc) WriteFunc {
- return func(p []byte) (int, error) {
- n, err := next(p)
-
- m.Written += int64(n)
- headerWritten = true
- return n, err
- }
- },
-
- ReadFrom: func(next ReadFromFunc) ReadFromFunc {
- return func(src io.Reader) (int64, error) {
- n, err := next(src)
-
- headerWritten = true
- m.Written += n
- return n, err
- }
- },
- }
- )
-
- fn(Wrap(w, hooks))
- m.Duration += time.Since(start)
-}
diff --git a/git-sensor/vendor/github.com/felixge/httpsnoop/docs.go b/git-sensor/vendor/github.com/felixge/httpsnoop/docs.go
deleted file mode 100644
index 203c35b3c..000000000
--- a/git-sensor/vendor/github.com/felixge/httpsnoop/docs.go
+++ /dev/null
@@ -1,10 +0,0 @@
-// Package httpsnoop provides an easy way to capture http related metrics (i.e.
-// response time, bytes written, and http status code) from your application's
-// http.Handlers.
-//
-// Doing this requires non-trivial wrapping of the http.ResponseWriter
-// interface, which is also exposed for users interested in a more low-level
-// API.
-package httpsnoop
-
-//go:generate go run codegen/main.go
diff --git a/git-sensor/vendor/github.com/felixge/httpsnoop/wrap_generated_gteq_1.8.go b/git-sensor/vendor/github.com/felixge/httpsnoop/wrap_generated_gteq_1.8.go
deleted file mode 100644
index 101cedde6..000000000
--- a/git-sensor/vendor/github.com/felixge/httpsnoop/wrap_generated_gteq_1.8.go
+++ /dev/null
@@ -1,436 +0,0 @@
-// +build go1.8
-// Code generated by "httpsnoop/codegen"; DO NOT EDIT.
-
-package httpsnoop
-
-import (
- "bufio"
- "io"
- "net"
- "net/http"
-)
-
-// HeaderFunc is part of the http.ResponseWriter interface.
-type HeaderFunc func() http.Header
-
-// WriteHeaderFunc is part of the http.ResponseWriter interface.
-type WriteHeaderFunc func(code int)
-
-// WriteFunc is part of the http.ResponseWriter interface.
-type WriteFunc func(b []byte) (int, error)
-
-// FlushFunc is part of the http.Flusher interface.
-type FlushFunc func()
-
-// CloseNotifyFunc is part of the http.CloseNotifier interface.
-type CloseNotifyFunc func() <-chan bool
-
-// HijackFunc is part of the http.Hijacker interface.
-type HijackFunc func() (net.Conn, *bufio.ReadWriter, error)
-
-// ReadFromFunc is part of the io.ReaderFrom interface.
-type ReadFromFunc func(src io.Reader) (int64, error)
-
-// PushFunc is part of the http.Pusher interface.
-type PushFunc func(target string, opts *http.PushOptions) error
-
-// Hooks defines a set of method interceptors for methods included in
-// http.ResponseWriter as well as some others. You can think of them as
-// middleware for the function calls they target. See Wrap for more details.
-type Hooks struct {
- Header func(HeaderFunc) HeaderFunc
- WriteHeader func(WriteHeaderFunc) WriteHeaderFunc
- Write func(WriteFunc) WriteFunc
- Flush func(FlushFunc) FlushFunc
- CloseNotify func(CloseNotifyFunc) CloseNotifyFunc
- Hijack func(HijackFunc) HijackFunc
- ReadFrom func(ReadFromFunc) ReadFromFunc
- Push func(PushFunc) PushFunc
-}
-
-// Wrap returns a wrapped version of w that provides the exact same interface
-// as w. Specifically if w implements any combination of:
-//
-// - http.Flusher
-// - http.CloseNotifier
-// - http.Hijacker
-// - io.ReaderFrom
-// - http.Pusher
-//
-// The wrapped version will implement the exact same combination. If no hooks
-// are set, the wrapped version also behaves exactly as w. Hooks targeting
-// methods not supported by w are ignored. Any other hooks will intercept the
-// method they target and may modify the call's arguments and/or return values.
-// The CaptureMetrics implementation serves as a working example for how the
-// hooks can be used.
-func Wrap(w http.ResponseWriter, hooks Hooks) http.ResponseWriter {
- rw := &rw{w: w, h: hooks}
- _, i0 := w.(http.Flusher)
- _, i1 := w.(http.CloseNotifier)
- _, i2 := w.(http.Hijacker)
- _, i3 := w.(io.ReaderFrom)
- _, i4 := w.(http.Pusher)
- switch {
- // combination 1/32
- case !i0 && !i1 && !i2 && !i3 && !i4:
- return struct {
- Unwrapper
- http.ResponseWriter
- }{rw, rw}
- // combination 2/32
- case !i0 && !i1 && !i2 && !i3 && i4:
- return struct {
- Unwrapper
- http.ResponseWriter
- http.Pusher
- }{rw, rw, rw}
- // combination 3/32
- case !i0 && !i1 && !i2 && i3 && !i4:
- return struct {
- Unwrapper
- http.ResponseWriter
- io.ReaderFrom
- }{rw, rw, rw}
- // combination 4/32
- case !i0 && !i1 && !i2 && i3 && i4:
- return struct {
- Unwrapper
- http.ResponseWriter
- io.ReaderFrom
- http.Pusher
- }{rw, rw, rw, rw}
- // combination 5/32
- case !i0 && !i1 && i2 && !i3 && !i4:
- return struct {
- Unwrapper
- http.ResponseWriter
- http.Hijacker
- }{rw, rw, rw}
- // combination 6/32
- case !i0 && !i1 && i2 && !i3 && i4:
- return struct {
- Unwrapper
- http.ResponseWriter
- http.Hijacker
- http.Pusher
- }{rw, rw, rw, rw}
- // combination 7/32
- case !i0 && !i1 && i2 && i3 && !i4:
- return struct {
- Unwrapper
- http.ResponseWriter
- http.Hijacker
- io.ReaderFrom
- }{rw, rw, rw, rw}
- // combination 8/32
- case !i0 && !i1 && i2 && i3 && i4:
- return struct {
- Unwrapper
- http.ResponseWriter
- http.Hijacker
- io.ReaderFrom
- http.Pusher
- }{rw, rw, rw, rw, rw}
- // combination 9/32
- case !i0 && i1 && !i2 && !i3 && !i4:
- return struct {
- Unwrapper
- http.ResponseWriter
- http.CloseNotifier
- }{rw, rw, rw}
- // combination 10/32
- case !i0 && i1 && !i2 && !i3 && i4:
- return struct {
- Unwrapper
- http.ResponseWriter
- http.CloseNotifier
- http.Pusher
- }{rw, rw, rw, rw}
- // combination 11/32
- case !i0 && i1 && !i2 && i3 && !i4:
- return struct {
- Unwrapper
- http.ResponseWriter
- http.CloseNotifier
- io.ReaderFrom
- }{rw, rw, rw, rw}
- // combination 12/32
- case !i0 && i1 && !i2 && i3 && i4:
- return struct {
- Unwrapper
- http.ResponseWriter
- http.CloseNotifier
- io.ReaderFrom
- http.Pusher
- }{rw, rw, rw, rw, rw}
- // combination 13/32
- case !i0 && i1 && i2 && !i3 && !i4:
- return struct {
- Unwrapper
- http.ResponseWriter
- http.CloseNotifier
- http.Hijacker
- }{rw, rw, rw, rw}
- // combination 14/32
- case !i0 && i1 && i2 && !i3 && i4:
- return struct {
- Unwrapper
- http.ResponseWriter
- http.CloseNotifier
- http.Hijacker
- http.Pusher
- }{rw, rw, rw, rw, rw}
- // combination 15/32
- case !i0 && i1 && i2 && i3 && !i4:
- return struct {
- Unwrapper
- http.ResponseWriter
- http.CloseNotifier
- http.Hijacker
- io.ReaderFrom
- }{rw, rw, rw, rw, rw}
- // combination 16/32
- case !i0 && i1 && i2 && i3 && i4:
- return struct {
- Unwrapper
- http.ResponseWriter
- http.CloseNotifier
- http.Hijacker
- io.ReaderFrom
- http.Pusher
- }{rw, rw, rw, rw, rw, rw}
- // combination 17/32
- case i0 && !i1 && !i2 && !i3 && !i4:
- return struct {
- Unwrapper
- http.ResponseWriter
- http.Flusher
- }{rw, rw, rw}
- // combination 18/32
- case i0 && !i1 && !i2 && !i3 && i4:
- return struct {
- Unwrapper
- http.ResponseWriter
- http.Flusher
- http.Pusher
- }{rw, rw, rw, rw}
- // combination 19/32
- case i0 && !i1 && !i2 && i3 && !i4:
- return struct {
- Unwrapper
- http.ResponseWriter
- http.Flusher
- io.ReaderFrom
- }{rw, rw, rw, rw}
- // combination 20/32
- case i0 && !i1 && !i2 && i3 && i4:
- return struct {
- Unwrapper
- http.ResponseWriter
- http.Flusher
- io.ReaderFrom
- http.Pusher
- }{rw, rw, rw, rw, rw}
- // combination 21/32
- case i0 && !i1 && i2 && !i3 && !i4:
- return struct {
- Unwrapper
- http.ResponseWriter
- http.Flusher
- http.Hijacker
- }{rw, rw, rw, rw}
- // combination 22/32
- case i0 && !i1 && i2 && !i3 && i4:
- return struct {
- Unwrapper
- http.ResponseWriter
- http.Flusher
- http.Hijacker
- http.Pusher
- }{rw, rw, rw, rw, rw}
- // combination 23/32
- case i0 && !i1 && i2 && i3 && !i4:
- return struct {
- Unwrapper
- http.ResponseWriter
- http.Flusher
- http.Hijacker
- io.ReaderFrom
- }{rw, rw, rw, rw, rw}
- // combination 24/32
- case i0 && !i1 && i2 && i3 && i4:
- return struct {
- Unwrapper
- http.ResponseWriter
- http.Flusher
- http.Hijacker
- io.ReaderFrom
- http.Pusher
- }{rw, rw, rw, rw, rw, rw}
- // combination 25/32
- case i0 && i1 && !i2 && !i3 && !i4:
- return struct {
- Unwrapper
- http.ResponseWriter
- http.Flusher
- http.CloseNotifier
- }{rw, rw, rw, rw}
- // combination 26/32
- case i0 && i1 && !i2 && !i3 && i4:
- return struct {
- Unwrapper
- http.ResponseWriter
- http.Flusher
- http.CloseNotifier
- http.Pusher
- }{rw, rw, rw, rw, rw}
- // combination 27/32
- case i0 && i1 && !i2 && i3 && !i4:
- return struct {
- Unwrapper
- http.ResponseWriter
- http.Flusher
- http.CloseNotifier
- io.ReaderFrom
- }{rw, rw, rw, rw, rw}
- // combination 28/32
- case i0 && i1 && !i2 && i3 && i4:
- return struct {
- Unwrapper
- http.ResponseWriter
- http.Flusher
- http.CloseNotifier
- io.ReaderFrom
- http.Pusher
- }{rw, rw, rw, rw, rw, rw}
- // combination 29/32
- case i0 && i1 && i2 && !i3 && !i4:
- return struct {
- Unwrapper
- http.ResponseWriter
- http.Flusher
- http.CloseNotifier
- http.Hijacker
- }{rw, rw, rw, rw, rw}
- // combination 30/32
- case i0 && i1 && i2 && !i3 && i4:
- return struct {
- Unwrapper
- http.ResponseWriter
- http.Flusher
- http.CloseNotifier
- http.Hijacker
- http.Pusher
- }{rw, rw, rw, rw, rw, rw}
- // combination 31/32
- case i0 && i1 && i2 && i3 && !i4:
- return struct {
- Unwrapper
- http.ResponseWriter
- http.Flusher
- http.CloseNotifier
- http.Hijacker
- io.ReaderFrom
- }{rw, rw, rw, rw, rw, rw}
- // combination 32/32
- case i0 && i1 && i2 && i3 && i4:
- return struct {
- Unwrapper
- http.ResponseWriter
- http.Flusher
- http.CloseNotifier
- http.Hijacker
- io.ReaderFrom
- http.Pusher
- }{rw, rw, rw, rw, rw, rw, rw}
- }
- panic("unreachable")
-}
-
-type rw struct {
- w http.ResponseWriter
- h Hooks
-}
-
-func (w *rw) Unwrap() http.ResponseWriter {
- return w.w
-}
-
-func (w *rw) Header() http.Header {
- f := w.w.(http.ResponseWriter).Header
- if w.h.Header != nil {
- f = w.h.Header(f)
- }
- return f()
-}
-
-func (w *rw) WriteHeader(code int) {
- f := w.w.(http.ResponseWriter).WriteHeader
- if w.h.WriteHeader != nil {
- f = w.h.WriteHeader(f)
- }
- f(code)
-}
-
-func (w *rw) Write(b []byte) (int, error) {
- f := w.w.(http.ResponseWriter).Write
- if w.h.Write != nil {
- f = w.h.Write(f)
- }
- return f(b)
-}
-
-func (w *rw) Flush() {
- f := w.w.(http.Flusher).Flush
- if w.h.Flush != nil {
- f = w.h.Flush(f)
- }
- f()
-}
-
-func (w *rw) CloseNotify() <-chan bool {
- f := w.w.(http.CloseNotifier).CloseNotify
- if w.h.CloseNotify != nil {
- f = w.h.CloseNotify(f)
- }
- return f()
-}
-
-func (w *rw) Hijack() (net.Conn, *bufio.ReadWriter, error) {
- f := w.w.(http.Hijacker).Hijack
- if w.h.Hijack != nil {
- f = w.h.Hijack(f)
- }
- return f()
-}
-
-func (w *rw) ReadFrom(src io.Reader) (int64, error) {
- f := w.w.(io.ReaderFrom).ReadFrom
- if w.h.ReadFrom != nil {
- f = w.h.ReadFrom(f)
- }
- return f(src)
-}
-
-func (w *rw) Push(target string, opts *http.PushOptions) error {
- f := w.w.(http.Pusher).Push
- if w.h.Push != nil {
- f = w.h.Push(f)
- }
- return f(target, opts)
-}
-
-type Unwrapper interface {
- Unwrap() http.ResponseWriter
-}
-
-// Unwrap returns the underlying http.ResponseWriter from within zero or more
-// layers of httpsnoop wrappers.
-func Unwrap(w http.ResponseWriter) http.ResponseWriter {
- if rw, ok := w.(Unwrapper); ok {
- // recurse until rw.Unwrap() returns a non-Unwrapper
- return Unwrap(rw.Unwrap())
- } else {
- return w
- }
-}
diff --git a/git-sensor/vendor/github.com/felixge/httpsnoop/wrap_generated_lt_1.8.go b/git-sensor/vendor/github.com/felixge/httpsnoop/wrap_generated_lt_1.8.go
deleted file mode 100644
index e0951df15..000000000
--- a/git-sensor/vendor/github.com/felixge/httpsnoop/wrap_generated_lt_1.8.go
+++ /dev/null
@@ -1,278 +0,0 @@
-// +build !go1.8
-// Code generated by "httpsnoop/codegen"; DO NOT EDIT.
-
-package httpsnoop
-
-import (
- "bufio"
- "io"
- "net"
- "net/http"
-)
-
-// HeaderFunc is part of the http.ResponseWriter interface.
-type HeaderFunc func() http.Header
-
-// WriteHeaderFunc is part of the http.ResponseWriter interface.
-type WriteHeaderFunc func(code int)
-
-// WriteFunc is part of the http.ResponseWriter interface.
-type WriteFunc func(b []byte) (int, error)
-
-// FlushFunc is part of the http.Flusher interface.
-type FlushFunc func()
-
-// CloseNotifyFunc is part of the http.CloseNotifier interface.
-type CloseNotifyFunc func() <-chan bool
-
-// HijackFunc is part of the http.Hijacker interface.
-type HijackFunc func() (net.Conn, *bufio.ReadWriter, error)
-
-// ReadFromFunc is part of the io.ReaderFrom interface.
-type ReadFromFunc func(src io.Reader) (int64, error)
-
-// Hooks defines a set of method interceptors for methods included in
-// http.ResponseWriter as well as some others. You can think of them as
-// middleware for the function calls they target. See Wrap for more details.
-type Hooks struct {
- Header func(HeaderFunc) HeaderFunc
- WriteHeader func(WriteHeaderFunc) WriteHeaderFunc
- Write func(WriteFunc) WriteFunc
- Flush func(FlushFunc) FlushFunc
- CloseNotify func(CloseNotifyFunc) CloseNotifyFunc
- Hijack func(HijackFunc) HijackFunc
- ReadFrom func(ReadFromFunc) ReadFromFunc
-}
-
-// Wrap returns a wrapped version of w that provides the exact same interface
-// as w. Specifically if w implements any combination of:
-//
-// - http.Flusher
-// - http.CloseNotifier
-// - http.Hijacker
-// - io.ReaderFrom
-//
-// The wrapped version will implement the exact same combination. If no hooks
-// are set, the wrapped version also behaves exactly as w. Hooks targeting
-// methods not supported by w are ignored. Any other hooks will intercept the
-// method they target and may modify the call's arguments and/or return values.
-// The CaptureMetrics implementation serves as a working example for how the
-// hooks can be used.
-func Wrap(w http.ResponseWriter, hooks Hooks) http.ResponseWriter {
- rw := &rw{w: w, h: hooks}
- _, i0 := w.(http.Flusher)
- _, i1 := w.(http.CloseNotifier)
- _, i2 := w.(http.Hijacker)
- _, i3 := w.(io.ReaderFrom)
- switch {
- // combination 1/16
- case !i0 && !i1 && !i2 && !i3:
- return struct {
- Unwrapper
- http.ResponseWriter
- }{rw, rw}
- // combination 2/16
- case !i0 && !i1 && !i2 && i3:
- return struct {
- Unwrapper
- http.ResponseWriter
- io.ReaderFrom
- }{rw, rw, rw}
- // combination 3/16
- case !i0 && !i1 && i2 && !i3:
- return struct {
- Unwrapper
- http.ResponseWriter
- http.Hijacker
- }{rw, rw, rw}
- // combination 4/16
- case !i0 && !i1 && i2 && i3:
- return struct {
- Unwrapper
- http.ResponseWriter
- http.Hijacker
- io.ReaderFrom
- }{rw, rw, rw, rw}
- // combination 5/16
- case !i0 && i1 && !i2 && !i3:
- return struct {
- Unwrapper
- http.ResponseWriter
- http.CloseNotifier
- }{rw, rw, rw}
- // combination 6/16
- case !i0 && i1 && !i2 && i3:
- return struct {
- Unwrapper
- http.ResponseWriter
- http.CloseNotifier
- io.ReaderFrom
- }{rw, rw, rw, rw}
- // combination 7/16
- case !i0 && i1 && i2 && !i3:
- return struct {
- Unwrapper
- http.ResponseWriter
- http.CloseNotifier
- http.Hijacker
- }{rw, rw, rw, rw}
- // combination 8/16
- case !i0 && i1 && i2 && i3:
- return struct {
- Unwrapper
- http.ResponseWriter
- http.CloseNotifier
- http.Hijacker
- io.ReaderFrom
- }{rw, rw, rw, rw, rw}
- // combination 9/16
- case i0 && !i1 && !i2 && !i3:
- return struct {
- Unwrapper
- http.ResponseWriter
- http.Flusher
- }{rw, rw, rw}
- // combination 10/16
- case i0 && !i1 && !i2 && i3:
- return struct {
- Unwrapper
- http.ResponseWriter
- http.Flusher
- io.ReaderFrom
- }{rw, rw, rw, rw}
- // combination 11/16
- case i0 && !i1 && i2 && !i3:
- return struct {
- Unwrapper
- http.ResponseWriter
- http.Flusher
- http.Hijacker
- }{rw, rw, rw, rw}
- // combination 12/16
- case i0 && !i1 && i2 && i3:
- return struct {
- Unwrapper
- http.ResponseWriter
- http.Flusher
- http.Hijacker
- io.ReaderFrom
- }{rw, rw, rw, rw, rw}
- // combination 13/16
- case i0 && i1 && !i2 && !i3:
- return struct {
- Unwrapper
- http.ResponseWriter
- http.Flusher
- http.CloseNotifier
- }{rw, rw, rw, rw}
- // combination 14/16
- case i0 && i1 && !i2 && i3:
- return struct {
- Unwrapper
- http.ResponseWriter
- http.Flusher
- http.CloseNotifier
- io.ReaderFrom
- }{rw, rw, rw, rw, rw}
- // combination 15/16
- case i0 && i1 && i2 && !i3:
- return struct {
- Unwrapper
- http.ResponseWriter
- http.Flusher
- http.CloseNotifier
- http.Hijacker
- }{rw, rw, rw, rw, rw}
- // combination 16/16
- case i0 && i1 && i2 && i3:
- return struct {
- Unwrapper
- http.ResponseWriter
- http.Flusher
- http.CloseNotifier
- http.Hijacker
- io.ReaderFrom
- }{rw, rw, rw, rw, rw, rw}
- }
- panic("unreachable")
-}
-
-type rw struct {
- w http.ResponseWriter
- h Hooks
-}
-
-func (w *rw) Unwrap() http.ResponseWriter {
- return w.w
-}
-
-func (w *rw) Header() http.Header {
- f := w.w.(http.ResponseWriter).Header
- if w.h.Header != nil {
- f = w.h.Header(f)
- }
- return f()
-}
-
-func (w *rw) WriteHeader(code int) {
- f := w.w.(http.ResponseWriter).WriteHeader
- if w.h.WriteHeader != nil {
- f = w.h.WriteHeader(f)
- }
- f(code)
-}
-
-func (w *rw) Write(b []byte) (int, error) {
- f := w.w.(http.ResponseWriter).Write
- if w.h.Write != nil {
- f = w.h.Write(f)
- }
- return f(b)
-}
-
-func (w *rw) Flush() {
- f := w.w.(http.Flusher).Flush
- if w.h.Flush != nil {
- f = w.h.Flush(f)
- }
- f()
-}
-
-func (w *rw) CloseNotify() <-chan bool {
- f := w.w.(http.CloseNotifier).CloseNotify
- if w.h.CloseNotify != nil {
- f = w.h.CloseNotify(f)
- }
- return f()
-}
-
-func (w *rw) Hijack() (net.Conn, *bufio.ReadWriter, error) {
- f := w.w.(http.Hijacker).Hijack
- if w.h.Hijack != nil {
- f = w.h.Hijack(f)
- }
- return f()
-}
-
-func (w *rw) ReadFrom(src io.Reader) (int64, error) {
- f := w.w.(io.ReaderFrom).ReadFrom
- if w.h.ReadFrom != nil {
- f = w.h.ReadFrom(f)
- }
- return f(src)
-}
-
-type Unwrapper interface {
- Unwrap() http.ResponseWriter
-}
-
-// Unwrap returns the underlying http.ResponseWriter from within zero or more
-// layers of httpsnoop wrappers.
-func Unwrap(w http.ResponseWriter) http.ResponseWriter {
- if rw, ok := w.(Unwrapper); ok {
- // recurse until rw.Unwrap() returns a non-Unwrapper
- return Unwrap(rw.Unwrap())
- } else {
- return w
- }
-}
diff --git a/git-sensor/vendor/github.com/go-git/go-git/v5/options.go b/git-sensor/vendor/github.com/go-git/go-git/v5/options.go
index e2c77edca..3cd0f952c 100644
--- a/git-sensor/vendor/github.com/go-git/go-git/v5/options.go
+++ b/git-sensor/vendor/github.com/go-git/go-git/v5/options.go
@@ -8,7 +8,6 @@ import (
"time"
"github.com/ProtonMail/go-crypto/openpgp"
-
"github.com/go-git/go-git/v5/config"
"github.com/go-git/go-git/v5/plumbing"
formatcfg "github.com/go-git/go-git/v5/plumbing/format/config"
@@ -73,16 +72,9 @@ type CloneOptions struct {
// Tags describe how the tags will be fetched from the remote repository,
// by default is AllTags.
Tags TagMode
- // InsecureSkipTLS skips SSL verification if protocol is HTTPS.
+ // InsecureSkipTLS skips ssl verify if protocol is https
InsecureSkipTLS bool
- // ClientCert is the client certificate to use for mutual TLS authentication
- // over the HTTPS protocol.
- ClientCert []byte
- // ClientKey is the client key to use for mutual TLS authentication over
- // the HTTPS protocol.
- ClientKey []byte
- // CABundle specifies an additional CA bundle to use together with the
- // system cert pool.
+ // CABundle specify additional ca bundle with system cert pool
CABundle []byte
// ProxyOptions provides info required for connecting to a proxy.
ProxyOptions transport.ProxyOptions
@@ -161,16 +153,9 @@ type PullOptions struct {
// Force allows the pull to update a local branch even when the remote
// branch does not descend from it.
Force bool
- // InsecureSkipTLS skips SSL verification if protocol is HTTPS.
+ // InsecureSkipTLS skips ssl verify if protocol is https
InsecureSkipTLS bool
- // ClientCert is the client certificate to use for mutual TLS authentication
- // over the HTTPS protocol.
- ClientCert []byte
- // ClientKey is the client key to use for mutual TLS authentication over
- // the HTTPS protocol.
- ClientKey []byte
- // CABundle specifies an additional CA bundle to use together with the
- // system cert pool.
+ // CABundle specify additional ca bundle with system cert pool
CABundle []byte
// ProxyOptions provides info required for connecting to a proxy.
ProxyOptions transport.ProxyOptions
@@ -226,16 +211,9 @@ type FetchOptions struct {
// Force allows the fetch to update a local branch even when the remote
// branch does not descend from it.
Force bool
- // InsecureSkipTLS skips SSL verification if protocol is HTTPS.
+ // InsecureSkipTLS skips ssl verify if protocol is https
InsecureSkipTLS bool
- // ClientCert is the client certificate to use for mutual TLS authentication
- // over the HTTPS protocol.
- ClientCert []byte
- // ClientKey is the client key to use for mutual TLS authentication over
- // the HTTPS protocol.
- ClientKey []byte
- // CABundle specifies an additional CA bundle to use together with the
- // system cert pool.
+ // CABundle specify additional ca bundle with system cert pool
CABundle []byte
// ProxyOptions provides info required for connecting to a proxy.
ProxyOptions transport.ProxyOptions
@@ -289,16 +267,9 @@ type PushOptions struct {
// Force allows the push to update a remote branch even when the local
// branch does not descend from it.
Force bool
- // InsecureSkipTLS skips SSL verification if protocol is HTTPS.
+ // InsecureSkipTLS skips ssl verify if protocol is https
InsecureSkipTLS bool
- // ClientCert is the client certificate to use for mutual TLS authentication
- // over the HTTPS protocol.
- ClientCert []byte
- // ClientKey is the client key to use for mutual TLS authentication over
- // the HTTPS protocol.
- ClientKey []byte
- // CABundle specifies an additional CA bundle to use together with the
- // system cert pool.
+ // CABundle specify additional ca bundle with system cert pool
CABundle []byte
// RequireRemoteRefs only allows a remote ref to be updated if its current
// value is the one specified here.
@@ -722,16 +693,9 @@ func (o *CreateTagOptions) loadConfigTagger(r *Repository) error {
type ListOptions struct {
// Auth credentials, if required, to use with the remote repository.
Auth transport.AuthMethod
- // InsecureSkipTLS skips SSL verification if protocol is HTTPS.
+ // InsecureSkipTLS skips ssl verify if protocol is https
InsecureSkipTLS bool
- // ClientCert is the client certificate to use for mutual TLS authentication
- // over the HTTPS protocol.
- ClientCert []byte
- // ClientKey is the client key to use for mutual TLS authentication over
- // the HTTPS protocol.
- ClientKey []byte
- // CABundle specifies an additional CA bundle to use together with the
- // system cert pool.
+ // CABundle specify additional ca bundle with system cert pool
CABundle []byte
// PeelingOption defines how peeled objects are handled during a
// remote list.
diff --git a/git-sensor/vendor/github.com/go-git/go-git/v5/plumbing/transport/common.go b/git-sensor/vendor/github.com/go-git/go-git/v5/plumbing/transport/common.go
index b4c5e98be..fae1aa98c 100644
--- a/git-sensor/vendor/github.com/go-git/go-git/v5/plumbing/transport/common.go
+++ b/git-sensor/vendor/github.com/go-git/go-git/v5/plumbing/transport/common.go
@@ -113,17 +113,9 @@ type Endpoint struct {
Port int
// Path is the repository path.
Path string
- // InsecureSkipTLS skips SSL verification if Protocol is HTTPS.
+ // InsecureSkipTLS skips ssl verify if protocol is https
InsecureSkipTLS bool
- // ClientCert specifies an optional client certificate to use for mutual
- // TLS authentication if Protocol is HTTPS.
- ClientCert []byte
- // ClientKey specifies an optional client key to use for mutual TLS
- // authentication if Protocol is HTTPS.
- ClientKey []byte
- // CaBundle specifies an optional CA bundle to use for SSL verification
- // if Protocol is HTTPS. The bundle is added in addition to the system
- // CA bundle.
+ // CaBundle specify additional ca bundle with system cert pool
CaBundle []byte
// Proxy provides info required for connecting to a proxy.
Proxy ProxyOptions
diff --git a/git-sensor/vendor/github.com/go-git/go-git/v5/plumbing/transport/http/common.go b/git-sensor/vendor/github.com/go-git/go-git/v5/plumbing/transport/http/common.go
index 5dd2e311f..df01890b2 100644
--- a/git-sensor/vendor/github.com/go-git/go-git/v5/plumbing/transport/http/common.go
+++ b/git-sensor/vendor/github.com/go-git/go-git/v5/plumbing/transport/http/common.go
@@ -15,13 +15,12 @@ import (
"strings"
"sync"
- "github.com/golang/groupcache/lru"
-
"github.com/go-git/go-git/v5/plumbing"
"github.com/go-git/go-git/v5/plumbing/protocol/packp"
"github.com/go-git/go-git/v5/plumbing/protocol/packp/capability"
"github.com/go-git/go-git/v5/plumbing/transport"
"github.com/go-git/go-git/v5/utils/ioutil"
+ "github.com/golang/groupcache/lru"
)
// it requires a bytes.Buffer, because we need to know the length
@@ -186,18 +185,6 @@ func transportWithInsecureTLS(transport *http.Transport) {
transport.TLSClientConfig.InsecureSkipVerify = true
}
-func transportWithClientCert(transport *http.Transport, cert, key []byte) error {
- keyPair, err := tls.X509KeyPair(cert, key)
- if err != nil {
- return err
- }
- if transport.TLSClientConfig == nil {
- transport.TLSClientConfig = &tls.Config{}
- }
- transport.TLSClientConfig.Certificates = []tls.Certificate{keyPair}
- return nil
-}
-
func transportWithCABundle(transport *http.Transport, caBundle []byte) error {
rootCAs, err := x509.SystemCertPool()
if err != nil {
@@ -219,11 +206,6 @@ func transportWithProxy(transport *http.Transport, proxyURL *url.URL) {
}
func configureTransport(transport *http.Transport, ep *transport.Endpoint) error {
- if len(ep.ClientCert) > 0 && len(ep.ClientKey) > 0 {
- if err := transportWithClientCert(transport, ep.ClientCert, ep.ClientKey); err != nil {
- return err
- }
- }
if len(ep.CaBundle) > 0 {
if err := transportWithCABundle(transport, ep.CaBundle); err != nil {
return err
@@ -248,7 +230,7 @@ func newSession(c *client, ep *transport.Endpoint, auth transport.AuthMethod) (*
// We need to configure the http transport if there are transport specific
// options present in the endpoint.
- if len(ep.ClientKey) > 0 || len(ep.ClientCert) > 0 || len(ep.CaBundle) > 0 || ep.InsecureSkipTLS || ep.Proxy.URL != "" {
+ if len(ep.CaBundle) > 0 || ep.InsecureSkipTLS || ep.Proxy.URL != "" {
var transport *http.Transport
// if the client wasn't configured to have a cache for transports then just configure
// the transport and use it directly, otherwise try to use the cache.
@@ -260,13 +242,9 @@ func newSession(c *client, ep *transport.Endpoint, auth transport.AuthMethod) (*
}
transport = tr.Clone()
- if err := configureTransport(transport, ep); err != nil {
- return nil, err
- }
+ configureTransport(transport, ep)
} else {
transportOpts := transportOptions{
- clientCert: string(ep.ClientCert),
- clientKey: string(ep.ClientKey),
caBundle: string(ep.CaBundle),
insecureSkipTLS: ep.InsecureSkipTLS,
}
@@ -282,9 +260,7 @@ func newSession(c *client, ep *transport.Endpoint, auth transport.AuthMethod) (*
if !found {
transport = c.client.Transport.(*http.Transport).Clone()
- if err := configureTransport(transport, ep); err != nil {
- return nil, err
- }
+ configureTransport(transport, ep)
c.addTransport(transportOpts, transport)
}
}
diff --git a/git-sensor/vendor/github.com/go-git/go-git/v5/plumbing/transport/http/transport.go b/git-sensor/vendor/github.com/go-git/go-git/v5/plumbing/transport/http/transport.go
index 1991d0512..c8db38920 100644
--- a/git-sensor/vendor/github.com/go-git/go-git/v5/plumbing/transport/http/transport.go
+++ b/git-sensor/vendor/github.com/go-git/go-git/v5/plumbing/transport/http/transport.go
@@ -9,10 +9,8 @@ import (
type transportOptions struct {
insecureSkipTLS bool
// []byte is not comparable.
- clientCert string
- clientKey string
- caBundle string
- proxyURL url.URL
+ caBundle string
+ proxyURL url.URL
}
func (c *client) addTransport(opts transportOptions, transport *http.Transport) {
diff --git a/git-sensor/vendor/github.com/go-git/go-git/v5/plumbing/transport/ssh/auth_method.go b/git-sensor/vendor/github.com/go-git/go-git/v5/plumbing/transport/ssh/auth_method.go
index a61610601..ac4e3583c 100644
--- a/git-sensor/vendor/github.com/go-git/go-git/v5/plumbing/transport/ssh/auth_method.go
+++ b/git-sensor/vendor/github.com/go-git/go-git/v5/plumbing/transport/ssh/auth_method.go
@@ -54,7 +54,7 @@ func (a *KeyboardInteractive) String() string {
}
func (a *KeyboardInteractive) ClientConfig() (*ssh.ClientConfig, error) {
- return a.SetHostKeyCallbackAndAlgorithms(&ssh.ClientConfig{
+ return a.SetHostKeyCallback(&ssh.ClientConfig{
User: a.User,
Auth: []ssh.AuthMethod{
a.Challenge,
@@ -78,7 +78,7 @@ func (a *Password) String() string {
}
func (a *Password) ClientConfig() (*ssh.ClientConfig, error) {
- return a.SetHostKeyCallbackAndAlgorithms(&ssh.ClientConfig{
+ return a.SetHostKeyCallback(&ssh.ClientConfig{
User: a.User,
Auth: []ssh.AuthMethod{ssh.Password(a.Password)},
})
@@ -101,7 +101,7 @@ func (a *PasswordCallback) String() string {
}
func (a *PasswordCallback) ClientConfig() (*ssh.ClientConfig, error) {
- return a.SetHostKeyCallbackAndAlgorithms(&ssh.ClientConfig{
+ return a.SetHostKeyCallback(&ssh.ClientConfig{
User: a.User,
Auth: []ssh.AuthMethod{ssh.PasswordCallback(a.Callback)},
})
@@ -150,7 +150,7 @@ func (a *PublicKeys) String() string {
}
func (a *PublicKeys) ClientConfig() (*ssh.ClientConfig, error) {
- return a.SetHostKeyCallbackAndAlgorithms(&ssh.ClientConfig{
+ return a.SetHostKeyCallback(&ssh.ClientConfig{
User: a.User,
Auth: []ssh.AuthMethod{ssh.PublicKeys(a.Signer)},
})
@@ -211,7 +211,7 @@ func (a *PublicKeysCallback) String() string {
}
func (a *PublicKeysCallback) ClientConfig() (*ssh.ClientConfig, error) {
- return a.SetHostKeyCallbackAndAlgorithms(&ssh.ClientConfig{
+ return a.SetHostKeyCallback(&ssh.ClientConfig{
User: a.User,
Auth: []ssh.AuthMethod{ssh.PublicKeysCallback(a.Callback)},
})
@@ -230,26 +230,11 @@ func (a *PublicKeysCallback) ClientConfig() (*ssh.ClientConfig, error) {
// ~/.ssh/known_hosts
// /etc/ssh/ssh_known_hosts
func NewKnownHostsCallback(files ...string) (ssh.HostKeyCallback, error) {
- kh, err := NewKnownHostsDb(files...)
- if err != nil {
- return nil, err
- }
- return kh.HostKeyCallback(), nil
+ kh, err := newKnownHosts(files...)
+ return ssh.HostKeyCallback(kh), err
}
-// NewKnownHostsDb returns knownhosts.HostKeyDB based on a file based on a
-// known_hosts file. http://man.openbsd.org/sshd#SSH_KNOWN_HOSTS_FILE_FORMAT
-//
-// If list of files is empty, then it will be read from the SSH_KNOWN_HOSTS
-// environment variable, example:
-//
-// /home/foo/custom_known_hosts_file:/etc/custom_known/hosts_file
-//
-// If SSH_KNOWN_HOSTS is not set the following file locations will be used:
-//
-// ~/.ssh/known_hosts
-// /etc/ssh/ssh_known_hosts
-func NewKnownHostsDb(files ...string) (*knownhosts.HostKeyDB, error) {
+func newKnownHosts(files ...string) (knownhosts.HostKeyCallback, error) {
var err error
if len(files) == 0 {
@@ -262,7 +247,7 @@ func NewKnownHostsDb(files ...string) (*knownhosts.HostKeyDB, error) {
return nil, err
}
- return knownhosts.NewDB(files...)
+ return knownhosts.New(files...)
}
func getDefaultKnownHostsFiles() ([]string, error) {
@@ -304,50 +289,25 @@ func filterKnownHostsFiles(files ...string) ([]string, error) {
}
// HostKeyCallbackHelper is a helper that provides common functionality to
-// configure HostKeyCallback and HostKeyAlgorithms into a ssh.ClientConfig.
+// configure HostKeyCallback into a ssh.ClientConfig.
type HostKeyCallbackHelper struct {
// HostKeyCallback is the function type used for verifying server keys.
- // If nil, a default callback will be created using NewKnownHostsDb
+ // If nil default callback will be create using NewKnownHostsCallback
// without argument.
HostKeyCallback ssh.HostKeyCallback
-
- // HostKeyAlgorithms is a list of supported host key algorithms that will
- // be used for host key verification.
- HostKeyAlgorithms []string
-
- // fallback allows for injecting the fallback call, which is called
- // when a HostKeyCallback is not set.
- fallback func(files ...string) (ssh.HostKeyCallback, error)
}
-// SetHostKeyCallbackAndAlgorithms sets the field HostKeyCallback and HostKeyAlgorithms in the given cfg.
-// If the host key callback or algorithms is empty it is left empty. It will be handled by the dial method,
-// falling back to knownhosts.
-func (m *HostKeyCallbackHelper) SetHostKeyCallbackAndAlgorithms(cfg *ssh.ClientConfig) (*ssh.ClientConfig, error) {
- if cfg == nil {
- cfg = &ssh.ClientConfig{}
- }
-
+// SetHostKeyCallback sets the field HostKeyCallback in the given cfg. If
+// HostKeyCallback is empty a default callback is created using
+// NewKnownHostsCallback.
+func (m *HostKeyCallbackHelper) SetHostKeyCallback(cfg *ssh.ClientConfig) (*ssh.ClientConfig, error) {
+ var err error
if m.HostKeyCallback == nil {
- if m.fallback == nil {
- m.fallback = NewKnownHostsCallback
+ if m.HostKeyCallback, err = NewKnownHostsCallback(); err != nil {
+ return cfg, err
}
-
- hkcb, err := m.fallback()
- if err != nil {
- return nil, fmt.Errorf("cannot create known hosts callback: %w", err)
- }
-
- cfg.HostKeyCallback = hkcb
- cfg.HostKeyAlgorithms = m.HostKeyAlgorithms
- return cfg, err
}
cfg.HostKeyCallback = m.HostKeyCallback
- cfg.HostKeyAlgorithms = m.HostKeyAlgorithms
return cfg, nil
}
-
-func (m *HostKeyCallbackHelper) SetHostKeyCallback(cfg *ssh.ClientConfig) (*ssh.ClientConfig, error) {
- return m.SetHostKeyCallbackAndAlgorithms(cfg)
-}
diff --git a/git-sensor/vendor/github.com/go-git/go-git/v5/plumbing/transport/ssh/common.go b/git-sensor/vendor/github.com/go-git/go-git/v5/plumbing/transport/ssh/common.go
index ae6f2174a..05dea448f 100644
--- a/git-sensor/vendor/github.com/go-git/go-git/v5/plumbing/transport/ssh/common.go
+++ b/git-sensor/vendor/github.com/go-git/go-git/v5/plumbing/transport/ssh/common.go
@@ -11,6 +11,7 @@ import (
"github.com/go-git/go-git/v5/plumbing/transport"
"github.com/go-git/go-git/v5/plumbing/transport/internal/common"
+ "github.com/skeema/knownhosts"
"github.com/kevinburke/ssh_config"
"golang.org/x/crypto/ssh"
@@ -126,17 +127,17 @@ func (c *command) connect() error {
}
hostWithPort := c.getHostWithPort()
if config.HostKeyCallback == nil {
- db, err := NewKnownHostsDb()
+ kh, err := newKnownHosts()
if err != nil {
return err
}
- config.HostKeyCallback = db.HostKeyCallback()
- config.HostKeyAlgorithms = db.HostKeyAlgorithms(hostWithPort)
- } else {
- // If the user gave a custom HostKeyCallback, we do not try to detect host key algorithms
- // based on knownhosts functionality, as the user may be requesting a FixedKey or using a
- // different key approval strategy. In that case, the user is responsible for populating
- // HostKeyAlgorithms appropriately
+ config.HostKeyCallback = kh.HostKeyCallback()
+ config.HostKeyAlgorithms = kh.HostKeyAlgorithms(hostWithPort)
+ } else if len(config.HostKeyAlgorithms) == 0 {
+ // Set the HostKeyAlgorithms based on HostKeyCallback.
+ // For background see https://github.com/go-git/go-git/issues/411 as well as
+ // https://github.com/golang/go/issues/29286 for root cause.
+ config.HostKeyAlgorithms = knownhosts.HostKeyAlgorithms(config.HostKeyCallback, hostWithPort)
}
overrideConfig(c.config, config)
diff --git a/git-sensor/vendor/github.com/go-git/go-git/v5/remote.go b/git-sensor/vendor/github.com/go-git/go-git/v5/remote.go
index 730812797..e2c734e75 100644
--- a/git-sensor/vendor/github.com/go-git/go-git/v5/remote.go
+++ b/git-sensor/vendor/github.com/go-git/go-git/v5/remote.go
@@ -114,7 +114,7 @@ func (r *Remote) PushContext(ctx context.Context, o *PushOptions) (err error) {
o.RemoteURL = r.c.URLs[len(r.c.URLs)-1]
}
- s, err := newSendPackSession(o.RemoteURL, o.Auth, o.InsecureSkipTLS, o.ClientCert, o.ClientKey, o.CABundle, o.ProxyOptions)
+ s, err := newSendPackSession(o.RemoteURL, o.Auth, o.InsecureSkipTLS, o.CABundle, o.ProxyOptions)
if err != nil {
return err
}
@@ -416,7 +416,7 @@ func (r *Remote) fetch(ctx context.Context, o *FetchOptions) (sto storer.Referen
o.RemoteURL = r.c.URLs[0]
}
- s, err := newUploadPackSession(o.RemoteURL, o.Auth, o.InsecureSkipTLS, o.ClientCert, o.ClientKey, o.CABundle, o.ProxyOptions)
+ s, err := newUploadPackSession(o.RemoteURL, o.Auth, o.InsecureSkipTLS, o.CABundle, o.ProxyOptions)
if err != nil {
return nil, err
}
@@ -532,8 +532,8 @@ func depthChanged(before []plumbing.Hash, s storage.Storer) (bool, error) {
return false, nil
}
-func newUploadPackSession(url string, auth transport.AuthMethod, insecure bool, clientCert, clientKey, caBundle []byte, proxyOpts transport.ProxyOptions) (transport.UploadPackSession, error) {
- c, ep, err := newClient(url, insecure, clientCert, clientKey, caBundle, proxyOpts)
+func newUploadPackSession(url string, auth transport.AuthMethod, insecure bool, cabundle []byte, proxyOpts transport.ProxyOptions) (transport.UploadPackSession, error) {
+ c, ep, err := newClient(url, insecure, cabundle, proxyOpts)
if err != nil {
return nil, err
}
@@ -541,8 +541,8 @@ func newUploadPackSession(url string, auth transport.AuthMethod, insecure bool,
return c.NewUploadPackSession(ep, auth)
}
-func newSendPackSession(url string, auth transport.AuthMethod, insecure bool, clientCert, clientKey, caBundle []byte, proxyOpts transport.ProxyOptions) (transport.ReceivePackSession, error) {
- c, ep, err := newClient(url, insecure, clientCert, clientKey, caBundle, proxyOpts)
+func newSendPackSession(url string, auth transport.AuthMethod, insecure bool, cabundle []byte, proxyOpts transport.ProxyOptions) (transport.ReceivePackSession, error) {
+ c, ep, err := newClient(url, insecure, cabundle, proxyOpts)
if err != nil {
return nil, err
}
@@ -550,15 +550,13 @@ func newSendPackSession(url string, auth transport.AuthMethod, insecure bool, cl
return c.NewReceivePackSession(ep, auth)
}
-func newClient(url string, insecure bool, clientCert, clientKey, caBundle []byte, proxyOpts transport.ProxyOptions) (transport.Transport, *transport.Endpoint, error) {
+func newClient(url string, insecure bool, cabundle []byte, proxyOpts transport.ProxyOptions) (transport.Transport, *transport.Endpoint, error) {
ep, err := transport.NewEndpoint(url)
if err != nil {
return nil, nil, err
}
ep.InsecureSkipTLS = insecure
- ep.ClientCert = clientCert
- ep.ClientKey = clientKey
- ep.CaBundle = caBundle
+ ep.CaBundle = cabundle
ep.Proxy = proxyOpts
c, err := client.NewClient(ep)
@@ -1358,7 +1356,7 @@ func (r *Remote) list(ctx context.Context, o *ListOptions) (rfs []*plumbing.Refe
return nil, ErrEmptyUrls
}
- s, err := newUploadPackSession(r.c.URLs[0], o.Auth, o.InsecureSkipTLS, o.ClientCert, o.ClientKey, o.CABundle, o.ProxyOptions)
+ s, err := newUploadPackSession(r.c.URLs[0], o.Auth, o.InsecureSkipTLS, o.CABundle, o.ProxyOptions)
if err != nil {
return nil, err
}
diff --git a/git-sensor/vendor/github.com/go-git/go-git/v5/repository.go b/git-sensor/vendor/github.com/go-git/go-git/v5/repository.go
index 401590544..200098e7a 100644
--- a/git-sensor/vendor/github.com/go-git/go-git/v5/repository.go
+++ b/git-sensor/vendor/github.com/go-git/go-git/v5/repository.go
@@ -19,7 +19,6 @@ import (
"github.com/go-git/go-billy/v5"
"github.com/go-git/go-billy/v5/osfs"
"github.com/go-git/go-billy/v5/util"
-
"github.com/go-git/go-git/v5/config"
"github.com/go-git/go-git/v5/internal/path_util"
"github.com/go-git/go-git/v5/internal/revision"
@@ -931,8 +930,6 @@ func (r *Repository) clone(ctx context.Context, o *CloneOptions) error {
Tags: o.Tags,
RemoteName: o.RemoteName,
InsecureSkipTLS: o.InsecureSkipTLS,
- ClientCert: o.ClientCert,
- ClientKey: o.ClientKey,
CABundle: o.CABundle,
ProxyOptions: o.ProxyOptions,
}, o.ReferenceName)
diff --git a/git-sensor/vendor/github.com/go-git/go-git/v5/worktree.go b/git-sensor/vendor/github.com/go-git/go-git/v5/worktree.go
index 479904e0c..dded08e99 100644
--- a/git-sensor/vendor/github.com/go-git/go-git/v5/worktree.go
+++ b/git-sensor/vendor/github.com/go-git/go-git/v5/worktree.go
@@ -12,7 +12,6 @@ import (
"github.com/go-git/go-billy/v5"
"github.com/go-git/go-billy/v5/util"
-
"github.com/go-git/go-git/v5/config"
"github.com/go-git/go-git/v5/plumbing"
"github.com/go-git/go-git/v5/plumbing/filemode"
@@ -80,8 +79,6 @@ func (w *Worktree) PullContext(ctx context.Context, o *PullOptions) error {
Progress: o.Progress,
Force: o.Force,
InsecureSkipTLS: o.InsecureSkipTLS,
- ClientCert: o.ClientCert,
- ClientKey: o.ClientKey,
CABundle: o.CABundle,
ProxyOptions: o.ProxyOptions,
})
diff --git a/git-sensor/vendor/github.com/gorilla/handlers/.editorconfig b/git-sensor/vendor/github.com/gorilla/handlers/.editorconfig
deleted file mode 100644
index c6b74c3e0..000000000
--- a/git-sensor/vendor/github.com/gorilla/handlers/.editorconfig
+++ /dev/null
@@ -1,20 +0,0 @@
-; https://editorconfig.org/
-
-root = true
-
-[*]
-insert_final_newline = true
-charset = utf-8
-trim_trailing_whitespace = true
-indent_style = space
-indent_size = 2
-
-[{Makefile,go.mod,go.sum,*.go,.gitmodules}]
-indent_style = tab
-indent_size = 4
-
-[*.md]
-indent_size = 4
-trim_trailing_whitespace = false
-
-eclint_indent_style = unset
\ No newline at end of file
diff --git a/git-sensor/vendor/github.com/gorilla/handlers/.gitignore b/git-sensor/vendor/github.com/gorilla/handlers/.gitignore
deleted file mode 100644
index 577a89e81..000000000
--- a/git-sensor/vendor/github.com/gorilla/handlers/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-# Output of the go test coverage tool
-coverage.coverprofile
diff --git a/git-sensor/vendor/github.com/gorilla/handlers/LICENSE b/git-sensor/vendor/github.com/gorilla/handlers/LICENSE
index bb9d80bc9..66ea3c8ae 100644
--- a/git-sensor/vendor/github.com/gorilla/handlers/LICENSE
+++ b/git-sensor/vendor/github.com/gorilla/handlers/LICENSE
@@ -1,27 +1,22 @@
-Copyright (c) 2023 The Gorilla Authors. All rights reserved.
+Copyright (c) 2013 The Gorilla Handlers Authors. All rights reserved.
Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
+modification, are permitted provided that the following conditions are met:
- * Redistributions of source code must retain the above copyright
-notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above
-copyright notice, this list of conditions and the following disclaimer
-in the documentation and/or other materials provided with the
-distribution.
- * Neither the name of Google Inc. nor the names of its
-contributors may be used to endorse or promote products derived from
-this software without specific prior written permission.
+ Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/git-sensor/vendor/github.com/gorilla/handlers/Makefile b/git-sensor/vendor/github.com/gorilla/handlers/Makefile
deleted file mode 100644
index 003b784f7..000000000
--- a/git-sensor/vendor/github.com/gorilla/handlers/Makefile
+++ /dev/null
@@ -1,34 +0,0 @@
-GO_LINT=$(shell which golangci-lint 2> /dev/null || echo '')
-GO_LINT_URI=github.com/golangci/golangci-lint/cmd/golangci-lint@latest
-
-GO_SEC=$(shell which gosec 2> /dev/null || echo '')
-GO_SEC_URI=github.com/securego/gosec/v2/cmd/gosec@latest
-
-GO_VULNCHECK=$(shell which govulncheck 2> /dev/null || echo '')
-GO_VULNCHECK_URI=golang.org/x/vuln/cmd/govulncheck@latest
-
-.PHONY: verify
-verify: sec govulncheck lint test
-
-.PHONY: lint
-lint:
- $(if $(GO_LINT), ,go install $(GO_LINT_URI))
- @echo "##### Running golangci-lint #####"
- golangci-lint run -v
-
-.PHONY: sec
-sec:
- $(if $(GO_SEC), ,go install $(GO_SEC_URI))
- @echo "##### Running gosec #####"
- gosec ./...
-
-.PHONY: govulncheck
-govulncheck:
- $(if $(GO_VULNCHECK), ,go install $(GO_VULNCHECK_URI))
- @echo "##### Running govulncheck #####"
- govulncheck ./...
-
-.PHONY: test
-test:
- @echo "##### Running tests #####"
- go test -race -cover -coverprofile=coverage.coverprofile -covermode=atomic -v ./...
diff --git a/git-sensor/vendor/github.com/gorilla/handlers/README.md b/git-sensor/vendor/github.com/gorilla/handlers/README.md
index 02555b264..6eba66bf3 100644
--- a/git-sensor/vendor/github.com/gorilla/handlers/README.md
+++ b/git-sensor/vendor/github.com/gorilla/handlers/README.md
@@ -1,10 +1,10 @@
-# gorilla/handlers
-
-
-[](https://codecov.io/github/gorilla/handlers)
+gorilla/handlers
+================
[](https://godoc.org/github.com/gorilla/handlers)
+[](https://circleci.com/gh/gorilla/handlers)
[](https://sourcegraph.com/github.com/gorilla/handlers?badge)
+
Package handlers is a collection of handlers (aka "HTTP middleware") for use
with Go's `net/http` package (or any framework supporting `http.Handler`), including:
diff --git a/git-sensor/vendor/github.com/gorilla/handlers/canonical.go b/git-sensor/vendor/github.com/gorilla/handlers/canonical.go
index 7121f5307..8437fefc1 100644
--- a/git-sensor/vendor/github.com/gorilla/handlers/canonical.go
+++ b/git-sensor/vendor/github.com/gorilla/handlers/canonical.go
@@ -21,11 +21,12 @@ type canonical struct {
//
// Example:
//
-// r := mux.NewRouter()
-// canonical := handlers.CanonicalHost("http://www.gorillatoolkit.org", 302)
-// r.HandleFunc("/route", YourHandler)
+// r := mux.NewRouter()
+// canonical := handlers.CanonicalHost("http://www.gorillatoolkit.org", 302)
+// r.HandleFunc("/route", YourHandler)
+//
+// log.Fatal(http.ListenAndServe(":7000", canonical(r)))
//
-// log.Fatal(http.ListenAndServe(":7000", canonical(r)))
func CanonicalHost(domain string, code int) func(h http.Handler) http.Handler {
fn := func(h http.Handler) http.Handler {
return canonical{h, domain, code}
diff --git a/git-sensor/vendor/github.com/gorilla/handlers/compress.go b/git-sensor/vendor/github.com/gorilla/handlers/compress.go
index d6f589503..e46a7bfd6 100644
--- a/git-sensor/vendor/github.com/gorilla/handlers/compress.go
+++ b/git-sensor/vendor/github.com/gorilla/handlers/compress.go
@@ -10,48 +10,47 @@ import (
"io"
"net/http"
"strings"
-
- "github.com/felixge/httpsnoop"
)
-const acceptEncoding string = "Accept-Encoding"
-
type compressResponseWriter struct {
- compressor io.Writer
- w http.ResponseWriter
+ io.Writer
+ http.ResponseWriter
+ http.Hijacker
+ http.Flusher
+ http.CloseNotifier
}
-func (cw *compressResponseWriter) WriteHeader(c int) {
- cw.w.Header().Del("Content-Length")
- cw.w.WriteHeader(c)
+func (w *compressResponseWriter) WriteHeader(c int) {
+ w.ResponseWriter.Header().Del("Content-Length")
+ w.ResponseWriter.WriteHeader(c)
}
-func (cw *compressResponseWriter) Write(b []byte) (int, error) {
- h := cw.w.Header()
+func (w *compressResponseWriter) Header() http.Header {
+ return w.ResponseWriter.Header()
+}
+
+func (w *compressResponseWriter) Write(b []byte) (int, error) {
+ h := w.ResponseWriter.Header()
if h.Get("Content-Type") == "" {
h.Set("Content-Type", http.DetectContentType(b))
}
h.Del("Content-Length")
- return cw.compressor.Write(b)
-}
-
-func (cw *compressResponseWriter) ReadFrom(r io.Reader) (int64, error) {
- return io.Copy(cw.compressor, r)
+ return w.Writer.Write(b)
}
type flusher interface {
Flush() error
}
-func (cw *compressResponseWriter) Flush() {
+func (w *compressResponseWriter) Flush() {
// Flush compressed data if compressor supports it.
- if f, ok := cw.compressor.(flusher); ok {
- _ = f.Flush()
+ if f, ok := w.Writer.(flusher); ok {
+ f.Flush()
}
// Flush HTTP response.
- if f, ok := cw.w.(http.Flusher); ok {
- f.Flush()
+ if w.Flusher != nil {
+ w.Flusher.Flush()
}
}
@@ -75,69 +74,77 @@ func CompressHandlerLevel(h http.Handler, level int) http.Handler {
level = gzip.DefaultCompression
}
- const (
- gzipEncoding = "gzip"
- flateEncoding = "deflate"
- )
-
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- // detect what encoding to use
- var encoding string
- for _, curEnc := range strings.Split(r.Header.Get(acceptEncoding), ",") {
- curEnc = strings.TrimSpace(curEnc)
- if curEnc == gzipEncoding || curEnc == flateEncoding {
- encoding = curEnc
- break
+ L:
+ for _, enc := range strings.Split(r.Header.Get("Accept-Encoding"), ",") {
+ switch strings.TrimSpace(enc) {
+ case "gzip":
+ w.Header().Set("Content-Encoding", "gzip")
+ r.Header.Del("Accept-Encoding")
+ w.Header().Add("Vary", "Accept-Encoding")
+
+ gw, _ := gzip.NewWriterLevel(w, level)
+ defer gw.Close()
+
+ h, hok := w.(http.Hijacker)
+ if !hok { /* w is not Hijacker... oh well... */
+ h = nil
+ }
+
+ f, fok := w.(http.Flusher)
+ if !fok {
+ f = nil
+ }
+
+ cn, cnok := w.(http.CloseNotifier)
+ if !cnok {
+ cn = nil
+ }
+
+ w = &compressResponseWriter{
+ Writer: gw,
+ ResponseWriter: w,
+ Hijacker: h,
+ Flusher: f,
+ CloseNotifier: cn,
+ }
+
+ break L
+ case "deflate":
+ w.Header().Set("Content-Encoding", "deflate")
+ r.Header.Del("Accept-Encoding")
+ w.Header().Add("Vary", "Accept-Encoding")
+
+ fw, _ := flate.NewWriter(w, level)
+ defer fw.Close()
+
+ h, hok := w.(http.Hijacker)
+ if !hok { /* w is not Hijacker... oh well... */
+ h = nil
+ }
+
+ f, fok := w.(http.Flusher)
+ if !fok {
+ f = nil
+ }
+
+ cn, cnok := w.(http.CloseNotifier)
+ if !cnok {
+ cn = nil
+ }
+
+ w = &compressResponseWriter{
+ Writer: fw,
+ ResponseWriter: w,
+ Hijacker: h,
+ Flusher: f,
+ CloseNotifier: cn,
+ }
+
+ break L
}
}
- // always add Accept-Encoding to Vary to prevent intermediate caches corruption
- w.Header().Add("Vary", acceptEncoding)
-
- // if we weren't able to identify an encoding we're familiar with, pass on the
- // request to the handler and return
- if encoding == "" {
- h.ServeHTTP(w, r)
- return
- }
-
- if r.Header.Get("Upgrade") != "" {
- h.ServeHTTP(w, r)
- return
- }
-
- // wrap the ResponseWriter with the writer for the chosen encoding
- var encWriter io.WriteCloser
- if encoding == gzipEncoding {
- encWriter, _ = gzip.NewWriterLevel(w, level)
- } else if encoding == flateEncoding {
- encWriter, _ = flate.NewWriter(w, level)
- }
- defer encWriter.Close()
-
- w.Header().Set("Content-Encoding", encoding)
- r.Header.Del(acceptEncoding)
-
- cw := &compressResponseWriter{
- w: w,
- compressor: encWriter,
- }
-
- w = httpsnoop.Wrap(w, httpsnoop.Hooks{
- Write: func(httpsnoop.WriteFunc) httpsnoop.WriteFunc {
- return cw.Write
- },
- WriteHeader: func(httpsnoop.WriteHeaderFunc) httpsnoop.WriteHeaderFunc {
- return cw.WriteHeader
- },
- Flush: func(httpsnoop.FlushFunc) httpsnoop.FlushFunc {
- return cw.Flush
- },
- ReadFrom: func(rff httpsnoop.ReadFromFunc) httpsnoop.ReadFromFunc {
- return cw.ReadFrom
- },
- })
-
h.ServeHTTP(w, r)
})
}
diff --git a/git-sensor/vendor/github.com/gorilla/handlers/cors.go b/git-sensor/vendor/github.com/gorilla/handlers/cors.go
index 8af9c096e..0dcdffb3d 100644
--- a/git-sensor/vendor/github.com/gorilla/handlers/cors.go
+++ b/git-sensor/vendor/github.com/gorilla/handlers/cors.go
@@ -26,14 +26,14 @@ type cors struct {
type OriginValidator func(string) bool
var (
- defaultCorsOptionStatusCode = http.StatusOK
- defaultCorsMethods = []string{http.MethodGet, http.MethodHead, http.MethodPost}
+ defaultCorsOptionStatusCode = 200
+ defaultCorsMethods = []string{"GET", "HEAD", "POST"}
defaultCorsHeaders = []string{"Accept", "Accept-Language", "Content-Language", "Origin"}
- // (WebKit/Safari v9 sends the Origin header by default in AJAX requests).
+ // (WebKit/Safari v9 sends the Origin header by default in AJAX requests)
)
const (
- corsOptionMethod string = http.MethodOptions
+ corsOptionMethod string = "OPTIONS"
corsAllowOriginHeader string = "Access-Control-Allow-Origin"
corsExposeHeadersHeader string = "Access-Control-Expose-Headers"
corsMaxAgeHeader string = "Access-Control-Max-Age"
@@ -101,8 +101,10 @@ func (ch *cors) ServeHTTP(w http.ResponseWriter, r *http.Request) {
if !ch.isMatch(method, defaultCorsMethods) {
w.Header().Set(corsAllowMethodsHeader, method)
}
- } else if len(ch.exposedHeaders) > 0 {
- w.Header().Set(corsExposeHeadersHeader, strings.Join(ch.exposedHeaders, ","))
+ } else {
+ if len(ch.exposedHeaders) > 0 {
+ w.Header().Set(corsExposeHeadersHeader, strings.Join(ch.exposedHeaders, ","))
+ }
}
if ch.allowCredentials {
@@ -139,21 +141,22 @@ func (ch *cors) ServeHTTP(w http.ResponseWriter, r *http.Request) {
// CORS provides Cross-Origin Resource Sharing middleware.
// Example:
//
-// import (
-// "net/http"
+// import (
+// "net/http"
+//
+// "github.com/gorilla/handlers"
+// "github.com/gorilla/mux"
+// )
//
-// "github.com/gorilla/handlers"
-// "github.com/gorilla/mux"
-// )
+// func main() {
+// r := mux.NewRouter()
+// r.HandleFunc("/users", UserEndpoint)
+// r.HandleFunc("/projects", ProjectEndpoint)
//
-// func main() {
-// r := mux.NewRouter()
-// r.HandleFunc("/users", UserEndpoint)
-// r.HandleFunc("/projects", ProjectEndpoint)
+// // Apply the CORS middleware to our top-level router, with the defaults.
+// http.ListenAndServe(":8000", handlers.CORS()(r))
+// }
//
-// // Apply the CORS middleware to our top-level router, with the defaults.
-// http.ListenAndServe(":8000", handlers.CORS()(r))
-// }
func CORS(opts ...CORSOption) func(http.Handler) http.Handler {
return func(h http.Handler) http.Handler {
ch := parseCORSOptions(opts...)
@@ -171,7 +174,7 @@ func parseCORSOptions(opts ...CORSOption) *cors {
}
for _, option := range opts {
- _ = option(ch) //TODO: @bharat-rajani, return error to caller if not nil?
+ option(ch)
}
return ch
diff --git a/git-sensor/vendor/github.com/gorilla/handlers/handlers.go b/git-sensor/vendor/github.com/gorilla/handlers/handlers.go
index 9b92fce33..d03f2bf13 100644
--- a/git-sensor/vendor/github.com/gorilla/handlers/handlers.go
+++ b/git-sensor/vendor/github.com/gorilla/handlers/handlers.go
@@ -35,7 +35,7 @@ func (h MethodHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
}
sort.Strings(allow)
w.Header().Set("Allow", strings.Join(allow, ", "))
- if req.Method == http.MethodOptions {
+ if req.Method == "OPTIONS" {
w.WriteHeader(http.StatusOK)
} else {
http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
@@ -44,13 +44,17 @@ func (h MethodHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
}
// responseLogger is wrapper of http.ResponseWriter that keeps track of its HTTP
-// status code and body size.
+// status code and body size
type responseLogger struct {
w http.ResponseWriter
status int
size int
}
+func (l *responseLogger) Header() http.Header {
+ return l.w.Header()
+}
+
func (l *responseLogger) Write(b []byte) (int, error) {
size, err := l.w.Write(b)
l.size += size
@@ -70,16 +74,39 @@ func (l *responseLogger) Size() int {
return l.size
}
-func (l *responseLogger) Hijack() (net.Conn, *bufio.ReadWriter, error) {
- conn, rw, err := l.w.(http.Hijacker).Hijack()
- if err == nil && l.status == 0 {
+func (l *responseLogger) Flush() {
+ f, ok := l.w.(http.Flusher)
+ if ok {
+ f.Flush()
+ }
+}
+
+type hijackLogger struct {
+ responseLogger
+}
+
+func (l *hijackLogger) Hijack() (net.Conn, *bufio.ReadWriter, error) {
+ h := l.responseLogger.w.(http.Hijacker)
+ conn, rw, err := h.Hijack()
+ if err == nil && l.responseLogger.status == 0 {
// The status will be StatusSwitchingProtocols if there was no error and
// WriteHeader has not been called yet
- l.status = http.StatusSwitchingProtocols
+ l.responseLogger.status = http.StatusSwitchingProtocols
}
return conn, rw, err
}
+type closeNotifyWriter struct {
+ loggingResponseWriter
+ http.CloseNotifier
+}
+
+type hijackCloseNotifier struct {
+ loggingResponseWriter
+ http.Hijacker
+ http.CloseNotifier
+}
+
// isContentType validates the Content-Type header matches the supplied
// contentType. That is, its type and subtype match.
func isContentType(h http.Header, contentType string) bool {
@@ -97,7 +124,7 @@ func isContentType(h http.Header, contentType string) bool {
// Only PUT, POST, and PATCH requests are considered.
func ContentTypeHandler(h http.Handler, contentTypes ...string) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- if !(r.Method == http.MethodPut || r.Method == http.MethodPost || r.Method == http.MethodPatch) {
+ if !(r.Method == "PUT" || r.Method == "POST" || r.Method == "PATCH") {
h.ServeHTTP(w, r)
return
}
@@ -108,10 +135,7 @@ func ContentTypeHandler(h http.Handler, contentTypes ...string) http.Handler {
return
}
}
- http.Error(w, fmt.Sprintf("Unsupported content type %q; expected one of %q",
- r.Header.Get("Content-Type"),
- contentTypes),
- http.StatusUnsupportedMediaType)
+ http.Error(w, fmt.Sprintf("Unsupported content type %q; expected one of %q", r.Header.Get("Content-Type"), contentTypes), http.StatusUnsupportedMediaType)
})
}
@@ -136,12 +160,12 @@ const (
// Form method takes precedence over header method.
func HTTPMethodOverrideHandler(h http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- if r.Method == http.MethodPost {
+ if r.Method == "POST" {
om := r.FormValue(HTTPMethodOverrideFormKey)
if om == "" {
om = r.Header.Get(HTTPMethodOverrideHeader)
}
- if om == http.MethodPut || om == http.MethodPatch || om == http.MethodDelete {
+ if om == "PUT" || om == "PATCH" || om == "DELETE" {
r.Method = om
}
}
diff --git a/git-sensor/vendor/github.com/gorilla/handlers/handlers_go18.go b/git-sensor/vendor/github.com/gorilla/handlers/handlers_go18.go
new file mode 100644
index 000000000..40f69146b
--- /dev/null
+++ b/git-sensor/vendor/github.com/gorilla/handlers/handlers_go18.go
@@ -0,0 +1,29 @@
+// +build go1.8
+
+package handlers
+
+import (
+ "fmt"
+ "net/http"
+)
+
+type loggingResponseWriter interface {
+ commonLoggingResponseWriter
+ http.Pusher
+}
+
+func (l *responseLogger) Push(target string, opts *http.PushOptions) error {
+ p, ok := l.w.(http.Pusher)
+ if !ok {
+ return fmt.Errorf("responseLogger does not implement http.Pusher")
+ }
+ return p.Push(target, opts)
+}
+
+func (c *compressResponseWriter) Push(target string, opts *http.PushOptions) error {
+ p, ok := c.ResponseWriter.(http.Pusher)
+ if !ok {
+ return fmt.Errorf("compressResponseWriter does not implement http.Pusher")
+ }
+ return p.Push(target, opts)
+}
diff --git a/git-sensor/vendor/github.com/gorilla/handlers/handlers_pre18.go b/git-sensor/vendor/github.com/gorilla/handlers/handlers_pre18.go
new file mode 100644
index 000000000..197836abb
--- /dev/null
+++ b/git-sensor/vendor/github.com/gorilla/handlers/handlers_pre18.go
@@ -0,0 +1,7 @@
+// +build !go1.8
+
+package handlers
+
+type loggingResponseWriter interface {
+ commonLoggingResponseWriter
+}
diff --git a/git-sensor/vendor/github.com/gorilla/handlers/logging.go b/git-sensor/vendor/github.com/gorilla/handlers/logging.go
index 2badb6fbf..88c25e72d 100644
--- a/git-sensor/vendor/github.com/gorilla/handlers/logging.go
+++ b/git-sensor/vendor/github.com/gorilla/handlers/logging.go
@@ -12,13 +12,11 @@ import (
"strconv"
"time"
"unicode/utf8"
-
- "github.com/felixge/httpsnoop"
)
// Logging
-// LogFormatterParams is the structure any formatter will be handed when time to log comes.
+// LogFormatterParams is the structure any formatter will be handed when time to log comes
type LogFormatterParams struct {
Request *http.Request
URL url.URL
@@ -27,7 +25,7 @@ type LogFormatterParams struct {
Size int
}
-// LogFormatter gives the signature of the formatter function passed to CustomLoggingHandler.
+// LogFormatter gives the signature of the formatter function passed to CustomLoggingHandler
type LogFormatter func(writer io.Writer, params LogFormatterParams)
// loggingHandler is the http.Handler implementation for LoggingHandlerTo and its
@@ -41,15 +39,12 @@ type loggingHandler struct {
func (h loggingHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
t := time.Now()
- logger, w := makeLogger(w)
+ logger := makeLogger(w)
url := *req.URL
- h.handler.ServeHTTP(w, req)
+ h.handler.ServeHTTP(logger, req)
if req.MultipartForm != nil {
- err := req.MultipartForm.RemoveAll()
- if err != nil {
- return
- }
+ req.MultipartForm.RemoveAll()
}
params := LogFormatterParams{
@@ -63,23 +58,34 @@ func (h loggingHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
h.formatter(h.writer, params)
}
-func makeLogger(w http.ResponseWriter) (*responseLogger, http.ResponseWriter) {
- logger := &responseLogger{w: w, status: http.StatusOK}
- return logger, httpsnoop.Wrap(w, httpsnoop.Hooks{
- Write: func(httpsnoop.WriteFunc) httpsnoop.WriteFunc {
- return logger.Write
- },
- WriteHeader: func(httpsnoop.WriteHeaderFunc) httpsnoop.WriteHeaderFunc {
- return logger.WriteHeader
- },
- })
+func makeLogger(w http.ResponseWriter) loggingResponseWriter {
+ var logger loggingResponseWriter = &responseLogger{w: w, status: http.StatusOK}
+ if _, ok := w.(http.Hijacker); ok {
+ logger = &hijackLogger{responseLogger{w: w, status: http.StatusOK}}
+ }
+ h, ok1 := logger.(http.Hijacker)
+ c, ok2 := w.(http.CloseNotifier)
+ if ok1 && ok2 {
+ return hijackCloseNotifier{logger, h, c}
+ }
+ if ok2 {
+ return &closeNotifyWriter{logger, c}
+ }
+ return logger
+}
+
+type commonLoggingResponseWriter interface {
+ http.ResponseWriter
+ http.Flusher
+ Status() int
+ Size() int
}
const lowerhex = "0123456789abcdef"
func appendQuoted(buf []byte, s string) []byte {
var runeTmp [utf8.UTFMax]byte
- for width := 0; len(s) > 0; s = s[width:] { //nolint: wastedassign //TODO: why width starts from 0and reassigned as 1
+ for width := 0; len(s) > 0; s = s[width:] {
r := rune(s[0])
width = 1
if r >= utf8.RuneSelf {
@@ -139,6 +145,7 @@ func appendQuoted(buf []byte, s string) []byte {
}
}
return buf
+
}
// buildCommonLogLine builds a log entry for req in Apache Common Log Format.
@@ -153,6 +160,7 @@ func buildCommonLogLine(req *http.Request, url url.URL, ts time.Time, status int
}
host, _, err := net.SplitHostPort(req.RemoteAddr)
+
if err != nil {
host = req.RemoteAddr
}
@@ -194,7 +202,7 @@ func buildCommonLogLine(req *http.Request, url url.URL, ts time.Time, status int
func writeLog(writer io.Writer, params LogFormatterParams) {
buf := buildCommonLogLine(params.Request, params.URL, params.TimeStamp, params.StatusCode, params.Size)
buf = append(buf, '\n')
- _, _ = writer.Write(buf)
+ writer.Write(buf)
}
// writeCombinedLog writes a log entry for req to w in Apache Combined Log Format.
@@ -207,7 +215,7 @@ func writeCombinedLog(writer io.Writer, params LogFormatterParams) {
buf = append(buf, `" "`...)
buf = appendQuoted(buf, params.Request.UserAgent())
buf = append(buf, '"', '\n')
- _, _ = writer.Write(buf)
+ writer.Write(buf)
}
// CombinedLoggingHandler return a http.Handler that wraps h and logs requests to out in
@@ -215,7 +223,7 @@ func writeCombinedLog(writer io.Writer, params LogFormatterParams) {
//
// See http://httpd.apache.org/docs/2.2/logs.html#combined for a description of this format.
//
-// LoggingHandler always sets the ident field of the log to -.
+// LoggingHandler always sets the ident field of the log to -
func CombinedLoggingHandler(out io.Writer, h http.Handler) http.Handler {
return loggingHandler{out, h, writeCombinedLog}
}
@@ -229,18 +237,19 @@ func CombinedLoggingHandler(out io.Writer, h http.Handler) http.Handler {
//
// Example:
//
-// r := mux.NewRouter()
-// r.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
-// w.Write([]byte("This is a catch-all route"))
-// })
-// loggedRouter := handlers.LoggingHandler(os.Stdout, r)
-// http.ListenAndServe(":1123", loggedRouter)
+// r := mux.NewRouter()
+// r.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
+// w.Write([]byte("This is a catch-all route"))
+// })
+// loggedRouter := handlers.LoggingHandler(os.Stdout, r)
+// http.ListenAndServe(":1123", loggedRouter)
+//
func LoggingHandler(out io.Writer, h http.Handler) http.Handler {
return loggingHandler{out, h, writeLog}
}
// CustomLoggingHandler provides a way to supply a custom log formatter
-// while taking advantage of the mechanisms in this package.
+// while taking advantage of the mechanisms in this package
func CustomLoggingHandler(out io.Writer, h http.Handler, f LogFormatter) http.Handler {
return loggingHandler{out, h, f}
}
diff --git a/git-sensor/vendor/github.com/gorilla/handlers/proxy_headers.go b/git-sensor/vendor/github.com/gorilla/handlers/proxy_headers.go
index 281d753e9..ed939dcef 100644
--- a/git-sensor/vendor/github.com/gorilla/handlers/proxy_headers.go
+++ b/git-sensor/vendor/github.com/gorilla/handlers/proxy_headers.go
@@ -18,7 +18,7 @@ var (
var (
// RFC7239 defines a new "Forwarded: " header designed to replace the
// existing use of X-Forwarded-* headers.
- // e.g. Forwarded: for=192.0.2.60;proto=https;by=203.0.113.43.
+ // e.g. Forwarded: for=192.0.2.60;proto=https;by=203.0.113.43
forwarded = http.CanonicalHeaderKey("Forwarded")
// Allows for a sub-match of the first value after 'for=' to the next
// comma, semi-colon or space. The match is case-insensitive.
@@ -67,9 +67,7 @@ func ProxyHeaders(h http.Handler) http.Handler {
func getIP(r *http.Request) string {
var addr string
- switch {
- case r.Header.Get(xForwardedFor) != "":
- fwd := r.Header.Get(xForwardedFor)
+ if fwd := r.Header.Get(xForwardedFor); fwd != "" {
// Only grab the first (client) address. Note that '192.168.0.1,
// 10.1.1.1' is a valid key for X-Forwarded-For where addresses after
// the first may represent forwarding proxies earlier in the chain.
@@ -78,15 +76,17 @@ func getIP(r *http.Request) string {
s = len(fwd)
}
addr = fwd[:s]
- case r.Header.Get(xRealIP) != "":
- addr = r.Header.Get(xRealIP)
- case r.Header.Get(forwarded) != "":
+ } else if fwd := r.Header.Get(xRealIP); fwd != "" {
+ // X-Real-IP should only contain one IP address (the client making the
+ // request).
+ addr = fwd
+ } else if fwd := r.Header.Get(forwarded); fwd != "" {
// match should contain at least two elements if the protocol was
// specified in the Forwarded header. The first element will always be
// the 'for=' capture, which we ignore. In the case of multiple IP
// addresses (for=8.8.8.8, 8.8.4.4,172.16.1.20 is valid) we only
// extract the first, which should be the client IP.
- if match := forRegex.FindStringSubmatch(r.Header.Get(forwarded)); len(match) > 1 {
+ if match := forRegex.FindStringSubmatch(fwd); len(match) > 1 {
// IPv6 addresses in Forwarded headers are quoted-strings. We strip
// these quotes.
addr = strings.Trim(match[1], `"`)
diff --git a/git-sensor/vendor/github.com/gorilla/handlers/recovery.go b/git-sensor/vendor/github.com/gorilla/handlers/recovery.go
index 0d4f955ec..b1be9dc83 100644
--- a/git-sensor/vendor/github.com/gorilla/handlers/recovery.go
+++ b/git-sensor/vendor/github.com/gorilla/handlers/recovery.go
@@ -19,7 +19,7 @@ type recoveryHandler struct {
// RecoveryOption provides a functional approach to define
// configuration for a handler; such as setting the logging
-// whether or not to print stack traces on panic.
+// whether or not to print strack traces on panic.
type RecoveryOption func(http.Handler)
func parseRecoveryOptions(h http.Handler, opts ...RecoveryOption) http.Handler {
@@ -36,12 +36,12 @@ func parseRecoveryOptions(h http.Handler, opts ...RecoveryOption) http.Handler {
//
// Example:
//
-// r := mux.NewRouter()
-// r.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
-// panic("Unexpected error!")
-// })
+// r := mux.NewRouter()
+// r.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
+// panic("Unexpected error!")
+// })
//
-// http.ListenAndServe(":1123", handlers.RecoveryHandler()(r))
+// http.ListenAndServe(":1123", handlers.RecoveryHandler()(r))
func RecoveryHandler(opts ...RecoveryOption) func(h http.Handler) http.Handler {
return func(h http.Handler) http.Handler {
r := &recoveryHandler{handler: h}
@@ -50,22 +50,20 @@ func RecoveryHandler(opts ...RecoveryOption) func(h http.Handler) http.Handler {
}
// RecoveryLogger is a functional option to override
-// the default logger.
+// the default logger
func RecoveryLogger(logger RecoveryHandlerLogger) RecoveryOption {
return func(h http.Handler) {
- r := h.(*recoveryHandler) //nolint:errcheck //TODO:
- // @bharat-rajani should return type-assertion error but would break the API?
+ r := h.(*recoveryHandler)
r.logger = logger
}
}
// PrintRecoveryStack is a functional option to enable
// or disable printing stack traces on panic.
-func PrintRecoveryStack(shouldPrint bool) RecoveryOption {
+func PrintRecoveryStack(print bool) RecoveryOption {
return func(h http.Handler) {
- r := h.(*recoveryHandler) //nolint:errcheck //TODO:
- // @bharat-rajani should return type-assertion error but would break the API?
- r.printStack = shouldPrint
+ r := h.(*recoveryHandler)
+ r.printStack = print
}
}
@@ -88,11 +86,6 @@ func (h recoveryHandler) log(v ...interface{}) {
}
if h.printStack {
- stack := string(debug.Stack())
- if h.logger != nil {
- h.logger.Println(stack)
- } else {
- log.Println(stack)
- }
+ debug.PrintStack()
}
}
diff --git a/git-sensor/vendor/github.com/skeema/knownhosts/NOTICE b/git-sensor/vendor/github.com/skeema/knownhosts/NOTICE
index 224b20248..a92cb34d6 100644
--- a/git-sensor/vendor/github.com/skeema/knownhosts/NOTICE
+++ b/git-sensor/vendor/github.com/skeema/knownhosts/NOTICE
@@ -1,4 +1,4 @@
-Copyright 2025 Skeema LLC and the Skeema Knownhosts authors
+Copyright 2024 Skeema LLC and the Skeema Knownhosts authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/git-sensor/vendor/github.com/skeema/knownhosts/README.md b/git-sensor/vendor/github.com/skeema/knownhosts/README.md
index 170e04d14..046bc0edc 100644
--- a/git-sensor/vendor/github.com/skeema/knownhosts/README.md
+++ b/git-sensor/vendor/github.com/skeema/knownhosts/README.md
@@ -116,7 +116,7 @@ config := &ssh.ClientConfig{
## License
-**Source code copyright 2025 Skeema LLC and the Skeema Knownhosts authors**
+**Source code copyright 2024 Skeema LLC and the Skeema Knownhosts authors**
```text
Licensed under the Apache License, Version 2.0 (the "License");
diff --git a/git-sensor/vendor/github.com/tidwall/gjson/README.md b/git-sensor/vendor/github.com/tidwall/gjson/README.md
index 387766d50..b7848de60 100644
--- a/git-sensor/vendor/github.com/tidwall/gjson/README.md
+++ b/git-sensor/vendor/github.com/tidwall/gjson/README.md
@@ -1,14 +1,10 @@
get json values quickly
@@ -18,10 +14,6 @@ It has features such as [one line retrieval](#get-a-value), [dot notation paths] Also check out [SJSON](https://github.com/tidwall/sjson) for modifying json, and the [JJ](https://github.com/tidwall/jj) command line tool. -This README is a quick overview of how to use GJSON, for more information check out [GJSON Syntax](SYNTAX.md). - -GJSON is also available for [Python](https://github.com/volans-/gjson-py) and [Rust](https://github.com/tidwall/gjson.rs) - Getting Started =============== @@ -178,7 +170,7 @@ The `result.Int()` and `result.Uint()` calls are capable of reading all 64 bits, ```go result.Int() int64 // -9223372036854775808 to 9223372036854775807 -result.Uint() uint64 // 0 to 18446744073709551615 +result.Uint() int64 // 0 to 18446744073709551615 ``` ## Modifiers and path chaining @@ -208,12 +200,6 @@ There are currently the following built-in modifiers: - `@valid`: Ensure the json document is valid. - `@flatten`: Flattens an array. - `@join`: Joins multiple objects into a single object. -- `@keys`: Returns an array of keys for an object. -- `@values`: Returns an array of values for an object. -- `@tostr`: Converts json to a string. Wraps a json string. -- `@fromstr`: Converts a string from json. Unwraps a json string. -- `@group`: Groups arrays of objects. See [e4fc67c](https://github.com/tidwall/gjson/commit/e4fc67c92aeebf2089fabc7872f010e340d105db). -- `@dig`: Search for a value without providing its entire path. See [e8e87f2](https://github.com/tidwall/gjson/commit/e8e87f2a00dc41f3aba5631094e21f59a8cf8cbf). ### Modifier arguments @@ -429,6 +415,16 @@ if result.Index > 0 { This is a best-effort no allocation sub slice of the original json. This method utilizes the `result.Index` field, which is the position of the raw data in the original json. It's possible that the value of `result.Index` equals zero, in which case the `result.Raw` is converted to a `[]byte`. +## Get multiple values at once + +The `GetMany` function can be used to get multiple values at the same time. + +```go +results := gjson.GetMany(json, "name.first", "name.last", "age") +``` + +The return value is a `[]Result`, which will always contain exactly the same number of items as the input paths. + ## Performance Benchmarks of GJSON alongside [encoding/json](https://golang.org/pkg/encoding/json/), @@ -438,15 +434,14 @@ Benchmarks of GJSON alongside [encoding/json](https://golang.org/pkg/encoding/js and [json-iterator](https://github.com/json-iterator/go) ``` -BenchmarkGJSONGet-10 17893731 202.1 ns/op 0 B/op 0 allocs/op -BenchmarkGJSONUnmarshalMap-10 1663548 2157 ns/op 1920 B/op 26 allocs/op -BenchmarkJSONUnmarshalMap-10 832236 4279 ns/op 2920 B/op 68 allocs/op -BenchmarkJSONUnmarshalStruct-10 1076475 3219 ns/op 920 B/op 12 allocs/op -BenchmarkJSONDecoder-10 585729 6126 ns/op 3845 B/op 160 allocs/op -BenchmarkFFJSONLexer-10 2508573 1391 ns/op 880 B/op 8 allocs/op -BenchmarkEasyJSONLexer-10 3000000 537.9 ns/op 501 B/op 5 allocs/op -BenchmarkJSONParserGet-10 13707510 263.9 ns/op 21 B/op 0 allocs/op -BenchmarkJSONIterator-10 3000000 561.2 ns/op 693 B/op 14 allocs/op +BenchmarkGJSONGet-8 3000000 372 ns/op 0 B/op 0 allocs/op +BenchmarkGJSONUnmarshalMap-8 900000 4154 ns/op 1920 B/op 26 allocs/op +BenchmarkJSONUnmarshalMap-8 600000 9019 ns/op 3048 B/op 69 allocs/op +BenchmarkJSONDecoder-8 300000 14120 ns/op 4224 B/op 184 allocs/op +BenchmarkFFJSONLexer-8 1500000 3111 ns/op 896 B/op 8 allocs/op +BenchmarkEasyJSONLexer-8 3000000 887 ns/op 613 B/op 6 allocs/op +BenchmarkJSONParserGet-8 3000000 499 ns/op 21 B/op 0 allocs/op +BenchmarkJSONIterator-8 3000000 812 ns/op 544 B/op 9 allocs/op ``` JSON document used: @@ -487,6 +482,4 @@ widget.image.hOffset widget.text.onMouseUp ``` -** - -*These benchmarks were run on a MacBook Pro M1 Max using Go 1.22 and can be found [here](https://github.com/tidwall/gjson-benchmarks).* +*These benchmarks were run on a MacBook Pro 15" 2.8 GHz Intel Core i7 using Go 1.8 and can be found [here](https://github.com/tidwall/gjson-benchmarks).* diff --git a/git-sensor/vendor/github.com/tidwall/gjson/SYNTAX.md b/git-sensor/vendor/github.com/tidwall/gjson/SYNTAX.md index a3f0fac23..34fdccf47 100644 --- a/git-sensor/vendor/github.com/tidwall/gjson/SYNTAX.md +++ b/git-sensor/vendor/github.com/tidwall/gjson/SYNTAX.md @@ -1,6 +1,6 @@ # GJSON Path Syntax -A GJSON Path is a text string syntax that describes a search pattern for quickly retrieving values from a JSON payload. +A GJSON Path is a text string syntax that describes a search pattern for quickly retreiving values from a JSON payload. This document is designed to explain the structure of a GJSON Path through examples. @@ -13,16 +13,16 @@ This document is designed to explain the structure of a GJSON Path through examp - [Dot vs Pipe](#dot-vs-pipe) - [Modifiers](#modifiers) - [Multipaths](#multipaths) -- [Literals](#literals) -The definitive implementation is [github.com/tidwall/gjson](https://github.com/tidwall/gjson). +The definitive implemenation is [github.com/tidwall/gjson](https://github.com/tidwall/gjson). Use the [GJSON Playground](https://gjson.dev) to experiment with the syntax online. + ## Path structure -A GJSON Path is intended to be easily expressed as a series of components separated by a `.` character. +A GJSON Path is intended to be easily expressed as a series of components seperated by a `.` character. -Along with `.` character, there are a few more that have special meaning, including `|`, `#`, `@`, `\`, `*`, `!`, and `?`. +Along with `.` character, there are a few more that have special meaning, including `|`, `#`, `@`, `\`, `*`, and `?`. ## Example @@ -46,7 +46,7 @@ The following GJSON Paths evaluate to the accompanying values. ### Basic -In many cases you'll just want to retrieve values by object name or array index. +In many cases you'll just want to retreive values by object name or array index. ```go name.last "Anderson" @@ -77,7 +77,7 @@ Special purpose characters, such as `.`, `*`, and `?` can be escaped with `\`. fav\.movie "Deer Hunter" ``` -You'll also need to make sure that the `\` character is correctly escaped when hardcoding a path in your source code. +You'll also need to make sure that the `\` character is correctly escaped when hardcoding a path in you source code. ```go // Go @@ -137,21 +137,12 @@ next major release.* The `~` (tilde) operator will convert a value to a boolean before comparison. -Supported tilde comparison type are: - -``` -~true Converts true-ish values to true -~false Converts false-ish and non-existent values to true -~null Converts null and non-existent values to true -~* Converts any existing value to true -``` - For example, using the following JSON: ```json { "vals": [ - { "a": 1, "b": "data" }, + { "a": 1, "b": true }, { "a": 2, "b": true }, { "a": 3, "b": false }, { "a": 4, "b": "0" }, @@ -166,23 +157,15 @@ For example, using the following JSON: } ``` -To query for all true-ish or false-ish values: +You can now query for all true(ish) or false(ish) values: ``` -vals.#(b==~true)#.a >> [2,6,7,8] +vals.#(b==~true)#.a >> [1,2,6,7,8] vals.#(b==~false)#.a >> [3,4,5,9,10,11] ``` The last value which was non-existent is treated as `false` -To query for null and explicit value existence: - -``` -vals.#(b==~null)#.a >> [10,11] -vals.#(b==~*)#.a >> [1,2,3,4,5,6,7,8,9,10] -vals.#(b!=~*)#.a >> [11] -``` - ### Dot vs Pipe The `.` is standard separator, but it's also possible to use a `|`. @@ -253,12 +236,6 @@ There are currently the following built-in modifiers: - `@valid`: Ensure the json document is valid. - `@flatten`: Flattens an array. - `@join`: Joins multiple objects into a single object. -- `@keys`: Returns an array of keys for an object. -- `@values`: Returns an array of values for an object. -- `@tostr`: Converts json to a string. Wraps a json string. -- `@fromstr`: Converts a string from json. Unwraps a json string. -- `@group`: Groups arrays of objects. See [e4fc67c](https://github.com/tidwall/gjson/commit/e4fc67c92aeebf2089fabc7872f010e340d105db). -- `@dig`: Search for a value without providing its entire path. See [e8e87f2](https://github.com/tidwall/gjson/commit/e8e87f2a00dc41f3aba5631094e21f59a8cf8cbf). #### Modifier arguments @@ -317,7 +294,7 @@ Starting with v1.3.0, GJSON added the ability to join multiple paths together to form new documents. Wrapping comma-separated paths between `[...]` or `{...}` will result in a new array or object, respectively. -For example, using the given multipath: +For example, using the given multipath ``` {name.first,age,"the_murphys":friends.#(last="Murphy")#.first} @@ -333,28 +310,8 @@ determined, then "_" is used. This results in -```json -{"first":"Tom","age":37,"the_murphys":["Dale","Jane"]} -``` - -### Literals - -Starting with v1.12.0, GJSON added support of json literals, which provides a way for constructing static blocks of json. This is can be particularly useful when constructing a new json document using [multipaths](#multipaths). - -A json literal begins with the '!' declaration character. - -For example, using the given multipath: - ``` -{name.first,age,"company":!"Happysoft","employed":!true} +{"first":"Tom","age":37,"the_murphys":["Dale","Jane"]} ``` -Here we selected the first name and age. Then add two new fields, "company" and "employed". - -This results in - -```json -{"first":"Tom","age":37,"company":"Happysoft","employed":true} -``` -*See issue [#249](https://github.com/tidwall/gjson/issues/249) for additional context on JSON Literals.* diff --git a/git-sensor/vendor/github.com/tidwall/gjson/gjson.go b/git-sensor/vendor/github.com/tidwall/gjson/gjson.go index 5aa2a4ffa..95d210b23 100644 --- a/git-sensor/vendor/github.com/tidwall/gjson/gjson.go +++ b/git-sensor/vendor/github.com/tidwall/gjson/gjson.go @@ -2,6 +2,7 @@ package gjson import ( + "encoding/json" "strconv" "strings" "time" @@ -188,15 +189,14 @@ func (t Result) Time() time.Time { } // Array returns back an array of values. -// If the result represents a null value or is non-existent, then an empty -// array will be returned. -// If the result is not a JSON array, the return value will be an +// If the result represents a non-existent value, then an empty array will be +// returned. If the result is not a JSON array, the return value will be an // array containing one result. func (t Result) Array() []Result { if t.Type == Null { return []Result{} } - if !t.IsArray() { + if t.Type != JSON { return []Result{t} } r := t.arrayOrMap('[', false) @@ -213,11 +213,6 @@ func (t Result) IsArray() bool { return t.Type == JSON && len(t.Raw) > 0 && t.Raw[0] == '[' } -// IsBool returns true if the result value is a JSON boolean. -func (t Result) IsBool() bool { - return t.Type == True || t.Type == False -} - // ForEach iterates through values. // If the result represents a non-existent value, then no values will be // iterated. If the result is an Object, the iterator will pass the key and @@ -233,19 +228,17 @@ func (t Result) ForEach(iterator func(key, value Result) bool) { return } json := t.Raw - var obj bool + var keys bool var i int var key, value Result for ; i < len(json); i++ { if json[i] == '{' { i++ key.Type = String - obj = true + keys = true break } else if json[i] == '[' { i++ - key.Type = Number - key.Num = -1 break } if json[i] > ' ' { @@ -255,9 +248,8 @@ func (t Result) ForEach(iterator func(key, value Result) bool) { var str string var vesc bool var ok bool - var idx int for ; i < len(json); i++ { - if obj { + if keys { if json[i] != '"' { continue } @@ -272,9 +264,7 @@ func (t Result) ForEach(iterator func(key, value Result) bool) { key.Str = str[1 : len(str)-1] } key.Raw = str - key.Index = s + t.Index - } else { - key.Num += 1 + key.Index = s } for ; i < len(json); i++ { if json[i] <= ' ' || json[i] == ',' || json[i] == ':' { @@ -287,17 +277,10 @@ func (t Result) ForEach(iterator func(key, value Result) bool) { if !ok { return } - if t.Indexes != nil { - if idx < len(t.Indexes) { - value.Index = t.Indexes[idx] - } - } else { - value.Index = s + t.Index - } + value.Index = s if !iterator(key, value) { return } - idx++ } } @@ -314,15 +297,7 @@ func (t Result) Map() map[string]Result { // Get searches result for the specified path. // The result should be a JSON array or object. func (t Result) Get(path string) Result { - r := Get(t.Raw, path) - if r.Indexes != nil { - for i := 0; i < len(r.Indexes); i++ { - r.Indexes[i] += t.Index - } - } else { - r.Index += t.Index - } - return r + return Get(t.Raw, path) } type arrayOrMapResult struct { @@ -413,8 +388,6 @@ func (t Result) arrayOrMap(vc byte, valueize bool) (r arrayOrMapResult) { value.Raw, value.Str = tostr(json[i:]) value.Num = 0 } - value.Index = i + t.Index - i += len(value.Raw) - 1 if r.vc == '{' { @@ -441,17 +414,6 @@ func (t Result) arrayOrMap(vc byte, valueize bool) (r arrayOrMapResult) { } } end: - if t.Indexes != nil { - if len(t.Indexes) != len(r.a) { - for i := 0; i < len(r.a); i++ { - r.a[i].Index = 0 - } - } else { - for i := 0; i < len(r.a); i++ { - r.a[i].Index = t.Indexes[i] - } - } - } return } @@ -463,8 +425,7 @@ end: // use the Valid function first. func Parse(json string) Result { var value Result - i := 0 - for ; i < len(json); i++ { + for i := 0; i < len(json); i++ { if json[i] == '{' || json[i] == '[' { value.Type = JSON value.Raw = json[i:] // just take the entire raw @@ -474,20 +435,16 @@ func Parse(json string) Result { continue } switch json[i] { - case '+', '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', - 'i', 'I', 'N': - value.Type = Number - value.Raw, value.Num = tonum(json[i:]) - case 'n': - if i+1 < len(json) && json[i+1] != 'u' { - // nan + default: + if (json[i] >= '0' && json[i] <= '9') || json[i] == '-' { value.Type = Number value.Raw, value.Num = tonum(json[i:]) } else { - // null - value.Type = Null - value.Raw = tolit(json[i:]) + return Result{} } + case 'n': + value.Type = Null + value.Raw = tolit(json[i:]) case 't': value.Type = True value.Raw = tolit(json[i:]) @@ -497,14 +454,9 @@ func Parse(json string) Result { case '"': value.Type = String value.Raw, value.Str = tostr(json[i:]) - default: - return Result{} } break } - if value.Exists() { - value.Index = i - } return value } @@ -578,12 +530,20 @@ func tonum(json string) (raw string, num float64) { return } // could be a '+' or '-'. let's assume so. - } else if json[i] == ']' || json[i] == '}' { - // break on ']' or '}' - raw = json[:i] - num, _ = strconv.ParseFloat(raw, 64) - return + continue + } + if json[i] < ']' { + // probably a valid number + continue + } + if json[i] == 'e' || json[i] == 'E' { + // allow for exponential numbers + continue } + // likely a ']' or '}' + raw = json[:i] + num, _ = strconv.ParseFloat(raw, 64) + return } raw = json num, _ = strconv.ParseFloat(raw, 64) @@ -645,9 +605,9 @@ func tostr(json string) (raw string, str string) { // Exists returns true if value exists. // -// if gjson.Get(json, "name.last").Exists(){ -// println("value exists") -// } +// if gjson.Get(json, "name.last").Exists(){ +// println("value exists") +// } func (t Result) Exists() bool { return t.Type != Null || len(t.Raw) != 0 } @@ -661,6 +621,7 @@ func (t Result) Exists() bool { // nil, for JSON null // map[string]interface{}, for JSON objects // []interface{}, for JSON arrays +// func (t Result) Value() interface{} { if t.Type == String { return t.Str @@ -774,7 +735,7 @@ func parseArrayPath(path string) (r arrayPathResult) { } if path[i] == '.' { r.part = path[:i] - if !r.arrch && i < len(path)-1 && isDotPiperChar(path[i+1:]) { + if !r.arrch && i < len(path)-1 && isDotPiperChar(path[i+1]) { r.pipe = path[i+1:] r.piped = true } else { @@ -799,7 +760,7 @@ func parseArrayPath(path string) (r arrayPathResult) { // bad query, end now break } - if len(value) >= 2 && value[0] == '"' && + if len(value) > 2 && value[0] == '"' && value[len(value)-1] == '"' { value = value[1 : len(value)-1] if vesc { @@ -825,28 +786,19 @@ func parseArrayPath(path string) (r arrayPathResult) { } // splitQuery takes a query and splits it into three parts: -// -// path, op, middle, and right. -// +// path, op, middle, and right. // So for this query: -// -// #(first_name=="Murphy").last -// +// #(first_name=="Murphy").last // Becomes -// -// first_name # path -// =="Murphy" # middle -// .last # right -// +// first_name # path +// =="Murphy" # middle +// .last # right // Or, -// -// #(service_roles.#(=="one")).cap -// +// #(service_roles.#(=="one")).cap // Becomes -// -// service_roles.#(=="one") # path -// # middle -// .cap # right +// service_roles.#(=="one") # path +// # middle +// .cap # right func parseQuery(query string) ( path, op, value, remain string, i int, vesc, ok bool, ) { @@ -944,23 +896,8 @@ right: } // peek at the next byte and see if it's a '@', '[', or '{'. -func isDotPiperChar(s string) bool { - if DisableModifiers { - return false - } - c := s[0] - if c == '@' { - // check that the next component is *not* a modifier. - i := 1 - for ; i < len(s); i++ { - if s[i] == '.' || s[i] == '|' || s[i] == ':' { - break - } - } - _, ok := modifiers[s[1:i]] - return ok - } - return c == '[' || c == '{' +func isDotPiperChar(c byte) bool { + return !DisableModifiers && (c == '@' || c == '[' || c == '{') } type objectPathResult struct { @@ -982,7 +919,7 @@ func parseObjectPath(path string) (r objectPathResult) { } if path[i] == '.' { r.part = path[:i] - if i < len(path)-1 && isDotPiperChar(path[i+1:]) { + if i < len(path)-1 && isDotPiperChar(path[i+1]) { r.pipe = path[i+1:] r.piped = true } else { @@ -1012,13 +949,13 @@ func parseObjectPath(path string) (r objectPathResult) { continue } else if path[i] == '.' { r.part = string(epart) - if i < len(path)-1 && isDotPiperChar(path[i+1:]) { + if i < len(path)-1 && isDotPiperChar(path[i+1]) { r.pipe = path[i+1:] r.piped = true } else { r.path = path[i+1:] - r.more = true } + r.more = true return } else if path[i] == '|' { r.part = string(epart) @@ -1040,10 +977,6 @@ func parseObjectPath(path string) (r objectPathResult) { return } -var vchars = [256]byte{ - '"': 2, '{': 3, '(': 3, '[': 3, '}': 1, ')': 1, ']': 1, -} - func parseSquash(json string, i int) (int, string) { // expects that the lead character is a '[' or '{' or '(' // squash the value, ignoring all nested arrays and objects. @@ -1051,137 +984,43 @@ func parseSquash(json string, i int) (int, string) { s := i i++ depth := 1 - var c byte - for i < len(json) { - for i < len(json)-8 { - jslice := json[i : i+8] - c = vchars[jslice[0]] - if c != 0 { - i += 0 - goto token - } - c = vchars[jslice[1]] - if c != 0 { - i += 1 - goto token - } - c = vchars[jslice[2]] - if c != 0 { - i += 2 - goto token - } - c = vchars[jslice[3]] - if c != 0 { - i += 3 - goto token - } - c = vchars[jslice[4]] - if c != 0 { - i += 4 - goto token - } - c = vchars[jslice[5]] - if c != 0 { - i += 5 - goto token - } - c = vchars[jslice[6]] - if c != 0 { - i += 6 - goto token - } - c = vchars[jslice[7]] - if c != 0 { - i += 7 - goto token - } - i += 8 - } - c = vchars[json[i]] - if c == 0 { - i++ - continue - } - token: - if c == 2 { - // '"' string - i++ - s2 := i - nextquote: - for i < len(json)-8 { - jslice := json[i : i+8] - if jslice[0] == '"' { - i += 0 - goto strchkesc - } - if jslice[1] == '"' { - i += 1 - goto strchkesc - } - if jslice[2] == '"' { - i += 2 - goto strchkesc - } - if jslice[3] == '"' { - i += 3 - goto strchkesc - } - if jslice[4] == '"' { - i += 4 - goto strchkesc - } - if jslice[5] == '"' { - i += 5 - goto strchkesc - } - if jslice[6] == '"' { - i += 6 - goto strchkesc - } - if jslice[7] == '"' { - i += 7 - goto strchkesc - } - i += 8 - } - goto strchkstd - strchkesc: - if json[i-1] != '\\' { + for ; i < len(json); i++ { + if json[i] >= '"' && json[i] <= '}' { + switch json[i] { + case '"': i++ - continue - } - strchkstd: - for i < len(json) { - if json[i] > '\\' || json[i] != '"' { - i++ - continue - } - // look for an escaped slash - if json[i-1] == '\\' { - n := 0 - for j := i - 2; j > s2-1; j-- { - if json[j] != '\\' { - break - } - n++ + s2 := i + for ; i < len(json); i++ { + if json[i] > '\\' { + continue } - if n%2 == 0 { - i++ - goto nextquote + if json[i] == '"' { + // look for an escaped slash + if json[i-1] == '\\' { + n := 0 + for j := i - 2; j > s2-1; j-- { + if json[j] != '\\' { + break + } + n++ + } + if n%2 == 0 { + continue + } + } + break } } - break - } - } else { - // '{', '[', '(', '}', ']', ')' - // open close tokens - depth += int(c) - 2 - if depth == 0 { - i++ - return i, json[s:i] + case '{', '[', '(': + depth++ + case '}', ']', ')': + depth-- + if depth == 0 { + i++ + return i, json[s:i] + } } } - i++ } return i, json[s:] } @@ -1263,7 +1102,6 @@ func parseObject(c *parseContext, i int, path string) (int, bool) { } hit = pmatch && !rp.more for ; i < len(c.json); i++ { - var num bool switch c.json[i] { default: continue @@ -1311,13 +1149,15 @@ func parseObject(c *parseContext, i int, path string) (int, bool) { return i, true } } - case 'n': - if i+1 < len(c.json) && c.json[i+1] != 'u' { - num = true - break + case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': + i, val = parseNumber(c.json, i) + if hit { + c.value.Raw = val + c.value.Type = Number + c.value.Num, _ = strconv.ParseFloat(val, 64) + return i, true } - fallthrough - case 't', 'f': + case 't', 'f', 'n': vc := c.json[i] i, val = parseLiteral(c.json, i) if hit { @@ -1330,18 +1170,6 @@ func parseObject(c *parseContext, i int, path string) (int, bool) { } return i, true } - case '+', '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', - 'i', 'I', 'N': - num = true - } - if num { - i, val = parseNumber(c.json, i) - if hit { - c.value.Raw = val - c.value.Type = Number - c.value.Num, _ = strconv.ParseFloat(val, 64) - return i, true - } } break } @@ -1350,81 +1178,22 @@ func parseObject(c *parseContext, i int, path string) (int, bool) { } // matchLimit will limit the complexity of the match operation to avoid ReDos -// attacks from arbitrary inputs. +// attacks from arbritary inputs. // See the github.com/tidwall/match.MatchLimit function for more information. func matchLimit(str, pattern string) bool { matched, _ := match.MatchLimit(str, pattern, 10000) return matched } -func falseish(t Result) bool { - switch t.Type { - case Null: - return true - case False: - return true - case String: - b, err := strconv.ParseBool(strings.ToLower(t.Str)) - if err != nil { - return false - } - return !b - case Number: - return t.Num == 0 - default: - return false - } -} - -func trueish(t Result) bool { - switch t.Type { - case True: - return true - case String: - b, err := strconv.ParseBool(strings.ToLower(t.Str)) - if err != nil { - return false - } - return b - case Number: - return t.Num != 0 - default: - return false - } -} - -func nullish(t Result) bool { - return t.Type == Null -} - func queryMatches(rp *arrayPathResult, value Result) bool { rpv := rp.query.value - if len(rpv) > 0 { - if rpv[0] == '~' { - // convert to bool - rpv = rpv[1:] - var ish, ok bool - switch rpv { - case "*": - ish, ok = value.Exists(), true - case "null": - ish, ok = nullish(value), true - case "true": - ish, ok = trueish(value), true - case "false": - ish, ok = falseish(value), true - } - if ok { - rpv = "true" - if ish { - value = Result{Type: True} - } else { - value = Result{Type: False} - } - } else { - rpv = "" - value = Result{} - } + if len(rpv) > 0 && rpv[0] == '~' { + // convert to bool + rpv = rpv[1:] + if value.Bool() { + value = Result{Type: True} + } else { + value = Result{Type: False} } } if !value.Exists() { @@ -1588,7 +1357,6 @@ func parseArray(c *parseContext, i int, path string) (int, bool) { } else { ch = c.json[i] } - var num bool switch ch { default: continue @@ -1671,13 +1439,26 @@ func parseArray(c *parseContext, i int, path string) (int, bool) { return i, true } } - case 'n': - if i+1 < len(c.json) && c.json[i+1] != 'u' { - num = true - break + case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': + i, val = parseNumber(c.json, i) + if rp.query.on { + var qval Result + qval.Raw = val + qval.Type = Number + qval.Num, _ = strconv.ParseFloat(val, 64) + if procQuery(qval) { + return i, true + } + } else if hit { + if rp.alogok { + break + } + c.value.Raw = val + c.value.Type = Number + c.value.Num, _ = strconv.ParseFloat(val, 64) + return i, true } - fallthrough - case 't', 'f': + case 't', 'f', 'n': vc := c.json[i] i, val = parseLiteral(c.json, i) if rp.query.on { @@ -1705,9 +1486,6 @@ func parseArray(c *parseContext, i int, path string) (int, bool) { } return i, true } - case '+', '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', - 'i', 'I', 'N': - num = true case ']': if rp.arrch && rp.part == "#" { if rp.alogok { @@ -1732,6 +1510,7 @@ func parseArray(c *parseContext, i int, path string) (int, bool) { } if idx < len(c.json) && c.json[idx] != ']' { _, res, ok := parseAny(c.json, idx, true) + parentIndex := res.Index if ok { res := res.Get(rp.alogkey) if res.Exists() { @@ -1743,7 +1522,8 @@ func parseArray(c *parseContext, i int, path string) (int, bool) { raw = res.String() } jsons = append(jsons, []byte(raw)...) - indexes = append(indexes, res.Index) + indexes = append(indexes, + res.Index+parentIndex) k++ } } @@ -1781,26 +1561,6 @@ func parseArray(c *parseContext, i int, path string) (int, bool) { } return i + 1, false } - if num { - i, val = parseNumber(c.json, i) - if rp.query.on { - var qval Result - qval.Raw = val - qval.Type = Number - qval.Num, _ = strconv.ParseFloat(val, 64) - if procQuery(qval) { - return i, true - } - } else if hit { - if rp.alogok { - break - } - c.value.Raw = val - c.value.Type = Number - c.value.Num, _ = strconv.ParseFloat(val, 64) - return i, true - } - } break } } @@ -1916,7 +1676,7 @@ type subSelector struct { // first character in path is either '[' or '{', and has already been checked // prior to calling this function. func parseSubSelectors(path string) (sels []subSelector, out string, ok bool) { - modifier := 0 + modifer := 0 depth := 1 colon := 0 start := 1 @@ -1931,7 +1691,6 @@ func parseSubSelectors(path string) (sels []subSelector, out string, ok bool) { } sels = append(sels, sel) colon = 0 - modifier = 0 start = i + 1 } for ; i < len(path); i++ { @@ -1939,11 +1698,11 @@ func parseSubSelectors(path string) (sels []subSelector, out string, ok bool) { case '\\': i++ case '@': - if modifier == 0 && i > 0 && (path[i-1] == '.' || path[i-1] == '|') { - modifier = i + if modifer == 0 && i > 0 && (path[i-1] == '.' || path[i-1] == '|') { + modifer = i } case ':': - if modifier == 0 && colon == 0 && depth == 1 { + if modifer == 0 && colon == 0 && depth == 1 { colon = i } case ',': @@ -1996,86 +1755,24 @@ func isSimpleName(component string) bool { return false } switch component[i] { - case '[', ']', '{', '}', '(', ')', '#', '|', '!': + case '[', ']', '{', '}', '(', ')', '#', '|': return false } } return true } -var hexchars = [...]byte{ - '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', - 'a', 'b', 'c', 'd', 'e', 'f', -} - -func appendHex16(dst []byte, x uint16) []byte { - return append(dst, - hexchars[x>>12&0xF], hexchars[x>>8&0xF], - hexchars[x>>4&0xF], hexchars[x>>0&0xF], - ) -} - -// DisableEscapeHTML will disable the automatic escaping of certain -// "problamatic" HTML characters when encoding to JSON. -// These character include '>', '<' and '&', which get escaped to \u003e, -// \u0026, and \u003c respectively. -// -// This is a global flag and will affect all further gjson operations. -// Ideally, if used, it should be set one time before other gjson functions -// are called. -var DisableEscapeHTML = false - -// AppendJSONString is a convenience function that converts the provided string -// to a valid JSON string and appends it to dst. -func AppendJSONString(dst []byte, s string) []byte { - dst = append(dst, make([]byte, len(s)+2)...) - dst = append(dst[:len(dst)-len(s)-2], '"') +func appendJSONString(dst []byte, s string) []byte { for i := 0; i < len(s); i++ { - if s[i] < ' ' { - dst = append(dst, '\\') - switch s[i] { - case '\b': - dst = append(dst, 'b') - case '\f': - dst = append(dst, 'f') - case '\n': - dst = append(dst, 'n') - case '\r': - dst = append(dst, 'r') - case '\t': - dst = append(dst, 't') - default: - dst = append(dst, 'u') - dst = appendHex16(dst, uint16(s[i])) - } - } else if !DisableEscapeHTML && - (s[i] == '>' || s[i] == '<' || s[i] == '&') { - dst = append(dst, '\\', 'u') - dst = appendHex16(dst, uint16(s[i])) - } else if s[i] == '\\' { - dst = append(dst, '\\', '\\') - } else if s[i] == '"' { - dst = append(dst, '\\', '"') - } else if s[i] > 127 { - // read utf8 character - r, n := utf8.DecodeRuneInString(s[i:]) - if n == 0 { - break - } - if r == utf8.RuneError && n == 1 { - dst = append(dst, `\ufffd`...) - } else if r == '\u2028' || r == '\u2029' { - dst = append(dst, `\u202`...) - dst = append(dst, hexchars[r&0xF]) - } else { - dst = append(dst, s[i:i+n]...) - } - i = i + n - 1 - } else { - dst = append(dst, s[i]) + if s[i] < ' ' || s[i] == '\\' || s[i] == '"' || s[i] > 126 { + d, _ := json.Marshal(s) + return append(dst, string(d)...) } } - return append(dst, '"') + dst = append(dst, '"') + dst = append(dst, s...) + dst = append(dst, '"') + return dst } type parseContext struct { @@ -2098,23 +1795,23 @@ type parseContext struct { // the '#' character. // The dot and wildcard character can be escaped with '\'. // -// { -// "name": {"first": "Tom", "last": "Anderson"}, -// "age":37, -// "children": ["Sara","Alex","Jack"], -// "friends": [ -// {"first": "James", "last": "Murphy"}, -// {"first": "Roger", "last": "Craig"} -// ] -// } -// "name.last" >> "Anderson" -// "age" >> 37 -// "children" >> ["Sara","Alex","Jack"] -// "children.#" >> 3 -// "children.1" >> "Alex" -// "child*.2" >> "Jack" -// "c?ildren.0" >> "Sara" -// "friends.#.first" >> ["James","Roger"] +// { +// "name": {"first": "Tom", "last": "Anderson"}, +// "age":37, +// "children": ["Sara","Alex","Jack"], +// "friends": [ +// {"first": "James", "last": "Murphy"}, +// {"first": "Roger", "last": "Craig"} +// ] +// } +// "name.last" >> "Anderson" +// "age" >> 37 +// "children" >> ["Sara","Alex","Jack"] +// "children.#" >> 3 +// "children.1" >> "Alex" +// "child*.2" >> "Jack" +// "c?ildren.0" >> "Sara" +// "friends.#.first" >> ["James","Roger"] // // This function expects that the json is well-formed, and does not validate. // Invalid json will not panic, but it may return back unexpected results. @@ -2122,25 +1819,23 @@ type parseContext struct { // use the Valid function first. func Get(json, path string) Result { if len(path) > 1 { - if (path[0] == '@' && !DisableModifiers) || path[0] == '!' { - // possible modifier - var ok bool - var npath string - var rjson string - if path[0] == '@' && !DisableModifiers { + if !DisableModifiers { + if path[0] == '@' { + // possible modifier + var ok bool + var npath string + var rjson string npath, rjson, ok = execModifier(json, path) - } else if path[0] == '!' { - npath, rjson, ok = execStatic(json, path) - } - if ok { - path = npath - if len(path) > 0 && (path[0] == '|' || path[0] == '.') { - res := Get(rjson, path[1:]) - res.Index = 0 - res.Indexes = nil - return res + if ok { + path = npath + if len(path) > 0 && (path[0] == '|' || path[0] == '.') { + res := Get(rjson, path[1:]) + res.Index = 0 + res.Indexes = nil + return res + } + return Parse(rjson) } - return Parse(rjson) } } if path[0] == '[' || path[0] == '{' { @@ -2165,14 +1860,14 @@ func Get(json, path string) Result { if sub.name[0] == '"' && Valid(sub.name) { b = append(b, sub.name...) } else { - b = AppendJSONString(b, sub.name) + b = appendJSONString(b, sub.name) } } else { last := nameOfLast(sub.path) if isSimpleName(last) { - b = AppendJSONString(b, last) + b = appendJSONString(b, last) } else { - b = AppendJSONString(b, "_") + b = appendJSONString(b, "_") } } b = append(b, ':') @@ -2303,10 +1998,11 @@ func unescape(json string) string { } // Less return true if a token is less than another token. -// The caseSensitive parameter is used when the tokens are Strings. +// The caseSensitive paramater is used when the tokens are Strings. // The order when comparing two different type is: // -// Null < False < Number < String < True < JSON +// Null < False < Number < String < True < JSON +// func (t Result) Less(token Result, caseSensitive bool) bool { if t.Type < token.Type { return true @@ -2384,7 +2080,6 @@ func parseAny(json string, i int, hit bool) (int, Result, bool) { if json[i] <= ' ' { continue } - var num bool switch json[i] { case '"': i++ @@ -2404,13 +2099,15 @@ func parseAny(json string, i int, hit bool) (int, Result, bool) { } } return i, res, true - case 'n': - if i+1 < len(json) && json[i+1] != 'u' { - num = true - break + case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': + i, val = parseNumber(json, i) + if hit { + res.Raw = val + res.Type = Number + res.Num, _ = strconv.ParseFloat(val, 64) } - fallthrough - case 't', 'f': + return i, res, true + case 't', 'f', 'n': vc := json[i] i, val = parseLiteral(json, i) if hit { @@ -2423,20 +2120,7 @@ func parseAny(json string, i int, hit bool) (int, Result, bool) { } return i, res, true } - case '+', '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', - 'i', 'I', 'N': - num = true - } - if num { - i, val = parseNumber(json, i) - if hit { - res.Raw = val - res.Type = Number - res.Num, _ = strconv.ParseFloat(val, 64) - } - return i, res, true } - } return i, res, false } @@ -2735,10 +2419,11 @@ func validnull(data []byte, i int) (outi int, ok bool) { // Valid returns true if the input is valid json. // -// if !gjson.Valid(json) { -// return errors.New("invalid json") -// } -// value := gjson.Get(json, "name.last") +// if !gjson.Valid(json) { +// return errors.New("invalid json") +// } +// value := gjson.Get(json, "name.last") +// func Valid(json string) bool { _, ok := validpayload(stringBytes(json), 0) return ok @@ -2746,12 +2431,13 @@ func Valid(json string) bool { // ValidBytes returns true if the input is valid json. // -// if !gjson.Valid(json) { -// return errors.New("invalid json") -// } -// value := gjson.Get(json, "name.last") +// if !gjson.Valid(json) { +// return errors.New("invalid json") +// } +// value := gjson.Get(json, "name.last") // // If working with bytes, this method preferred over ValidBytes(string(data)) +// func ValidBytes(json []byte) bool { _, ok := validpayload(json, 0) return ok @@ -2806,40 +2492,8 @@ func safeInt(f float64) (n int64, ok bool) { return int64(f), true } -// execStatic parses the path to find a static value. -// The input expects that the path already starts with a '!' -func execStatic(json, path string) (pathOut, res string, ok bool) { - name := path[1:] - if len(name) > 0 { - switch name[0] { - case '{', '[', '"', '+', '-', '0', '1', '2', '3', '4', '5', '6', '7', - '8', '9': - _, res = parseSquash(name, 0) - pathOut = name[len(res):] - return pathOut, res, true - } - } - for i := 1; i < len(path); i++ { - if path[i] == '|' { - pathOut = path[i:] - name = path[1:i] - break - } - if path[i] == '.' { - pathOut = path[i:] - name = path[1:i] - break - } - } - switch strings.ToLower(name) { - case "true", "false", "null", "nan", "inf": - return pathOut, name, true - } - return pathOut, res, false -} - // execModifier parses the path to find a matching modifier function. -// The input expects that the path already starts with a '@' +// then input expects that the path already starts with a '@' func execModifier(json, path string) (pathOut, res string, ok bool) { name := path[1:] var hasArgs bool @@ -2867,7 +2521,6 @@ func execModifier(json, path string) (pathOut, res string, ok bool) { var parsedArgs bool switch pathOut[0] { case '{', '[', '"': - // json arg res := Parse(pathOut) if res.Exists() { args = squash(pathOut) @@ -2876,20 +2529,14 @@ func execModifier(json, path string) (pathOut, res string, ok bool) { } } if !parsedArgs { - // simple arg - i := 0 - for ; i < len(pathOut); i++ { - if pathOut[i] == '|' { - break - } - switch pathOut[i] { - case '{', '[', '"', '(': - s := squash(pathOut[i:]) - i += len(s) - 1 - } + idx := strings.IndexByte(pathOut, '|') + if idx == -1 { + args = pathOut + pathOut = "" + } else { + args = pathOut[:idx] + pathOut = pathOut[idx:] } - args = pathOut[:i] - pathOut = pathOut[i:] } } return pathOut, fn(json, args), true @@ -2909,24 +2556,14 @@ func unwrap(json string) string { // DisableModifiers will disable the modifier syntax var DisableModifiers = false -var modifiers map[string]func(json, arg string) string - -func init() { - modifiers = map[string]func(json, arg string) string{ - "pretty": modPretty, - "ugly": modUgly, - "reverse": modReverse, - "this": modThis, - "flatten": modFlatten, - "join": modJoin, - "valid": modValid, - "keys": modKeys, - "values": modValues, - "tostr": modToStr, - "fromstr": modFromStr, - "group": modGroup, - "dig": modDig, - } +var modifiers = map[string]func(json, arg string) string{ + "pretty": modPretty, + "ugly": modUgly, + "reverse": modReverse, + "this": modThis, + "flatten": modFlatten, + "join": modJoin, + "valid": modValid, } // AddModifier binds a custom modifier command to the GJSON syntax. @@ -3037,13 +2674,9 @@ func modReverse(json, arg string) string { } // @flatten an array with child arrays. -// -// [1,[2],[3,4],[5,[6,7]]] -> [1,2,3,4,5,[6,7]] -// +// [1,[2],[3,4],[5,[6,7]]] -> [1,2,3,4,5,[6,7]] // The {"deep":true} arg can be provide for deep flattening. -// -// [1,[2],[3,4],[5,[6,7]]] -> [1,2,3,4,5,6,7] -// +// [1,[2],[3,4],[5,[6,7]]] -> [1,2,3,4,5,6,7] // The original json is returned when the json is not an array. func modFlatten(json, arg string) string { res := Parse(json) @@ -3087,72 +2720,12 @@ func modFlatten(json, arg string) string { return bytesString(out) } -// @keys extracts the keys from an object. -// -// {"first":"Tom","last":"Smith"} -> ["first","last"] -func modKeys(json, arg string) string { - v := Parse(json) - if !v.Exists() { - return "[]" - } - obj := v.IsObject() - var out strings.Builder - out.WriteByte('[') - var i int - v.ForEach(func(key, _ Result) bool { - if i > 0 { - out.WriteByte(',') - } - if obj { - out.WriteString(key.Raw) - } else { - out.WriteString("null") - } - i++ - return true - }) - out.WriteByte(']') - return out.String() -} - -// @values extracts the values from an object. -// -// {"first":"Tom","last":"Smith"} -> ["Tom","Smith"] -func modValues(json, arg string) string { - v := Parse(json) - if !v.Exists() { - return "[]" - } - if v.IsArray() { - return json - } - var out strings.Builder - out.WriteByte('[') - var i int - v.ForEach(func(_, value Result) bool { - if i > 0 { - out.WriteByte(',') - } - out.WriteString(value.Raw) - i++ - return true - }) - out.WriteByte(']') - return out.String() -} - // @join multiple objects into a single object. -// -// [{"first":"Tom"},{"last":"Smith"}] -> {"first","Tom","last":"Smith"} -// +// [{"first":"Tom"},{"last":"Smith"}] -> {"first","Tom","last":"Smith"} // The arg can be "true" to specify that duplicate keys should be preserved. -// -// [{"first":"Tom","age":37},{"age":41}] -> {"first","Tom","age":37,"age":41} -// +// [{"first":"Tom","age":37},{"age":41}] -> {"first","Tom","age":37,"age":41} // Without preserved keys: -// -// [{"first":"Tom","age":37},{"age":41}] -> {"first","Tom","age":41} -// +// [{"first":"Tom","age":37},{"age":41}] -> {"first","Tom","age":41} // The original json is returned when the json is not an object. func modJoin(json, arg string) string { res := Parse(json) @@ -3224,58 +2797,6 @@ func modValid(json, arg string) string { return json } -// @fromstr converts a string to json -// -// "{\"id\":1023,\"name\":\"alert\"}" -> {"id":1023,"name":"alert"} -func modFromStr(json, arg string) string { - if !Valid(json) { - return "" - } - return Parse(json).String() -} - -// @tostr converts a string to json -// -// {"id":1023,"name":"alert"} -> "{\"id\":1023,\"name\":\"alert\"}" -func modToStr(str, arg string) string { - return string(AppendJSONString(nil, str)) -} - -func modGroup(json, arg string) string { - res := Parse(json) - if !res.IsObject() { - return "" - } - var all [][]byte - res.ForEach(func(key, value Result) bool { - if !value.IsArray() { - return true - } - var idx int - value.ForEach(func(_, value Result) bool { - if idx == len(all) { - all = append(all, []byte{}) - } - all[idx] = append(all[idx], ("," + key.Raw + ":" + value.Raw)...) - idx++ - return true - }) - return true - }) - var data []byte - data = append(data, '[') - for i, item := range all { - if i > 0 { - data = append(data, ',') - } - data = append(data, '{') - data = append(data, item[1:]...) - data = append(data, '}') - } - data = append(data, ']') - return string(data) -} - // stringHeader instead of reflect.StringHeader type stringHeader struct { data unsafe.Pointer @@ -3361,243 +2882,3 @@ func stringBytes(s string) []byte { func bytesString(b []byte) string { return *(*string)(unsafe.Pointer(&b)) } - -func revSquash(json string) string { - // reverse squash - // expects that the tail character is a ']' or '}' or ')' or '"' - // squash the value, ignoring all nested arrays and objects. - i := len(json) - 1 - var depth int - if json[i] != '"' { - depth++ - } - if json[i] == '}' || json[i] == ']' || json[i] == ')' { - i-- - } - for ; i >= 0; i-- { - switch json[i] { - case '"': - i-- - for ; i >= 0; i-- { - if json[i] == '"' { - esc := 0 - for i > 0 && json[i-1] == '\\' { - i-- - esc++ - } - if esc%2 == 1 { - continue - } - i += esc - break - } - } - if depth == 0 { - if i < 0 { - i = 0 - } - return json[i:] - } - case '}', ']', ')': - depth++ - case '{', '[', '(': - depth-- - if depth == 0 { - return json[i:] - } - } - } - return json -} - -// Paths returns the original GJSON paths for a Result where the Result came -// from a simple query path that returns an array, like: -// -// gjson.Get(json, "friends.#.first") -// -// The returned value will be in the form of a JSON array: -// -// ["friends.0.first","friends.1.first","friends.2.first"] -// -// The param 'json' must be the original JSON used when calling Get. -// -// Returns an empty string if the paths cannot be determined, which can happen -// when the Result came from a path that contained a multipath, modifier, -// or a nested query. -func (t Result) Paths(json string) []string { - if t.Indexes == nil { - return nil - } - paths := make([]string, 0, len(t.Indexes)) - t.ForEach(func(_, value Result) bool { - paths = append(paths, value.Path(json)) - return true - }) - if len(paths) != len(t.Indexes) { - return nil - } - return paths -} - -// Path returns the original GJSON path for a Result where the Result came -// from a simple path that returns a single value, like: -// -// gjson.Get(json, "friends.#(last=Murphy)") -// -// The returned value will be in the form of a JSON string: -// -// "friends.0" -// -// The param 'json' must be the original JSON used when calling Get. -// -// Returns an empty string if the paths cannot be determined, which can happen -// when the Result came from a path that contained a multipath, modifier, -// or a nested query. -func (t Result) Path(json string) string { - var path []byte - var comps []string // raw components - i := t.Index - 1 - if t.Index+len(t.Raw) > len(json) { - // JSON cannot safely contain Result. - goto fail - } - if !strings.HasPrefix(json[t.Index:], t.Raw) { - // Result is not at the JSON index as expected. - goto fail - } - for ; i >= 0; i-- { - if json[i] <= ' ' { - continue - } - if json[i] == ':' { - // inside of object, get the key - for ; i >= 0; i-- { - if json[i] != '"' { - continue - } - break - } - raw := revSquash(json[:i+1]) - i = i - len(raw) - comps = append(comps, raw) - // key gotten, now squash the rest - raw = revSquash(json[:i+1]) - i = i - len(raw) - i++ // increment the index for next loop step - } else if json[i] == '{' { - // Encountered an open object. The original result was probably an - // object key. - goto fail - } else if json[i] == ',' || json[i] == '[' { - // inside of an array, count the position - var arrIdx int - if json[i] == ',' { - arrIdx++ - i-- - } - for ; i >= 0; i-- { - if json[i] == ':' { - // Encountered an unexpected colon. The original result was - // probably an object key. - goto fail - } else if json[i] == ',' { - arrIdx++ - } else if json[i] == '[' { - comps = append(comps, strconv.Itoa(arrIdx)) - break - } else if json[i] == ']' || json[i] == '}' || json[i] == '"' { - raw := revSquash(json[:i+1]) - i = i - len(raw) + 1 - } - } - } - } - if len(comps) == 0 { - if DisableModifiers { - goto fail - } - return "@this" - } - for i := len(comps) - 1; i >= 0; i-- { - rcomp := Parse(comps[i]) - if !rcomp.Exists() { - goto fail - } - comp := Escape(rcomp.String()) - path = append(path, '.') - path = append(path, comp...) - } - if len(path) > 0 { - path = path[1:] - } - return string(path) -fail: - return "" -} - -// isSafePathKeyChar returns true if the input character is safe for not -// needing escaping. -func isSafePathKeyChar(c byte) bool { - return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || - (c >= '0' && c <= '9') || c <= ' ' || c > '~' || c == '_' || - c == '-' || c == ':' -} - -// Escape returns an escaped path component. -// -// json := `{ -// "user":{ -// "first.name": "Janet", -// "last.name": "Prichard" -// } -// }` -// user := gjson.Get(json, "user") -// println(user.Get(gjson.Escape("first.name")) -// println(user.Get(gjson.Escape("last.name")) -// // Output: -// // Janet -// // Prichard -func Escape(comp string) string { - for i := 0; i < len(comp); i++ { - if !isSafePathKeyChar(comp[i]) { - ncomp := make([]byte, len(comp)+1) - copy(ncomp, comp[:i]) - ncomp = ncomp[:i] - for ; i < len(comp); i++ { - if !isSafePathKeyChar(comp[i]) { - ncomp = append(ncomp, '\\') - } - ncomp = append(ncomp, comp[i]) - } - return string(ncomp) - } - } - return comp -} - -func parseRecursiveDescent(all []Result, parent Result, path string) []Result { - if res := parent.Get(path); res.Exists() { - all = append(all, res) - } - if parent.IsArray() || parent.IsObject() { - parent.ForEach(func(_, val Result) bool { - all = parseRecursiveDescent(all, val, path) - return true - }) - } - return all -} - -func modDig(json, arg string) string { - all := parseRecursiveDescent(nil, Parse(json), arg) - var out []byte - out = append(out, '[') - for i, res := range all { - if i > 0 { - out = append(out, ',') - } - out = append(out, res.Raw...) - } - out = append(out, ']') - return string(out) -} diff --git a/git-sensor/vendor/github.com/tidwall/gjson/logo.png b/git-sensor/vendor/github.com/tidwall/gjson/logo.png new file mode 100644 index 000000000..17a8bbe9d Binary files /dev/null and b/git-sensor/vendor/github.com/tidwall/gjson/logo.png differ diff --git a/git-sensor/vendor/github.com/tidwall/pretty/README.md b/git-sensor/vendor/github.com/tidwall/pretty/README.md index 76c06a5e5..d3be5e54e 100644 --- a/git-sensor/vendor/github.com/tidwall/pretty/README.md +++ b/git-sensor/vendor/github.com/tidwall/pretty/README.md @@ -59,7 +59,7 @@ Will format the json to: Color will colorize the json for outputing to the screen. -```go +```json result = pretty.Color(json, nil) ``` diff --git a/git-sensor/vendor/github.com/tidwall/pretty/pretty.go b/git-sensor/vendor/github.com/tidwall/pretty/pretty.go index d705f9cdb..f3f756aad 100644 --- a/git-sensor/vendor/github.com/tidwall/pretty/pretty.go +++ b/git-sensor/vendor/github.com/tidwall/pretty/pretty.go @@ -422,7 +422,6 @@ type Style struct { Key, String, Number [2]string True, False, Null [2]string Escape [2]string - Brackets [2]string Append func(dst []byte, c byte) []byte } @@ -440,14 +439,13 @@ var TerminalStyle *Style func init() { TerminalStyle = &Style{ - Key: [2]string{"\x1B[1m\x1B[94m", "\x1B[0m"}, - String: [2]string{"\x1B[32m", "\x1B[0m"}, - Number: [2]string{"\x1B[33m", "\x1B[0m"}, - True: [2]string{"\x1B[36m", "\x1B[0m"}, - False: [2]string{"\x1B[36m", "\x1B[0m"}, - Null: [2]string{"\x1B[2m", "\x1B[0m"}, - Escape: [2]string{"\x1B[35m", "\x1B[0m"}, - Brackets: [2]string{"\x1B[1m", "\x1B[0m"}, + Key: [2]string{"\x1B[94m", "\x1B[0m"}, + String: [2]string{"\x1B[92m", "\x1B[0m"}, + Number: [2]string{"\x1B[93m", "\x1B[0m"}, + True: [2]string{"\x1B[96m", "\x1B[0m"}, + False: [2]string{"\x1B[96m", "\x1B[0m"}, + Null: [2]string{"\x1B[91m", "\x1B[0m"}, + Escape: [2]string{"\x1B[35m", "\x1B[0m"}, Append: func(dst []byte, c byte) []byte { if c < ' ' && (c != '\r' && c != '\n' && c != '\t' && c != '\v') { dst = append(dst, "\\u00"...) @@ -541,19 +539,13 @@ func Color(src []byte, style *Style) []byte { } } else if src[i] == '{' || src[i] == '[' { stack = append(stack, stackt{src[i], src[i] == '{'}) - dst = append(dst, style.Brackets[0]...) dst = apnd(dst, src[i]) - dst = append(dst, style.Brackets[1]...) } else if (src[i] == '}' || src[i] == ']') && len(stack) > 0 { stack = stack[:len(stack)-1] - dst = append(dst, style.Brackets[0]...) dst = apnd(dst, src[i]) - dst = append(dst, style.Brackets[1]...) } else if (src[i] == ':' || src[i] == ',') && len(stack) > 0 && stack[len(stack)-1].kind == '{' { stack[len(stack)-1].key = !stack[len(stack)-1].key - dst = append(dst, style.Brackets[0]...) dst = apnd(dst, src[i]) - dst = append(dst, style.Brackets[1]...) } else { var kind byte if (src[i] >= '0' && src[i] <= '9') || src[i] == '-' || isNaNOrInf(src[i:]) { diff --git a/git-sensor/vendor/golang.org/x/crypto/cryptobyte/asn1.go b/git-sensor/vendor/golang.org/x/crypto/cryptobyte/asn1.go deleted file mode 100644 index d25979d9f..000000000 --- a/git-sensor/vendor/golang.org/x/crypto/cryptobyte/asn1.go +++ /dev/null @@ -1,825 +0,0 @@ -// Copyright 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package cryptobyte - -import ( - encoding_asn1 "encoding/asn1" - "fmt" - "math/big" - "reflect" - "time" - - "golang.org/x/crypto/cryptobyte/asn1" -) - -// This file contains ASN.1-related methods for String and Builder. - -// Builder - -// AddASN1Int64 appends a DER-encoded ASN.1 INTEGER. -func (b *Builder) AddASN1Int64(v int64) { - b.addASN1Signed(asn1.INTEGER, v) -} - -// AddASN1Int64WithTag appends a DER-encoded ASN.1 INTEGER with the -// given tag. -func (b *Builder) AddASN1Int64WithTag(v int64, tag asn1.Tag) { - b.addASN1Signed(tag, v) -} - -// AddASN1Enum appends a DER-encoded ASN.1 ENUMERATION. -func (b *Builder) AddASN1Enum(v int64) { - b.addASN1Signed(asn1.ENUM, v) -} - -func (b *Builder) addASN1Signed(tag asn1.Tag, v int64) { - b.AddASN1(tag, func(c *Builder) { - length := 1 - for i := v; i >= 0x80 || i < -0x80; i >>= 8 { - length++ - } - - for ; length > 0; length-- { - i := v >> uint((length-1)*8) & 0xff - c.AddUint8(uint8(i)) - } - }) -} - -// AddASN1Uint64 appends a DER-encoded ASN.1 INTEGER. -func (b *Builder) AddASN1Uint64(v uint64) { - b.AddASN1(asn1.INTEGER, func(c *Builder) { - length := 1 - for i := v; i >= 0x80; i >>= 8 { - length++ - } - - for ; length > 0; length-- { - i := v >> uint((length-1)*8) & 0xff - c.AddUint8(uint8(i)) - } - }) -} - -// AddASN1BigInt appends a DER-encoded ASN.1 INTEGER. -func (b *Builder) AddASN1BigInt(n *big.Int) { - if b.err != nil { - return - } - - b.AddASN1(asn1.INTEGER, func(c *Builder) { - if n.Sign() < 0 { - // A negative number has to be converted to two's-complement form. So we - // invert and subtract 1. If the most-significant-bit isn't set then - // we'll need to pad the beginning with 0xff in order to keep the number - // negative. - nMinus1 := new(big.Int).Neg(n) - nMinus1.Sub(nMinus1, bigOne) - bytes := nMinus1.Bytes() - for i := range bytes { - bytes[i] ^= 0xff - } - if len(bytes) == 0 || bytes[0]&0x80 == 0 { - c.add(0xff) - } - c.add(bytes...) - } else if n.Sign() == 0 { - c.add(0) - } else { - bytes := n.Bytes() - if bytes[0]&0x80 != 0 { - c.add(0) - } - c.add(bytes...) - } - }) -} - -// AddASN1OctetString appends a DER-encoded ASN.1 OCTET STRING. -func (b *Builder) AddASN1OctetString(bytes []byte) { - b.AddASN1(asn1.OCTET_STRING, func(c *Builder) { - c.AddBytes(bytes) - }) -} - -const generalizedTimeFormatStr = "20060102150405Z0700" - -// AddASN1GeneralizedTime appends a DER-encoded ASN.1 GENERALIZEDTIME. -func (b *Builder) AddASN1GeneralizedTime(t time.Time) { - if t.Year() < 0 || t.Year() > 9999 { - b.err = fmt.Errorf("cryptobyte: cannot represent %v as a GeneralizedTime", t) - return - } - b.AddASN1(asn1.GeneralizedTime, func(c *Builder) { - c.AddBytes([]byte(t.Format(generalizedTimeFormatStr))) - }) -} - -// AddASN1UTCTime appends a DER-encoded ASN.1 UTCTime. -func (b *Builder) AddASN1UTCTime(t time.Time) { - b.AddASN1(asn1.UTCTime, func(c *Builder) { - // As utilized by the X.509 profile, UTCTime can only - // represent the years 1950 through 2049. - if t.Year() < 1950 || t.Year() >= 2050 { - b.err = fmt.Errorf("cryptobyte: cannot represent %v as a UTCTime", t) - return - } - c.AddBytes([]byte(t.Format(defaultUTCTimeFormatStr))) - }) -} - -// AddASN1BitString appends a DER-encoded ASN.1 BIT STRING. This does not -// support BIT STRINGs that are not a whole number of bytes. -func (b *Builder) AddASN1BitString(data []byte) { - b.AddASN1(asn1.BIT_STRING, func(b *Builder) { - b.AddUint8(0) - b.AddBytes(data) - }) -} - -func (b *Builder) addBase128Int(n int64) { - var length int - if n == 0 { - length = 1 - } else { - for i := n; i > 0; i >>= 7 { - length++ - } - } - - for i := length - 1; i >= 0; i-- { - o := byte(n >> uint(i*7)) - o &= 0x7f - if i != 0 { - o |= 0x80 - } - - b.add(o) - } -} - -func isValidOID(oid encoding_asn1.ObjectIdentifier) bool { - if len(oid) < 2 { - return false - } - - if oid[0] > 2 || (oid[0] <= 1 && oid[1] >= 40) { - return false - } - - for _, v := range oid { - if v < 0 { - return false - } - } - - return true -} - -func (b *Builder) AddASN1ObjectIdentifier(oid encoding_asn1.ObjectIdentifier) { - b.AddASN1(asn1.OBJECT_IDENTIFIER, func(b *Builder) { - if !isValidOID(oid) { - b.err = fmt.Errorf("cryptobyte: invalid OID: %v", oid) - return - } - - b.addBase128Int(int64(oid[0])*40 + int64(oid[1])) - for _, v := range oid[2:] { - b.addBase128Int(int64(v)) - } - }) -} - -func (b *Builder) AddASN1Boolean(v bool) { - b.AddASN1(asn1.BOOLEAN, func(b *Builder) { - if v { - b.AddUint8(0xff) - } else { - b.AddUint8(0) - } - }) -} - -func (b *Builder) AddASN1NULL() { - b.add(uint8(asn1.NULL), 0) -} - -// MarshalASN1 calls encoding_asn1.Marshal on its input and appends the result if -// successful or records an error if one occurred. -func (b *Builder) MarshalASN1(v interface{}) { - // NOTE(martinkr): This is somewhat of a hack to allow propagation of - // encoding_asn1.Marshal errors into Builder.err. N.B. if you call MarshalASN1 with a - // value embedded into a struct, its tag information is lost. - if b.err != nil { - return - } - bytes, err := encoding_asn1.Marshal(v) - if err != nil { - b.err = err - return - } - b.AddBytes(bytes) -} - -// AddASN1 appends an ASN.1 object. The object is prefixed with the given tag. -// Tags greater than 30 are not supported and result in an error (i.e. -// low-tag-number form only). The child builder passed to the -// BuilderContinuation can be used to build the content of the ASN.1 object. -func (b *Builder) AddASN1(tag asn1.Tag, f BuilderContinuation) { - if b.err != nil { - return - } - // Identifiers with the low five bits set indicate high-tag-number format - // (two or more octets), which we don't support. - if tag&0x1f == 0x1f { - b.err = fmt.Errorf("cryptobyte: high-tag number identifier octets not supported: 0x%x", tag) - return - } - b.AddUint8(uint8(tag)) - b.addLengthPrefixed(1, true, f) -} - -// String - -// ReadASN1Boolean decodes an ASN.1 BOOLEAN and converts it to a boolean -// representation into out and advances. It reports whether the read -// was successful. -func (s *String) ReadASN1Boolean(out *bool) bool { - var bytes String - if !s.ReadASN1(&bytes, asn1.BOOLEAN) || len(bytes) != 1 { - return false - } - - switch bytes[0] { - case 0: - *out = false - case 0xff: - *out = true - default: - return false - } - - return true -} - -// ReadASN1Integer decodes an ASN.1 INTEGER into out and advances. If out does -// not point to an integer, to a big.Int, or to a []byte it panics. Only -// positive and zero values can be decoded into []byte, and they are returned as -// big-endian binary values that share memory with s. Positive values will have -// no leading zeroes, and zero will be returned as a single zero byte. -// ReadASN1Integer reports whether the read was successful. -func (s *String) ReadASN1Integer(out interface{}) bool { - switch out := out.(type) { - case *int, *int8, *int16, *int32, *int64: - var i int64 - if !s.readASN1Int64(&i) || reflect.ValueOf(out).Elem().OverflowInt(i) { - return false - } - reflect.ValueOf(out).Elem().SetInt(i) - return true - case *uint, *uint8, *uint16, *uint32, *uint64: - var u uint64 - if !s.readASN1Uint64(&u) || reflect.ValueOf(out).Elem().OverflowUint(u) { - return false - } - reflect.ValueOf(out).Elem().SetUint(u) - return true - case *big.Int: - return s.readASN1BigInt(out) - case *[]byte: - return s.readASN1Bytes(out) - default: - panic("out does not point to an integer type") - } -} - -func checkASN1Integer(bytes []byte) bool { - if len(bytes) == 0 { - // An INTEGER is encoded with at least one octet. - return false - } - if len(bytes) == 1 { - return true - } - if bytes[0] == 0 && bytes[1]&0x80 == 0 || bytes[0] == 0xff && bytes[1]&0x80 == 0x80 { - // Value is not minimally encoded. - return false - } - return true -} - -var bigOne = big.NewInt(1) - -func (s *String) readASN1BigInt(out *big.Int) bool { - var bytes String - if !s.ReadASN1(&bytes, asn1.INTEGER) || !checkASN1Integer(bytes) { - return false - } - if bytes[0]&0x80 == 0x80 { - // Negative number. - neg := make([]byte, len(bytes)) - for i, b := range bytes { - neg[i] = ^b - } - out.SetBytes(neg) - out.Add(out, bigOne) - out.Neg(out) - } else { - out.SetBytes(bytes) - } - return true -} - -func (s *String) readASN1Bytes(out *[]byte) bool { - var bytes String - if !s.ReadASN1(&bytes, asn1.INTEGER) || !checkASN1Integer(bytes) { - return false - } - if bytes[0]&0x80 == 0x80 { - return false - } - for len(bytes) > 1 && bytes[0] == 0 { - bytes = bytes[1:] - } - *out = bytes - return true -} - -func (s *String) readASN1Int64(out *int64) bool { - var bytes String - if !s.ReadASN1(&bytes, asn1.INTEGER) || !checkASN1Integer(bytes) || !asn1Signed(out, bytes) { - return false - } - return true -} - -func asn1Signed(out *int64, n []byte) bool { - length := len(n) - if length > 8 { - return false - } - for i := 0; i < length; i++ { - *out <<= 8 - *out |= int64(n[i]) - } - // Shift up and down in order to sign extend the result. - *out <<= 64 - uint8(length)*8 - *out >>= 64 - uint8(length)*8 - return true -} - -func (s *String) readASN1Uint64(out *uint64) bool { - var bytes String - if !s.ReadASN1(&bytes, asn1.INTEGER) || !checkASN1Integer(bytes) || !asn1Unsigned(out, bytes) { - return false - } - return true -} - -func asn1Unsigned(out *uint64, n []byte) bool { - length := len(n) - if length > 9 || length == 9 && n[0] != 0 { - // Too large for uint64. - return false - } - if n[0]&0x80 != 0 { - // Negative number. - return false - } - for i := 0; i < length; i++ { - *out <<= 8 - *out |= uint64(n[i]) - } - return true -} - -// ReadASN1Int64WithTag decodes an ASN.1 INTEGER with the given tag into out -// and advances. It reports whether the read was successful and resulted in a -// value that can be represented in an int64. -func (s *String) ReadASN1Int64WithTag(out *int64, tag asn1.Tag) bool { - var bytes String - return s.ReadASN1(&bytes, tag) && checkASN1Integer(bytes) && asn1Signed(out, bytes) -} - -// ReadASN1Enum decodes an ASN.1 ENUMERATION into out and advances. It reports -// whether the read was successful. -func (s *String) ReadASN1Enum(out *int) bool { - var bytes String - var i int64 - if !s.ReadASN1(&bytes, asn1.ENUM) || !checkASN1Integer(bytes) || !asn1Signed(&i, bytes) { - return false - } - if int64(int(i)) != i { - return false - } - *out = int(i) - return true -} - -func (s *String) readBase128Int(out *int) bool { - ret := 0 - for i := 0; len(*s) > 0; i++ { - if i == 5 { - return false - } - // Avoid overflowing int on a 32-bit platform. - // We don't want different behavior based on the architecture. - if ret >= 1<<(31-7) { - return false - } - ret <<= 7 - b := s.read(1)[0] - - // ITU-T X.690, section 8.19.2: - // The subidentifier shall be encoded in the fewest possible octets, - // that is, the leading octet of the subidentifier shall not have the value 0x80. - if i == 0 && b == 0x80 { - return false - } - - ret |= int(b & 0x7f) - if b&0x80 == 0 { - *out = ret - return true - } - } - return false // truncated -} - -// ReadASN1ObjectIdentifier decodes an ASN.1 OBJECT IDENTIFIER into out and -// advances. It reports whether the read was successful. -func (s *String) ReadASN1ObjectIdentifier(out *encoding_asn1.ObjectIdentifier) bool { - var bytes String - if !s.ReadASN1(&bytes, asn1.OBJECT_IDENTIFIER) || len(bytes) == 0 { - return false - } - - // In the worst case, we get two elements from the first byte (which is - // encoded differently) and then every varint is a single byte long. - components := make([]int, len(bytes)+1) - - // The first varint is 40*value1 + value2: - // According to this packing, value1 can take the values 0, 1 and 2 only. - // When value1 = 0 or value1 = 1, then value2 is <= 39. When value1 = 2, - // then there are no restrictions on value2. - var v int - if !bytes.readBase128Int(&v) { - return false - } - if v < 80 { - components[0] = v / 40 - components[1] = v % 40 - } else { - components[0] = 2 - components[1] = v - 80 - } - - i := 2 - for ; len(bytes) > 0; i++ { - if !bytes.readBase128Int(&v) { - return false - } - components[i] = v - } - *out = components[:i] - return true -} - -// ReadASN1GeneralizedTime decodes an ASN.1 GENERALIZEDTIME into out and -// advances. It reports whether the read was successful. -func (s *String) ReadASN1GeneralizedTime(out *time.Time) bool { - var bytes String - if !s.ReadASN1(&bytes, asn1.GeneralizedTime) { - return false - } - t := string(bytes) - res, err := time.Parse(generalizedTimeFormatStr, t) - if err != nil { - return false - } - if serialized := res.Format(generalizedTimeFormatStr); serialized != t { - return false - } - *out = res - return true -} - -const defaultUTCTimeFormatStr = "060102150405Z0700" - -// ReadASN1UTCTime decodes an ASN.1 UTCTime into out and advances. -// It reports whether the read was successful. -func (s *String) ReadASN1UTCTime(out *time.Time) bool { - var bytes String - if !s.ReadASN1(&bytes, asn1.UTCTime) { - return false - } - t := string(bytes) - - formatStr := defaultUTCTimeFormatStr - var err error - res, err := time.Parse(formatStr, t) - if err != nil { - // Fallback to minute precision if we can't parse second - // precision. If we are following X.509 or X.690 we shouldn't - // support this, but we do. - formatStr = "0601021504Z0700" - res, err = time.Parse(formatStr, t) - } - if err != nil { - return false - } - - if serialized := res.Format(formatStr); serialized != t { - return false - } - - if res.Year() >= 2050 { - // UTCTime interprets the low order digits 50-99 as 1950-99. - // This only applies to its use in the X.509 profile. - // See https://tools.ietf.org/html/rfc5280#section-4.1.2.5.1 - res = res.AddDate(-100, 0, 0) - } - *out = res - return true -} - -// ReadASN1BitString decodes an ASN.1 BIT STRING into out and advances. -// It reports whether the read was successful. -func (s *String) ReadASN1BitString(out *encoding_asn1.BitString) bool { - var bytes String - if !s.ReadASN1(&bytes, asn1.BIT_STRING) || len(bytes) == 0 || - len(bytes)*8/8 != len(bytes) { - return false - } - - paddingBits := bytes[0] - bytes = bytes[1:] - if paddingBits > 7 || - len(bytes) == 0 && paddingBits != 0 || - len(bytes) > 0 && bytes[len(bytes)-1]&(1<