-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
pyama86
committed
Jan 30, 2020
0 parents
commit 1913868
Showing
8 changed files
with
288 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
*.test |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
## 0.1.0 (2020-01-30) | ||
|
||
Initial release | ||
|
||
### Added | ||
|
||
- Add Fundamental features | ||
|
||
### Deprecated | ||
|
||
- Nothing | ||
|
||
### Removed | ||
|
||
- Nothing | ||
|
||
### Fixed | ||
|
||
- Nothing |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
VERSION := $(shell git tag | tail -n1 | sed 's/v//g') | ||
REVISION := $(shell git rev-parse --short HEAD) | ||
INFO_COLOR=\033[1;34m | ||
RESET=\033[0m | ||
BOLD=\033[1m | ||
ifeq ("$(shell uname)","Darwin") | ||
GO ?= GO111MODULE=on go | ||
else | ||
GO ?= GO111MODULE=on /usr/local/go/bin/go | ||
endif | ||
|
||
TEST ?= $(shell $(GO) list ./... | grep -v -e vendor -e keys -e tmp) | ||
build: | ||
$(GO) build -o nke -ldflags "-X main.Version=$(VERSION)-$(REVISION)" | ||
|
||
deps: | ||
go get -u golang.org/x/lint/golint | ||
|
||
git-semv: | ||
brew tap linyows/git-semv | ||
brew install git-semv | ||
|
||
goreleaser: | ||
brew install goreleaser/tap/goreleaser | ||
brew install goreleaser | ||
|
||
ci: unit_test lint | ||
lint: deps | ||
@echo "$(INFO_COLOR)==> $(RESET)$(BOLD)Linting$(RESET)" | ||
golint -min_confidence 1.1 -set_exit_status $(TEST) | ||
|
||
unit_test: ## Run test | ||
@echo "$(INFO_COLOR)==> $(RESET)$(BOLD)Testing$(RESET)" | ||
$(GO) test -v $(TEST) -timeout=30s -parallel=4 -coverprofile cover.out.tmp | ||
cat cover.out.tmp | grep -v -e "main.go" -e "cmd.go" -e "_mock.go" > cover.out | ||
$(GO) tool cover -func cover.out | ||
$(GO) test -race $(TEST) | ||
|
||
release: releasedeps | ||
git semv patch --bump | ||
goreleaser --rm-dist | ||
run: | ||
$(GO) run main.go version.go cli.go |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
# pam-google-web-oauth | ||
|
||
|
||
|
||
## Description | ||
|
||
## Usage | ||
|
||
## Install | ||
|
||
To install, use `go get`: | ||
|
||
```bash | ||
$ go get -d github.com/pyama86/pam-google-web-oauth | ||
``` | ||
|
||
## Contribution | ||
|
||
1. Fork ([https://github.com/pyama86/pam-google-web-oauth/fork](https://github.com/pyama86/pam-google-web-oauth/fork)) | ||
1. Create a feature branch | ||
1. Commit your changes | ||
1. Rebase your local changes against the master branch | ||
1. Run test suite with the `go test ./...` command and confirm that it passes | ||
1. Run `gofmt -s` | ||
1. Create a new Pull Request | ||
|
||
## Author | ||
|
||
[pyama86](https://github.com/pyama86) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,151 @@ | ||
package main | ||
|
||
import ( | ||
"context" | ||
"encoding/json" | ||
"flag" | ||
"fmt" | ||
"io" | ||
"io/ioutil" | ||
"log" | ||
"net/url" | ||
"os" | ||
"os/user" | ||
"path/filepath" | ||
|
||
"github.com/sirupsen/logrus" | ||
"golang.org/x/oauth2" | ||
"golang.org/x/oauth2/google" | ||
) | ||
|
||
// Exit codes are int values that represent an exit code for a particular error. | ||
const ( | ||
ExitCodeOK int = 0 | ||
ExitCodeError int = 1 + iota | ||
) | ||
|
||
// CLI is the command line object | ||
type CLI struct { | ||
// outStream and errStream are the stdout and stderr | ||
// to write message from the CLI. | ||
outStream, errStream io.Writer | ||
} | ||
|
||
// Run invokes the CLI with the given arguments. | ||
func (cli *CLI) Run(args []string) int { | ||
var ( | ||
config string | ||
version bool | ||
) | ||
|
||
flags := flag.NewFlagSet(Name, flag.ContinueOnError) | ||
flags.SetOutput(cli.errStream) | ||
|
||
flags.StringVar(&config, "config", "/etc/pam-google-web-oauth/client_secret.json", "Config file path") | ||
flags.StringVar(&config, "c", "/etc/pam-google-web-oauth/client_secret.json", "Config file path(Short)") | ||
|
||
flags.BoolVar(&version, "version", false, "Print version information and quit.") | ||
|
||
// Parse commandline flag | ||
if err := flags.Parse(args[1:]); err != nil { | ||
return ExitCodeError | ||
} | ||
|
||
// Show version | ||
if version { | ||
fmt.Fprintf(cli.errStream, "%s version %s\n", Name, Version) | ||
return ExitCodeOK | ||
} | ||
if err := cli.run(config); err != nil { | ||
logrus.Error(err) | ||
return ExitCodeError | ||
} | ||
return ExitCodeOK | ||
|
||
} | ||
func (cli *CLI) run(config string) error { | ||
ctx := context.Background() | ||
b, err := ioutil.ReadFile(config) | ||
if err != nil { | ||
log.Fatalf("Unable to read client secret file: %s", config) | ||
} | ||
|
||
gconfig, err := google.ConfigFromJSON(b, "profile") | ||
if err != nil { | ||
fmt.Errorf("Unable to parse client secret file to config: %v", err) | ||
} | ||
err = auth(ctx, gconfig) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
return nil | ||
|
||
} | ||
|
||
func auth(ctx context.Context, c *oauth2.Config) error { | ||
cacheFile, err := tokenCacheFile() | ||
if err != nil { | ||
return err | ||
} | ||
tok, err := tokenFromFile(cacheFile) | ||
if err != nil || !tok.Valid() { | ||
tok, err := getTokenFromWeb(c) | ||
if err != nil { | ||
return err | ||
} | ||
return saveToken(cacheFile, tok) | ||
} | ||
return nil | ||
} | ||
|
||
func getTokenFromWeb(c *oauth2.Config) (*oauth2.Token, error) { | ||
authURL := c.AuthCodeURL("state-token", oauth2.AccessTypeOffline) | ||
fmt.Printf("Go to the following link in your browser then type the "+ | ||
"authorization code: \n\n%v\n\nPlease type code:", authURL) | ||
|
||
var code string | ||
if _, err := fmt.Scan(&code); err != nil { | ||
return nil, fmt.Errorf("Unable to read authorization code %v", err) | ||
} | ||
|
||
tok, err := c.Exchange(oauth2.NoContext, code) | ||
if err != nil { | ||
return nil, fmt.Errorf("Unable to retrieve token from web %v", err) | ||
} | ||
return tok, nil | ||
} | ||
|
||
func tokenCacheFile() (string, error) { | ||
userInfo, err := user.Lookup(os.Getenv("PAM_USER")) | ||
if err != nil { | ||
return "", err | ||
} | ||
tokenCacheDir := filepath.Join(userInfo.HomeDir, ".credentials") | ||
err = os.MkdirAll(tokenCacheDir, 0700) | ||
if err != nil { | ||
return "", err | ||
} | ||
return filepath.Join(tokenCacheDir, url.QueryEscape("google_oauth.json")), nil | ||
} | ||
|
||
func tokenFromFile(file string) (*oauth2.Token, error) { | ||
f, err := os.Open(file) | ||
if err != nil { | ||
return nil, err | ||
} | ||
t := &oauth2.Token{} | ||
err = json.NewDecoder(f).Decode(t) | ||
defer f.Close() | ||
return t, err | ||
} | ||
|
||
func saveToken(file string, token *oauth2.Token) error { | ||
fmt.Printf("Saving credential file to: %s\n", file) | ||
f, err := os.OpenFile(file, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0600) | ||
if err != nil { | ||
log.Fatalf("Unable to cache oauth token: %v", err) | ||
} | ||
defer f.Close() | ||
return json.NewEncoder(f).Encode(token) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
package main | ||
|
||
import ( | ||
"bytes" | ||
"fmt" | ||
"strings" | ||
"testing" | ||
) | ||
|
||
func TestRun_versionFlag(t *testing.T) { | ||
outStream, errStream := new(bytes.Buffer), new(bytes.Buffer) | ||
cli := &CLI{outStream: outStream, errStream: errStream} | ||
args := strings.Split("./pam-google-web-oauth -version", " ") | ||
|
||
status := cli.Run(args) | ||
if status != ExitCodeOK { | ||
t.Errorf("expected %d to eq %d", status, ExitCodeOK) | ||
} | ||
|
||
expected := fmt.Sprintf("pam-google-web-oauth version %s", Version) | ||
if !strings.Contains(errStream.String(), expected) { | ||
t.Errorf("expected %q to eq %q", errStream.String(), expected) | ||
} | ||
} | ||
|
||
func TestRun_configFlag(t *testing.T) { | ||
outStream, errStream := new(bytes.Buffer), new(bytes.Buffer) | ||
cli := &CLI{outStream: outStream, errStream: errStream} | ||
args := strings.Split("./pam-google-web-oauth -config", " ") | ||
|
||
status := cli.Run(args) | ||
_ = status | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
package main | ||
|
||
import "os" | ||
|
||
func main() { | ||
cli := &CLI{outStream: os.Stdout, errStream: os.Stderr} | ||
os.Exit(cli.Run(os.Args)) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
package main | ||
|
||
const Name string = "pam-google-web-oauth" | ||
const Version string = "0.1.0" |