Pārlūkot izejas kodu

working on tests

zricethezav 8 gadi atpakaļ
vecāks
revīzija
36c31bf181
6 mainītis faili ar 97 papildinājumiem un 99 dzēšanām
  1. 1 1
      main.go
  2. 36 29
      options.go
  3. 3 3
      options_test.go
  4. 17 45
      owner.go
  5. 11 12
      repo.go
  6. 29 9
      repo_test.go

+ 1 - 1
main.go

@@ -22,7 +22,7 @@ var (
 	assignRegex   *regexp.Regexp
 	fileDiffRegex *regexp.Regexp
 	opts          *Options
-	pwd 		  string
+	pwd           string
 )
 
 func init() {

+ 36 - 29
options.go

@@ -3,10 +3,10 @@ package main
 import (
 	"fmt"
 	"os"
+	"path/filepath"
 	"regexp"
 	"strconv"
 	"strings"
-	"path/filepath"
 )
 
 const usage = `usage: gitleaks [options] <URL>/<path_to_repo>
@@ -47,6 +47,7 @@ type Options struct {
 	RepoPath string
 
 	ReportPath string
+	ClonePath  string
 
 	Concurrency      int
 	B64EntropyCutoff int
@@ -141,25 +142,6 @@ func newOpts(args []string) *Options {
 
 // deafultOptions provides the default options
 func defaultOptions() (*Options, error) {
-	/*
-	// default GITLEAKS_HOME is $HOME/.gitleaks
-	// gitleaks will use this location for clones if
-	// no clone-path is provided
-	gitleaksHome := os.Getenv("GITLEAKS_HOME")
-	if gitleaksHome == "" {
-		homeDir, err := homedir.Dir()
-		if err != nil {
-			return nil, fmt.Errorf("could not find system home dir")
-		}
-		gitleaksHome = filepath.Join(homeDir, ".gitleaks")
-	}
-
-	// make sure gitleaks home exists
-	if _, err := os.Stat(gitleaksHome); os.IsNotExist(err) {
-		os.Mkdir(gitleaksHome, os.ModePerm)
-	}
-	*/
-
 	return &Options{
 		Concurrency:      10,
 		B64EntropyCutoff: 70,
@@ -213,25 +195,33 @@ func (opts *Options) parseOptions(args []string) error {
 			help()
 			os.Exit(EXIT_CLEAN)
 		default:
-			// TARGETS
-			if i == len(args)-1 {
-				if opts.LocalMode {
-					opts.RepoPath = filepath.Clean(args[i])
-				} else {
-					opts.URL = args[i]
-				}
-			} else if match, value := opts.optString(arg, "--token="); match {
+			if match, value := opts.optString(arg, "--token="); match {
 				opts.Token = value
 			} else if match, value := opts.optString(arg, "--since="); match {
 				opts.SinceCommit = value
 			} else if match, value := opts.optString(arg, "--report-path="); match {
 				opts.ReportPath = value
+			} else if match, value := opts.optString(arg, "--clone-path="); match {
+				opts.ClonePath = value
 			} else if match, value := opts.optInt(arg, "--log="); match {
 				opts.LogLevel = value
 			} else if match, value := opts.optInt(arg, "--b64Entropy="); match {
 				opts.B64EntropyCutoff = value
 			} else if match, value := opts.optInt(arg, "--hexEntropy="); match {
 				opts.HexEntropyCutoff = value
+			} else if i == len(args)-1 {
+				fmt.Println(args[i])
+				if opts.LocalMode {
+					opts.RepoPath = filepath.Clean(args[i])
+				} else {
+					if isGithubTarget(args[i]) {
+						opts.URL = args[i]
+					} else {
+						fmt.Printf("Unknown option %s\n\n", arg)
+						help()
+						os.Exit(EXIT_CLEAN)
+					}
+				}
 			} else {
 				fmt.Printf("Unknown option %s\n\n", arg)
 				help()
@@ -239,9 +229,26 @@ func (opts *Options) parseOptions(args []string) error {
 			}
 		}
 	}
+
 	err := opts.guards()
 	if !opts.RepoMode && !opts.UserMode && !opts.OrgMode && !opts.LocalMode {
-		opts.RepoMode = true
+		if opts.URL != "" {
+			opts.RepoMode = true
+			return nil
+		}
+		pwd, _ = os.Getwd()
+		// check if pwd contains a .git, if it does, run local mode
+		dotGitPath := filepath.Join(pwd, ".git")
+
+		if _, err := os.Stat(dotGitPath); os.IsNotExist(err) {
+			fmt.Printf("gitleaks has no target")
+			os.Exit(EXIT_CLEAN)
+		} else {
+			opts.LocalMode = true
+			opts.RepoPath = pwd
+			opts.RepoMode = false
+		}
+
 	}
 	return err
 }

+ 3 - 3
options_test.go

@@ -76,13 +76,13 @@ func TestParseOptions(t *testing.T) {
 }
 
 func TestGithubTarget(t *testing.T) {
-	if !isGithubTarget("github.com"){
+	if !isGithubTarget("github.com") {
 		t.Error()
 	}
-	if !isGithubTarget("https://github.com/"){
+	if !isGithubTarget("https://github.com/") {
 		t.Error()
 	}
-	if !isGithubTarget("git@github.com:zricethezav/gitleaks.git"){
+	if !isGithubTarget("git@github.com:zricethezav/gitleaks.git") {
 		t.Error()
 	}
 

+ 17 - 45
owner.go

@@ -7,14 +7,12 @@ import (
 	"github.com/google/go-github/github"
 	"golang.org/x/oauth2"
 	"io/ioutil"
+	"log"
 	"net/http"
 	"os"
 	"os/signal"
 	"path"
 	"strings"
-	"github.com/mitchellh/go-homedir"
-	"path/filepath"
-	"log"
 )
 
 type Owner struct {
@@ -26,27 +24,20 @@ type Owner struct {
 	repos       []Repo
 }
 
-func ownerPath(ownerName string) (string, error){
+func ownerPath(ownerName string) (string, error) {
 	if opts.Tmp {
 		fmt.Println("creating tmp")
 		dir, err := ioutil.TempDir("", ownerName)
 		return dir, err
-	}
-
-	gitleaksHome := os.Getenv("GITLEAKS_HOME")
-	if gitleaksHome == "" {
-		homeDir, err := homedir.Dir()
-		if err != nil {
-			return "", fmt.Errorf("could not find system home dir")
+	} else if opts.ClonePath != "" {
+		if _, err := os.Stat(opts.ClonePath); os.IsNotExist(err) {
+			os.Mkdir(opts.ClonePath, os.ModePerm)
 		}
-		gitleaksHome = filepath.Join(homeDir, ".gitleaks")
+		return opts.ClonePath, nil
+	} else {
+		return os.Getwd()
 	}
 
-	// make sure gitleaks home exists
-	if _, err := os.Stat(gitleaksHome); os.IsNotExist(err) {
-		os.Mkdir(gitleaksHome, os.ModePerm)
-	}
-	return gitleaksHome + "/" + ownerName, nil
 }
 
 // newOwner instantiates an owner and creates any necessary resources for said owner.
@@ -54,14 +45,14 @@ func ownerPath(ownerName string) (string, error){
 func newOwner() *Owner {
 	name := ownerName()
 	ownerPath, err := ownerPath(name)
-	if err != nil{
+	if err != nil {
 		failF("%v", err)
 	}
 	owner := &Owner{
 		name:        name,
 		url:         opts.URL,
 		accountType: ownerType(),
-		path: ownerPath,
+		path:        ownerPath,
 	}
 
 	// listen for ctrl-c
@@ -83,10 +74,10 @@ func newOwner() *Owner {
 	}
 
 	/*
-	err := owner.setupDir()
-	if err != nil {
-		owner.failF("%v", err)
-	}*/
+		err := owner.setupDir()
+		if err != nil {
+			owner.failF("%v", err)
+		}*/
 	err = owner.fetchRepos()
 	if err != nil {
 		owner.failF("%v", err)
@@ -104,7 +95,7 @@ func (owner *Owner) fetchRepos() error {
 	if owner.accountType == "" {
 		// single repo, ambiguous account type
 		_, repoName := path.Split(opts.URL)
-		repo := newRepo(repoName, opts.URL, owner.path + "/" + repoName)
+		repo := newRepo(repoName, opts.URL, owner.path+"/"+repoName)
 		owner.repos = append(owner.repos, *repo)
 	} else {
 		// org or user account type, would fail if not valid before
@@ -187,7 +178,7 @@ func (owner *Owner) fetchUserRepos(userOpts *github.RepositoryListOptions, gitCl
 // github's org/user response.
 func (owner *Owner) addRepos(githubRepos []*github.Repository) {
 	for _, repo := range githubRepos {
-		owner.repos = append(owner.repos, *newRepo(*repo.Name, *repo.CloneURL, owner.path + "/" + *repo.Name))
+		owner.repos = append(owner.repos, *newRepo(*repo.Name, *repo.CloneURL, owner.path+"/"+*repo.Name))
 	}
 }
 
@@ -195,7 +186,7 @@ func (owner *Owner) addRepos(githubRepos []*github.Repository) {
 func (owner *Owner) auditRepos() int {
 	exitCode := EXIT_CLEAN
 	for _, repo := range owner.repos {
-		leaksPst, err := repo.audit(owner)
+		leaksPst, err := repo.audit()
 		if err != nil {
 			failF("%v\n", err)
 		}
@@ -216,25 +207,6 @@ func (owner *Owner) failF(format string, args ...interface{}) {
 	os.Exit(EXIT_FAILURE)
 }
 
-// setupDir sets up the owner's directory for clones and reports.
-// If the temporary option is set then a temporary directory will be
-// used for the owner repo clones.
-func (owner *Owner) setupDir() error {
-	if opts.Tmp {
-		fmt.Println("creating tmp")
-		dir, err := ioutil.TempDir("", owner.name)
-		if err != nil {
-			fmt.Errorf("unable to create temp directories for cloning")
-		}
-		owner.path = dir
-	} else {
-		if _, err := os.Stat(owner.path); os.IsNotExist(err) {
-			os.Mkdir(owner.path, os.ModePerm)
-		}
-	}
-	return nil
-}
-
 // rmTmp removes the temporary repo
 func (owner *Owner) rmTmp() {
 	log.Printf("removing tmp gitleaks repo for %s\n", owner.name)

+ 11 - 12
repo.go

@@ -5,20 +5,20 @@ import (
 	"encoding/json"
 	"fmt"
 	"io/ioutil"
+	"log"
 	"os"
 	"os/exec"
 	"path"
 	"path/filepath"
 	"sync"
-	"log"
 )
 
 type Repo struct {
-	name   string
-	url    string
-	path   string
-	status string // TODO
-	leaks  []Leak
+	name       string
+	url        string
+	path       string
+	status     string // TODO
+	leaks      []Leak
 	reportPath string
 }
 
@@ -45,8 +45,8 @@ type Commit struct {
 func newLocalRepo(repoPath string) *Repo {
 	_, name := path.Split(repoPath)
 	repo := &Repo{
-		name: name,
-		path: repoPath,
+		name:       name,
+		path:       repoPath,
 		reportPath: opts.ReportPath,
 	}
 	return repo
@@ -58,7 +58,7 @@ func newRepo(name string, url string, path string) *Repo {
 		name: name,
 		url:  url,
 		// TODO handle existing one
-		path: path,
+		path:       path,
 		reportPath: opts.ReportPath,
 	}
 	return repo
@@ -70,7 +70,7 @@ func newRepo(name string, url string, path string) *Repo {
 // commands so that users could opt for doing all clones/diffs in memory.
 // Audit also declares two WaitGroups, one for distributing regex/entropy checks, and one for receiving
 // the leaks if there are any. This could be done a little more elegantly in the future.
-func (repo *Repo) audit(owner *Owner) (bool, error) {
+func (repo *Repo) audit() (bool, error) {
 	var (
 		out               []byte
 		err               error
@@ -140,7 +140,7 @@ func (repo *Repo) audit(owner *Owner) (bool, error) {
 		leaksPst = true
 	}
 
-	if opts.ReportPath != "" && len(leaks) != 0 {
+	if (opts.ReportPath != "" || opts.ReportOut) && len(leaks) != 0 {
 		err = repo.writeReport()
 		if err != nil {
 			return leaksPst, fmt.Errorf("could not write report to %s", opts.ReportPath)
@@ -154,7 +154,6 @@ func (repo *Repo) audit(owner *Owner) (bool, error) {
 // no leaks have been found
 func (repo *Repo) writeReport() error {
 	reportJSON, _ := json.MarshalIndent(repo.leaks, "", "\t")
-
 	if _, err := os.Stat(opts.ReportPath); os.IsNotExist(err) {
 		os.Mkdir(opts.ReportPath, os.ModePerm)
 	}

+ 29 - 9
repo_test.go

@@ -1,6 +1,10 @@
 package main
 
-import "testing"
+import (
+	"testing"
+	"os"
+	"fmt"
+)
 
 func TestNewRepo(t *testing.T) {
 	// TODO
@@ -11,11 +15,30 @@ func TestNewLocalRepo(t *testing.T) {
 }
 
 func TestWriteReport(t *testing.T) {
-	// TODO
-	/*
-	opts, err := defaultOptions()
-	r := newRepo("fakerepo", "github.com")
-	sampleLeak := Leak{
+	opts, _ = defaultOptions()
+	r := newRepo("fakerepo", "github.com", "")
+	r.leaks = []Leak{*sampleLeak(), *sampleLeak()}
+	r.writeReport()
+	if _, err := os.Stat("fakerepo_leaks.json"); os.IsNotExist(err) {
+		t.Error()
+	} else {
+		os.Remove("fakerepo_leaks.json")
+	}
+}
+
+func TestAudit(t *testing.T) {
+	opts, _ = defaultOptions()
+	opts.RepoMode = true
+	opts.Tmp = true
+	opts.URL = "https://github.com/zricethezav/gronit"
+	owner := newOwner()
+	r := newRepo("gronit", "https://github.com/zricethezav/gronit", owner.path)
+	r.audit()
+
+}
+
+func sampleLeak() *Leak {
+	return &Leak{
 		Line: "yoo",
 		Commit: "mycommit",
 		Offender: "oh boy",
@@ -25,7 +48,4 @@ func TestWriteReport(t *testing.T) {
 		Author: "lol",
 		RepoURL: "yooo",
 	}
-	r.leaks = []Leak{sampleLeak, sampleLeak}
-	r.writeReport()
-	*/
 }