Skip to content

Commit

Permalink
🚧 setting the ground for authentication
Browse files Browse the repository at this point in the history
  • Loading branch information
acidjazz committed Mar 9, 2024
1 parent f1f4fcb commit 9377a9e
Show file tree
Hide file tree
Showing 12 changed files with 198 additions and 10 deletions.
2 changes: 1 addition & 1 deletion cmd/vc/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@ package main
import "github.com/vulncheck-oss/cli/pkg/cmd/root"

func main() {
root.Execute("v0.1.0", "2024-03-08")
root.Execute()
}
4 changes: 4 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ require (
)

require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/gomarkdown/markdown v0.0.0-20210208175418-bda154fe17d8 // indirect
github.com/google/uuid v1.2.0 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/octoper/go-ray v0.1.5 // indirect
github.com/spf13/pflag v1.0.5 // indirect
)
17 changes: 17 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,12 +1,29 @@
github.com/MakeNowJust/heredoc/v2 v2.0.1 h1:rlCHh70XXXv7toz95ajQWOWQnN4WNLt0TdpZYIR/J6A=
github.com/MakeNowJust/heredoc/v2 v2.0.1/go.mod h1:6/2Abh5s+hc3g9nbWLe9ObDIOhaRrqsyY9MWy+4JdRM=
github.com/bradleyjkemp/cupaloy/v2 v2.6.0/go.mod h1:bm7JXdkRd4BHJk9HpwqAI8BoAY1lps46Enkdqw6aRX0=
github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/gomarkdown/markdown v0.0.0-20210208175418-bda154fe17d8 h1:nWU6p08f1VgIalT6iZyqXi4o5cZsz4X6qa87nusfcsc=
github.com/gomarkdown/markdown v0.0.0-20210208175418-bda154fe17d8/go.mod h1:aii0r/K0ZnHv7G0KF7xy1v0A7s2Ljrb5byB7MO5p6TU=
github.com/google/uuid v1.2.0 h1:qJYtXnJRWmpe7m/3XlyhrsLrEURqHRM2kxzoxXqyUDs=
github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
github.com/octoper/go-ray v0.1.5 h1:tTN+4HptuzSnw60E0wM71wegKsy8wYhnQ2THjMvXBGQ=
github.com/octoper/go-ray v0.1.5/go.mod h1:Y1I9cUEZ4oD94H0/M+xwHhvGVbFu1o/dW3fDrknELk8=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0=
github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
golang.org/dl v0.0.0-20190829154251-82a15e2f2ead/go.mod h1:IUMfjQLJQd4UTqG1Z90tenwKoCX93Gn3MAQJMOSBsDQ=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
2 changes: 2 additions & 0 deletions pkg/cmd/ascii/ascii.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
_ "embed"
"fmt"
"github.com/spf13/cobra"
"github.com/vulncheck-oss/cli/pkg/session"
)

//go:embed ascii.txt
Expand All @@ -17,5 +18,6 @@ func Command() *cobra.Command {
fmt.Println(ascii)
},
}
session.DisableAuthCheck(cmd)
return cmd
}
21 changes: 21 additions & 0 deletions pkg/cmd/auth/auth.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package auth

import (
"github.com/spf13/cobra"
"github.com/vulncheck-oss/cli/pkg/cmd/auth/login"
"github.com/vulncheck-oss/cli/pkg/session"
)

func Command() *cobra.Command {
cmd := &cobra.Command{
Use: "auth <command",
Short: "Authenticate vc with the VulnCheck portal",
GroupID: "core",
}

session.DisableAuthCheck(cmd)

cmd.AddCommand(login.Command())

return cmd
}
73 changes: 73 additions & 0 deletions pkg/cmd/auth/login/login.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package login

import (
"github.com/MakeNowJust/heredoc/v2"
"github.com/spf13/cobra"
"github.com/vulncheck-oss/cli/pkg/session"
"github.com/vulncheck-oss/cli/pkg/util"
"strings"
)

func Command() *cobra.Command {

cmd := &cobra.Command{
Use: "login",
Short: "Log in with a VulnCheck account",

Long: heredoc.Docf(`
Authenticate with a VulnCheck account.
The default authentication mode is a web-based browser flow.
Alternatively, use %[1]stoken%[1]s to specify an issued token directly.
Alternatively, vc will use the authentication token found in the %[1]sVC_TOKEN%[1]s environment variable.
This method is most suitable for "headless" use of vc such as in automation.
`, "`"),
Example: heredoc.Doc(`
# Start interactive authentication
$ vc auth login
# Authenticate with vulncheck.com by passing in a token
$ vc auth login token vulncheck_******************
`),
}

web := &cobra.Command{
Use: "web",
Short: "Log in with a VulnCheck account using a web browser",
RunE: func(cmd *cobra.Command, args []string) error {
return util.FlagErrorf("web login is not yet implemented")
},
}

token := &cobra.Command{
Use: "token",
Short: "Connect a VulnCheck account using a token",
RunE: func(cmd *cobra.Command, args []string) error {
if len(args) != 1 {
return util.FlagErrorf("No token specified")
}
if !ValidToken(args[0]) {
return util.FlagErrorf("Invalid token specified")
}
return nil
},
}

cmd.AddCommand(web, token)

session.DisableAuthCheck(cmd)
return cmd
}

func ValidToken(token string) bool {
if !strings.HasPrefix(token, "vulncheck_") {
return false
}

if len(token) != 74 {
return false
}
return true
}
37 changes: 37 additions & 0 deletions pkg/cmd/auth/login/login_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package login

import (
"testing"
)

func TestValidToken(t *testing.T) {
tests := []struct {
name string
token string
want bool
}{
{
name: "valid token",
token: "vulncheck_1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef",
want: true,
},
{
name: "no token",
token: "",
want: false,
},
{
name: "invalid token",
token: "checkvuln_1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef",
want: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := ValidToken(tt.token); got != tt.want {
t.Errorf("ValidToken() = %v, want %v", got, tt.want)
}
})
}

}
2 changes: 1 addition & 1 deletion pkg/cmd/root/help.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (
func authHelp() string {
if os.Getenv("GITHUB_ACTIONS") == "true" {
return heredoc.Doc(`
vc: To use GitHub CLI in a GitHub Actions workflow, set the GH_TOKEN environment variable. Example:
vc: To use VulnCheck CLI in a GitHub Actions workflow, set the VC_TOKEN environment variable. Example:
env:
VC_TOKEN: ${{ secrets.vulncheck_token }}
`)
Expand Down
13 changes: 10 additions & 3 deletions pkg/cmd/root/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,11 @@ import (
"fmt"
"github.com/MakeNowJust/heredoc/v2"
"github.com/spf13/cobra"
"github.com/vulncheck-oss/cli/pkg/auth"
"github.com/vulncheck-oss/cli/pkg/build"
"github.com/vulncheck-oss/cli/pkg/cmd/ascii"
"github.com/vulncheck-oss/cli/pkg/cmd/auth"
cmdVersion "github.com/vulncheck-oss/cli/pkg/cmd/version"
"github.com/vulncheck-oss/cli/pkg/session"
"os"
)

Expand All @@ -35,7 +36,7 @@ func NewCmdRoot() *cobra.Command {
},
PersistentPreRunE: func(cmd *cobra.Command, args []string) error {

if auth.IsAuthCheckEnabled(cmd) && !auth.CheckAuth() {
if session.IsAuthCheckEnabled(cmd) && !session.CheckAuth() {
fmt.Println(authHelp())
return &AuthError{}
}
Expand All @@ -47,13 +48,19 @@ func NewCmdRoot() *cobra.Command {

cmd.PersistentFlags().Bool("help", false, "Show help for command")

cmd.AddGroup(&cobra.Group{
ID: "core",
Title: "Core Commands",
})

cmd.AddCommand(cmdVersion.Command())
cmd.AddCommand(ascii.Command())
cmd.AddCommand(auth.Command())

return cmd
}

func Execute(version string, date string) {
func Execute() {

if err := NewCmdRoot().Execute(); err != nil {
fmt.Println(err)
Expand Down
4 changes: 2 additions & 2 deletions pkg/cmd/version/version.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package version
import (
"fmt"
"github.com/spf13/cobra"
"github.com/vulncheck-oss/cli/pkg/auth"
"github.com/vulncheck-oss/cli/pkg/session"
"regexp"
"strings"
)
Expand All @@ -17,7 +17,7 @@ func Command() *cobra.Command {
},
}

auth.DisableAuthCheck(cmd)
session.DisableAuthCheck(cmd)
return cmd
}

Expand Down
8 changes: 5 additions & 3 deletions pkg/auth/auth.go → pkg/session/session.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package auth
package session

import "github.com/spf13/cobra"
import (
"github.com/spf13/cobra"
)

func IsAuthCheckEnabled(cmd *cobra.Command) bool {
switch cmd.Name() {
Expand All @@ -26,5 +28,5 @@ func DisableAuthCheck(cmd *cobra.Command) {
}

func CheckAuth() bool {
return false
return true
}
25 changes: 25 additions & 0 deletions pkg/util/util.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package util

import (
"fmt"
)

type FlagError struct {
// Note: not struct{error}: only *FlagError should satisfy error.
err error
}

func (fe *FlagError) Error() string {
return fe.err.Error()
}

func (fe *FlagError) Unwrap() error {
return fe.err
}

func FlagErrorf(format string, args ...interface{}) error {
return FlagErrorWrap(fmt.Errorf(format, args...))
}

// FlagErrorWrap FlagError returns a new FlagError that wraps the specified error.
func FlagErrorWrap(err error) error { return &FlagError{err} }

0 comments on commit 9377a9e

Please sign in to comment.