Skip to content

Commit

Permalink
Break out auth; add some tests
Browse files Browse the repository at this point in the history
  • Loading branch information
gkze committed Apr 23, 2019
1 parent a012b57 commit 2fb3dbd
Show file tree
Hide file tree
Showing 12 changed files with 322 additions and 47 deletions.
7 changes: 5 additions & 2 deletions .goreleaser.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ archive:
windows: Windows
before:
hooks:
- go mod download
- go mod tidy
brew:
commit_author:
email: "[email protected]"
Expand All @@ -21,10 +21,13 @@ brew:
homepage: "https://github.com/gkze/stars"
test: "system \"#{bin}/stars -v\""
builds:
-
- main: ./cmd/main.go
binary: stars
env:
- "GO111MODULE=on"
- "CGO_ENABLED=0"
ldflags:
- -X main.Version={{.Version}}
changelog:
filters:
exclude:
Expand Down
17 changes: 17 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
.PHONY: check
check:
go vet ./...

.PHONY: test
test: check
go test -v -race ./...

.PHONY: build
build: test
CGO_ENABLED=0 go build -o stars -ldflags "-X main.Version=$(shell cat VERSION)" ./cmd

.PHONY: release
release:
git tag v$(shell cat VERSION)
git push origin master
goreleaser --rm-dist
14 changes: 7 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,15 +47,15 @@ USAGE:
stars [global options] command [command options] [arguments...]

VERSION:
0.4.3
0.4.9

COMMANDS:
save Save all stars
list-topics list all topics of starred projects
show Show popular stars given filters
clear Clear local stars cache
cleanup Clean up old stars
help, h Shows a list of commands or help for one command
save Save all stars
topics list all topics of starred projects
show Show popular stars given filters
clear Clear local stars cache
cleanup Clean up old stars
help, h Shows a list of commands or help for one command

GLOBAL OPTIONS:
--help, -h show help
Expand Down
1 change: 1 addition & 0 deletions VERSION
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
0.4.9
99 changes: 99 additions & 0 deletions auth/auth.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
package auth

import (
"fmt"
"os/user"
"path/filepath"

"github.com/jdxcode/netrc"
)

// IConfig represents a generic configuration interface
type IConfig interface{}

// Interface is the interface to the authentication manager
type Interface interface {
// New initializes a netrc auth manager, or throws an error
New(cfg *IConfig) (*Interface, error)

// GetAuth retrieves the authentication credentials for a given host, or
// throws an error
GetAuth(host string) (string, string, error)
}

// NetrcUsernameField is the value that holds the username in the netrc format
const NetrcUsernameField string = "login"

// NetrcPasswordField is the value that holds the passwod in the netrc format
const NetrcPasswordField string = "password"

// NetrcDefaultFilename is the default name of the netrc configuration file.
const NetrcDefaultFilename string = ".netrc"

// Config represents a configuration structure passed to the Netrc object
// in order to initialize it
type Config struct {
User *user.User
Filename string
}

// NewConfig returns a new configuration structure for the netrc authenticator.
func NewConfig() (*Config, error) {
curUser, err := user.Current()
if err != nil {
return nil, err
}

return &Config{
User: curUser,
Filename: NetrcDefaultFilename,
}, nil
}

// NetrcAuth reresents the implementation of the netrc authentication manager
// interface
type NetrcAuth struct {
// Config is the reference to the config struct
Config *Config

// Netrc is the parsed netrc file
Netrc *netrc.Netrc
}

// New creates a new netrc auth manager, or returns an error
func NewNetrc(cfg *Config) (*NetrcAuth, error) {
auth := &NetrcAuth{Config: cfg}

n, err := auth.ParseNetrc()
if err != nil {
return nil, err
}

auth.Netrc = n

return auth, nil
}

// ParseNetrc parses the netrc that is given to the auth manager
func (a *NetrcAuth) ParseNetrc() (*netrc.Netrc, error) {
netrc, err := netrc.Parse(filepath.Join(
a.Config.User.HomeDir,
a.Config.Filename,
))
if err != nil {
return nil, err
}

return netrc, nil
}

// GetAuth retrieves authentication credentials from the parsed netrc file,
// given that the host exists
func (a *NetrcAuth) GetAuth(host string) (string, string, error) {
netrcHost := a.Netrc.Machine(host)
if netrcHost == nil {
return "", "", fmt.Errorf("no auth for %s configured", host)
}

return netrcHost.Get(NetrcUsernameField), netrcHost.Get(NetrcPasswordField), nil
}
95 changes: 95 additions & 0 deletions auth/auth_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
package auth

import (
"io/ioutil"
"os"
"os/user"
"testing"

"github.com/stretchr/testify/assert"
)

// Netrc is a valid netrc configuration file
var Netrc = `
machine host.domain.tld
login user
password secret
`

// ValidUser is a valid root user
var ValidUser = &user.User{
Uid: "1",
Gid: "1",
Username: "root",
HomeDir: "/",
}

// InvalidUser is an invalid user
var InvalidUser = &user.User{
Uid: "99999",
Gid: "99999",
Username: "invaliduser",
HomeDir: "/invaliduser",
}

// Tests whether
func TestAuthParseNetrcInvalidUser(t *testing.T) {
MockAuth := &NetrcAuth{
Config: &Config{
User: InvalidUser,
Filename: ".netrc",
},
}

n, err := MockAuth.ParseNetrc()
assert.Error(t, err)
assert.Nil(t, n)
}

func TestAuthParseNetrcInvalidNetrcFilename(t *testing.T) {
MockAuth := &NetrcAuth{
Config: &Config{
User: ValidUser,
Filename: ".invalidnetrcfilename",
},
}

n, err := MockAuth.ParseNetrc()
assert.Error(t, err)
assert.Nil(t, n)
}

func TestAuthParseNetrcValidUser(t *testing.T) {
tfd, err := ioutil.TempFile("/tmp", ".netrc")
assert.NoError(t, err)
assert.NotNil(t, tfd)

tempName := tfd.Name()

bw, err := tfd.WriteString(Netrc)
assert.NoError(t, err)
assert.NotEqual(t, bw, 0)

assert.NoError(t, tfd.Close())

MockAuth := &NetrcAuth{
Config: &Config{
User: ValidUser,
Filename: tempName,
},
}

n, err := MockAuth.ParseNetrc()
assert.NoError(t, err)
assert.NotNil(t, n)

// This is normally done inside New() but we set it manually here
MockAuth.Netrc = n

user, pass, err := MockAuth.GetAuth("host.domain.tld")
assert.NoError(t, err)
assert.Equal(t, user, "user")
assert.Equal(t, pass, "secret")

os.Remove(tempName)
}
5 changes: 4 additions & 1 deletion main.go → cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ import (
"github.com/urfave/cli"
)

// Version is version information dynamically injected at build time
var Version string

func main() {
sm, err := starmanager.New()
if err != nil {
Expand All @@ -21,7 +24,7 @@ func main() {
cmdline := cli.NewApp()
cmdline.Name = "stars"
cmdline.Usage = "Command-line interface to YOUR GitHub stars"
cmdline.Version = "0.4.8"
cmdline.Version = Version
cmdline.Commands = []cli.Command{
{
Name: "save",
Expand Down
12 changes: 11 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
@@ -1,10 +1,20 @@
module github.com/gkze/stars

require (
github.com/DataDog/zstd v1.4.0 // indirect
github.com/Sereal/Sereal v0.0.0-20190416075407-a9d24ede505a // indirect
github.com/asdine/storm v2.1.2+incompatible
github.com/google/go-github/v19 v19.1.0
github.com/boltdb/bolt v1.3.1 // indirect
github.com/dickeyxxx/netrc v0.0.0-20190329161231-b36f1c51d91d // indirect
github.com/golang/snappy v0.0.1 // indirect
github.com/google/go-github/v25 v25.0.1
github.com/jdxcode/netrc v0.0.0-20180207092346-e1a19c977509
github.com/kr/pretty v0.1.0 // indirect
github.com/stretchr/testify v1.3.0
github.com/urfave/cli v1.20.0
github.com/vmihailenco/msgpack v4.0.4+incompatible // indirect
go.etcd.io/bbolt v1.3.0 // indirect
golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890
golang.org/x/sync v0.0.0-20190412183630-56d357773e84 // indirect
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect
)
46 changes: 40 additions & 6 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,21 +1,55 @@
github.com/DataDog/zstd v1.4.0 h1:vhoV+DUHnRZdKW1i5UMjAk2G4JY8wN4ayRfYDNdEhwo=
github.com/DataDog/zstd v1.4.0/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo=
github.com/Sereal/Sereal v0.0.0-20190416075407-a9d24ede505a h1:Bko8Pi4GKR2wdRwsTXWkEiH3LUcZ6HpgvgYcMZGMd50=
github.com/Sereal/Sereal v0.0.0-20190416075407-a9d24ede505a/go.mod h1:D0JMgToj/WdxCgd30Kc1UcA9E+WdZoJqeVOuYW7iTBM=
github.com/asdine/storm v2.1.2+incompatible h1:dczuIkyqwY2LrtXPz8ixMrU/OFgZp71kbKTHGrXYt/Q=
github.com/asdine/storm v2.1.2+incompatible/go.mod h1:RarYDc9hq1UPLImuiXK3BIWPJLdIygvV3PsInK0FbVQ=
github.com/boltdb/bolt v1.3.1 h1:JQmyP4ZBrce+ZQu0dY660FMfatumYDLun9hBCUVIkF4=
github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps=
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dickeyxxx/netrc v0.0.0-20190329161231-b36f1c51d91d h1:eyRad931+c8mkOQX0i6+nyVVFk73RW9GvbMEpPjOmo4=
github.com/dickeyxxx/netrc v0.0.0-20190329161231-b36f1c51d91d/go.mod h1:yJi2ErNJXXF67mkADCp1kk8AMBFiX48CwUWnsjpCpII=
github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/google/go-github/v19 v19.1.0 h1:EXbrEGEwc4zOSl/exLvlHW+y6hEbhI/En/w7lW2PaBI=
github.com/google/go-github/v19 v19.1.0/go.mod h1:GVHidlOJOqnOChZvI4HBBXoOaZ64OfJRoSoY6uo5BSI=
github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4=
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/google/go-github/v25 v25.0.1 h1:s405kPD52lKa1MVxiEumod/E6/+0pvQ8Ed/sT65DjKc=
github.com/google/go-github/v25 v25.0.1/go.mod h1:6z5pC69qHtrPJ0sXPsj4BLnd82b+r6sLB7qcBoRZqpw=
github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk=
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
github.com/jdxcode/netrc v0.0.0-20180207092346-e1a19c977509 h1:G91xmBQ9Jntm4Dqgb0BGXMRipGBiYLYNWeKcbeJTXPk=
github.com/jdxcode/netrc v0.0.0-20180207092346-e1a19c977509/go.mod h1:PSWm5RA4GUQ+cyCXiBIIUjlDWdJci5cU3GVKwaQRmW8=
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/urfave/cli v1.20.0 h1:fDqGv3UG/4jbVl/QkFwEdddtEDjh/5Ov6X+0B/3bPaw=
github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
github.com/vmihailenco/msgpack v4.0.4+incompatible h1:dSLoQfGFAo3F6OoNhwUmLwVgaUXK79GlxNBwueZn0xI=
github.com/vmihailenco/msgpack v4.0.4+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk=
go.etcd.io/bbolt v1.3.0 h1:oY10fI923Q5pVCVt1GBTZMn8LHo5M+RCInFpeMnV4QI=
go.etcd.io/bbolt v1.3.0/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
golang.org/x/crypto v0.0.0-20180820150726-614d502a4dac/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d h1:g9qWBGx4puODJTMVyoPrpoxPFgVGd+z1DZwjfRu4d0I=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/net v0.0.0-20190311183353-d8887717615a h1:oWX7TPOiFAMXLq8o0ikBYfCJVlRHBcsciT5bXOrH628=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890 h1:uESlIz09WIHT2I+pasSXcpLYqYK8wHcdCetU3VuMBJE=
golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/sys v0.0.0-20180824143301-4910a1d54f87/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190412183630-56d357773e84 h1:IqXQ59gzdXv58Jmm2xn0tSOR9i6HqroaOFRQ3wR/dJQ=
golang.org/x/sync v0.0.0-20190412183630-56d357773e84/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a h1:1BGLXjeY4akVXGgbC9HugT3Jv3hCI0z56oJR5vAMgBU=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
google.golang.org/appengine v1.1.0 h1:igQkv0AAhEIvTEpD5LIpAfav2eeVO9HBTjvKHVJPRSs=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
11 changes: 9 additions & 2 deletions starmanager/starmanager.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ import (
"github.com/asdine/storm"
"github.com/asdine/storm/q"
"github.com/gkze/stars/utils"
"github.com/google/go-github/v19/github"
"github.com/gkze/stars/auth"
"github.com/google/go-github/v25/github"
)

// GITHUB - the GitHub API host
Expand Down Expand Up @@ -56,7 +57,13 @@ type StarManager struct {

// New - initialize a new starmanager
func New() (*StarManager, error) {
username, password, err := utils.GetNetrcAuth(GITHUB)
cfg, err := auth.NewConfig()
if err != nil {
return nil, err
}

netrcAuth, err := auth.NewNetrc(cfg)
username, password, err := netrcAuth.GetAuth(GITHUB)
if err != nil {
return nil, err
}
Expand Down
Loading

0 comments on commit 2fb3dbd

Please sign in to comment.