Skip to content

Commit

Permalink
Add enterprise check for fingerprint scanning
Browse files Browse the repository at this point in the history
  • Loading branch information
filip-debricked committed Apr 23, 2024
1 parent 0ccea4f commit b4045cc
Show file tree
Hide file tree
Showing 3 changed files with 250 additions and 41 deletions.
4 changes: 2 additions & 2 deletions internal/cmd/scan/scan.go
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ $ debricked scan . `+exampleFlags)
cmd.Flags().BoolVarP(&passOnDowntime, PassOnTimeOut, "p", false, "pass scan if there is a service access timeout")
cmd.Flags().BoolVar(&noResolve, NoResolveFlag, false, `disables resolution of manifest files that lack lock files. Resolving manifest files enables more accurate dependency scanning since the whole dependency tree will be analysed.
For example, if there is a "go.mod" in the target path, its dependencies are going to get resolved onto a lock file, and latter scanned.`)
cmd.Flags().BoolVar(&noFingerprint, FingerprintFlag, false, "enables fingerprinting for undeclared component identification. Can be run as a standalone command [files fingerprint] with more granular options. Will be default in an upcoming major release.")
cmd.Flags().BoolVar(&noFingerprint, FingerprintFlag, false, "disables fingerprinting for undeclared component identification. Can be run as a standalone command [files fingerprint] with more granular options.")
cmd.Flags().BoolVar(&callgraph, CallGraphFlag, false, `Enables call graph generation during scan.`)
cmd.Flags().IntVar(&callgraphUploadTimeout, CallGraphUploadTimeoutFlag, 10*60, "Set a timeout (in seconds) on call graph upload.")
cmd.Flags().IntVar(&callgraphGenerateTimeout, CallGraphGenerateTimeoutFlag, 60*60, "Set a timeout (in seconds) on call graph generation.")
Expand Down Expand Up @@ -162,7 +162,7 @@ func RunE(s *scan.IScanner) func(_ *cobra.Command, args []string) error {
options := scan.DebrickedOptions{
Path: path,
Resolve: !viper.GetBool(NoResolveFlag),
Fingerprint: viper.GetBool(FingerprintFlag),
Fingerprint: !viper.GetBool(FingerprintFlag),
Exclusions: viper.GetStringSlice(ExclusionFlag),
Verbose: viper.GetBool(VerboseFlag),
Regenerate: viper.GetInt(RegenerateFlag),
Expand Down
54 changes: 54 additions & 0 deletions internal/scan/scanner.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import (
"encoding/json"
"errors"
"fmt"
"io"
"net/http"
"os"
"path/filepath"

Expand All @@ -26,6 +28,8 @@ var (
FailPipelineErr = errors.New("")
)

const enterpriseCheckUri = "/api/1.0/open/user-profile/get-billing-info"

type IScanner interface {
Scan(o IOptions) error
}
Expand Down Expand Up @@ -157,8 +161,19 @@ func (dScanner *DebrickedScanner) scanResolve(options DebrickedOptions) error {
return nil
}

type BillingPlanError struct {
errorMessage string
}

func (billingPlanError BillingPlanError) Error() string {
return billingPlanError.errorMessage
}

func (dScanner *DebrickedScanner) scanFingerprint(options DebrickedOptions) error {
if options.Fingerprint {
if !dScanner.IsEnterpriseCustomer() {
return BillingPlanError{errorMessage: "Could not validate Enterprise billing plan, which is a requirement for fingerprinting and manifestless matching."}
}
fingerprints, err := dScanner.fingerprint.FingerprintFiles(
options.Path, file.DefaultExclusionsFingerprint(), false, options.MinFingerprintContentLength,
)
Expand All @@ -173,6 +188,45 @@ func (dScanner *DebrickedScanner) scanFingerprint(options DebrickedOptions) erro
return nil
}

type BillingPlan struct {
SCA string `json:"sca"`
Select string `json:"select"`
}

func (dScanner *DebrickedScanner) IsEnterpriseCustomer() bool {
res, err := (*dScanner.client).Get(enterpriseCheckUri, "application/json")
if err != nil {
fmt.Printf("%s Unable to get billing plan from the server. Defaulting to non-enterprise plan.\n", color.YellowString("⚠️"))

return false
}
defer res.Body.Close()

if res.StatusCode != http.StatusOK {
fmt.Printf("%s Unable to get billing plan from the server. Defaulting to non-enterprise plan.\n", color.YellowString("⚠️"))

return false
}

billingPlanJSON, err := io.ReadAll(res.Body)
if err != nil {
fmt.Printf("%s Unable to get billing plan correctly formatted from the server. Defaulting to non-enterprise plan.\n", color.YellowString("⚠️"))

return false
}

var billingPlan BillingPlan

err = json.Unmarshal(billingPlanJSON, &billingPlan)
if err != nil {
fmt.Printf("%s Unable to get billing plan correctly formatted from the server. Defaulting to non-enterprise plan.\n", color.YellowString("⚠️"))

return false
}

return billingPlan.SCA == "enterprise"
}

func (dScanner *DebrickedScanner) scan(options DebrickedOptions, gitMetaObject git.MetaObject) (*upload.UploadResult, error) {

err := dScanner.scanResolve(options)
Expand Down
Loading

0 comments on commit b4045cc

Please sign in to comment.