Skip to content

Commit 208f1c5

Browse files
author
Daisuke Miyamoto
committed
Merge branch 'release/0.2'
2 parents 9859609 + 519f94e commit 208f1c5

File tree

7 files changed

+143
-20
lines changed

7 files changed

+143
-20
lines changed

README.md

Lines changed: 70 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,22 @@ aurl
33

44
## Description
55

6-
HTTP CLI client with OAuth2 authentication
6+
HTTP CLI client with OAuth 2.0 authentication.
77

8-
curl is powerful command line tool and you can make any complex HTTP request to every servers. But the target web
9-
server is secured by OAuth2, you must request another HTTP request to the authorization server before making
10-
principal request. And more, you should to manage issued access tokens for every resources.
8+
You know `curl` is powerful command line tool and you can make any complex HTTP request to every servers. But the target web server is secured by OAuth 2.0, you must send another HTTP request to the authorization server before making principal request. And more, you should to manage issued access tokens for every resources.
119

12-
aurl is auto processing OAuth dance and manage access/refresh tokens.
10+
`aurl` is a command-line tool that process OAuth 2.0 dance and manage access/refresh tokens automatically.
11+
12+
**Note:** Currently, `aurl` is not support OAuth 1.0a. Your pull-request is appreciated.
1313

1414
## Install
1515

16-
To install, use `go get`:
16+
To install, use `homebrew` or `go get`:
17+
18+
```bash
19+
$ brew tap classmethod-aws/cm
20+
$ brew install aurl
21+
```
1722

1823
```bash
1924
$ go get -d github.com/classmethod-aws/aurl
@@ -23,10 +28,29 @@ $ go get -d github.com/classmethod-aws/aurl
2328

2429
### Profile configuration
2530

26-
First, you MUST create profile setting file `~/.aurl/profiles` file which format is described below.
31+
First, you must create profile setting file `~/.aurl/profiles` file which format is described below.
2732
Profile setting file format is typically called [INI file](http://en.wikipedia.org/wiki/INI_file).
2833
Each section name is used as profile name.
2934

35+
###### SYNOPSIS
36+
37+
Section name is utilized as profile name. In each section following key settings are available:
38+
39+
| key name | description | default value | available values | mandatory |
40+
| ----------------------------- | --------------------------------- |:-------------:|:----------------:|:-------------------------------:|
41+
| grant\_type | OAuth2 grant type (implicit flow is not supported currently) | authorization_code | authorization_code, password | no |
42+
| client\_id | client id | aurl | (any) | no |
43+
| client_secret | client secret | aurl | (any) | no |
44+
| auth\_server\_auth\_endpoint | OAuth2 authorization endpoint URI | (none) | (any) | YES (except for password grant) |
45+
| auth\_server\_token\_endpoint | OAuth2 token endpoint URI | (none) | (any) | YES |
46+
| redirect | redirect URI | (none) | (any) | YES (except for password grant) |
47+
| scopes | space separated scope values | read write | (any) | no |
48+
| username | username for password grant | (none) | (any) | no (except for password grant) |
49+
| password | password for password grant | (none) | (any) | no (except for password grant) |
50+
51+
52+
###### EXAMPLE
53+
3054
```
3155
[default]
3256
auth_server_auth_endpoint = https://api.example.com/oauth/authorize
@@ -35,16 +59,36 @@ redirect = https://api.example.com/oauth/oob
3559
3660
[foobar]
3761
grant_type = password
62+
client_id = foobar
63+
client_secret = bazqux
3864
auth_server_token_endpoint = https://api.example.com/oauth/token
65+
scopes = read write global
3966
username = john
4067
password = pass1234
68+
69+
[fb]
70+
client_id = your_facebook_App_ID
71+
client_secret = your_facebook_App_Secret
72+
auth_server_auth_endpoint = https://www.facebook.com/dialog/oauth
73+
auth_server_token_endpoint = https://graph.facebook.com/oauth/access_token
74+
redirect = https://www.facebook.com/connect/login_success.html
75+
scopes = public_profile email user_friends
76+
77+
[google]
78+
client_id = xxxxxxxx.apps.googleusercontent.com
79+
client_secret = yyyyyyyy
80+
auth_server_auth_endpoint = https://accounts.google.com/o/oauth2/auth
81+
auth_server_token_endpoint = https://www.googleapis.com/oauth2/v3/token
82+
redirect = urn:ietf:wg:oauth:2.0:oob
83+
scopes = https://www.googleapis.com/auth/plus.login https://www.googleapis.com/auth/userinfo.email
84+
4185
```
4286

4387
### Token store file
4488

4589
Token store file `~/.aurl/tokens` is used by acurl internally. Retrieved access/refresh token is stored in this file.
4690
You SHOULD NOT edit this file manually because this file is overwritten every time curl is executed.
47-
You MAY lose comment and another extra data.
91+
You may lose comment and another extra data.
4892

4993
Just for information, token sotore file example is following:
5094

@@ -59,6 +103,12 @@ refresh_token = yyyy
59103
expiry = 1424141030
60104
access_token = zzzz
61105
token_type = bearer
106+
107+
[fb]
108+
refresh_token =
109+
expiry = 1429580553
110+
access_token = blahblah
111+
token_type =
62112
```
63113

64114
### Execution
@@ -69,33 +119,41 @@ token_type = bearer
69119
$ aurl [global options] command [command options] [arguments...]
70120
```
71121

72-
`command` is every http method (e.g. `get`, `post`, `delete`) and first argument is target url.
122+
`command` is every http method (e.g. `get`, `post`, `delete`) and first argument is target url. You can see all `command` in the help message. Try, `aurl -h`.
73123

74124
###### EXAMPLE
75125

76126
```bash
77127
$ aurl get http://api.example.com/path/to/resource
128+
...http.response.body...
78129
$ aurl post http://api.example.com/path/to/resource --data "foobar"
130+
...http.response.body...
79131
```
80132

81133
aurl make request with access token in `Authorization` header of `default` profile.
82134
You can specify profile name with `--profile` option.
83135

84136
```bash
85-
$ aurl --profile foobar get http://api.example.com/path/to/resource
137+
$ aurl --profile fb get https://graph.facebook.com/me
138+
{"id":"...","email": ... }
139+
$ aurl --profile google get https://www.googleapis.com/plus/v1/people/me
140+
{
141+
"kind": "plus#person",
142+
...
143+
}
86144
```
87145

88146
By default aurl prints response body in stdout. When an error occured the detail is printed in stderr.
89147
You may want not response body but response header, then you can use `--no-body` and `--print-headers` option.
90148

91149
```bash
92150
$ aurl --no-body --print-headers options http://api.example.com/path/to/resource
93-
{"Content-Type":["application/json;charset=UTF-8"],"Date":["Tue, 17 Feb 2015 08:16:41 GMT"],"Server":["nginx/1.6.2"], "...": "..."}
151+
{"Content-Type":["application/json;charset=UTF-8"],"Date":["Tue, 17 Feb 2015 08:16:41 GMT"],"Server":["nginx/1.6.2"], ...}
94152
```
95153

96154
## Contribution
97155

98-
1. Fork ([https://github.com/classmethod-aws/oauthttp/fork](https://github.com/classmethod-aws/aurl/fork))
156+
1. Fork ([https://github.com/classmethod-aws/aurl/fork](https://github.com/classmethod-aws/aurl/fork))
99157
1. Create a feature branch named like `feature/something_awesome_feature` from `development` branch
100158
1. Commit your changes
101159
1. Rebase your local changes against the `develop` branch

commands.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -186,14 +186,14 @@ func doRequest(ctx *cli.Context, method string) {
186186

187187
Tracef("doRequest start")
188188
resp, tok, err := doRequest0(ctx, method)
189+
if tok != nil && resp != nil && resp.StatusCode != 401 && resp.StatusCode != 403 {
190+
storeToken(tok)
191+
}
189192
if err != nil {
190193
log.Fatal(err)
191194
return
192195
} else {
193196
Tracef("request done successfully")
194-
if tok != nil {
195-
storeToken(tok)
196-
}
197197
}
198198

199199
Tracef("printing headers")
@@ -311,7 +311,7 @@ func toString(retrieve bool) string {
311311
if retrieve {
312312
return "retrieve"
313313
}
314-
return "sotred"
314+
return "stored"
315315
}
316316

317317
func targetUrl(ctx *cli.Context) (string, error) {

oauth2.go

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ func AccessToken(profileName string, retrieve bool) (*oauth2.Token, bool, error)
3737
return tok, false, nil
3838
}
3939
} else {
40-
Tracef("load error: %v", err)
40+
Tracef("cannot found token store: %v", err)
4141
}
4242
Tracef("==== phase transition to Retrieve")
4343
}
@@ -50,6 +50,8 @@ func AccessToken(profileName string, retrieve bool) (*oauth2.Token, bool, error)
5050
switch grantType {
5151
case "authorization_code":
5252
return authorizationCodeFlow(oauth2Conf)
53+
case "implicit":
54+
return implicitFlow(oauth2Conf)
5355
case "password":
5456
return resourceOwnerPasswordFlow(oauth2Conf, currentProfile[USERNAME], currentProfile[PASSWORD])
5557
case "switch_user":
@@ -74,6 +76,11 @@ func authorizationCodeFlow(oauth2Conf *oauth2.Config) (*oauth2.Token, bool, erro
7476
}
7577
}
7678

79+
func implicitFlow(oauth2Conf *oauth2.Config) (*oauth2.Token, bool, error) {
80+
return &oauth2.Token{}, true, fmt.Errorf("implicit flow is not supported")
81+
// TODO
82+
}
83+
7784
func resourceOwnerPasswordFlow(oauth2Conf *oauth2.Config, username string, password string) (*oauth2.Token, bool, error) {
7885
if tok, err := oauth2Conf.PasswordCredentialsToken(oauth2.NoContext, username, password); err != nil {
7986
return &oauth2.Token{}, true, err

profile.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ const (
1818
PASSWORD = "password"
1919
SOURCE_PROFILE = "source_profile"
2020

21-
DEFAULT_CLIENT_ID = "oauthttp"
22-
DEFAULT_CLIENT_SECRET = "oauthttp"
21+
DEFAULT_CLIENT_ID = "aurl"
22+
DEFAULT_CLIENT_SECRET = "aurl"
2323
DEFAULT_GRANT_TYPE = "authorization_code"
2424
DEFAULT_SCOPES = "read,write"
2525
)

scripts/compile.sh

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#! /bin/bash
2+
set -e
3+
4+
DIR=$(cd $(dirname ${0})/.. && pwd)
5+
cd ${DIR}
6+
7+
XC_ARCH=${XC_ARCH:-386 amd64}
8+
XC_OS=${XC_OS:-darwin linux windows}
9+
10+
rm -rf pkg/
11+
12+
gox -output "pkg/{{.OS}}_{{.Arch}}/{{.Dir}}"
13+

scripts/package.sh

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
#!/bin/bash
2+
set -e
3+
4+
DIR=$(cd $(dirname ${0})/.. && pwd)
5+
cd ${DIR}
6+
7+
# If you prepare version.go
8+
VERSION=$(grep "const Version " version.go | sed -E 's/.*"(.+)"$/\1/')
9+
if [ -z "${VERSION}" ]; then
10+
echo "Please specify a version."
11+
exit 1
12+
fi
13+
14+
if [ -z "${REPO}" ]; then
15+
echo "Please set your Application name in the REPO env var."
16+
exit 1
17+
fi
18+
19+
# Run Compile
20+
./scripts/compile.sh
21+
22+
23+
if [ -d pkg ];then
24+
rm -rf ./pkg/dist
25+
fi
26+
27+
# Package all binary as .zip
28+
mkdir -p ./pkg/dist
29+
for PLATFORM in $(find ./pkg -mindepth 1 -maxdepth 1 -type d); do
30+
PLATFORM_NAME=$(basename ${PLATFORM})
31+
ARCHIVE_NAME=${REPO}_${VERSION}_${PLATFORM_NAME}
32+
33+
if [ $PLATFORM_NAME = "dist" ]; then
34+
continue
35+
fi
36+
37+
pushd ${PLATFORM}
38+
zip ${DIR}/pkg/dist/${ARCHIVE_NAME}.zip ./*
39+
popd
40+
done
41+
42+
# Generate shasum
43+
pushd ./pkg/dist
44+
shasum * > ./${VERSION}_SHASUMS
45+
popd

version.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
package main
22

3-
const Version string = "0.1"
3+
const Version string = "0.2"

0 commit comments

Comments
 (0)