fidor_starter_kits 0.3.3 → 0.3.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +7 -2
- data/README.md +4 -5
- data/lib/fidor_starter_kits/version.rb +2 -2
- data/lib/fidor_starter_kits.rb +4 -4
- data/spec/fidor_starter_kits_spec.rb +7 -7
- data/starter_kits/golang_plain/example.go +170 -91
- data/starter_kits/node_tx/example.js +246 -40
- data/starter_kits/{php_plain → php_oauth_plain}/.fidor_meta.json +2 -2
- data/starter_kits/{php_plain → php_oauth_plain}/README.md +1 -1
- data/starter_kits/{php_plain → php_oauth_plain}/example.php +12 -13
- data/starter_kits/ruby_oauth_plain/.fidor_meta.json +7 -0
- data/starter_kits/{sinatra_plain → ruby_oauth_plain}/Gemfile +1 -2
- data/starter_kits/{sinatra_plain → ruby_oauth_plain}/README.md +2 -2
- data/starter_kits/ruby_oauth_plain/example.rb +39 -0
- metadata +9 -9
- data/starter_kits/sinatra_plain/.fidor_meta.json +0 -7
- data/starter_kits/sinatra_plain/example.rb +0 -40
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0d9257e8f3fd57a085a5bfad18e7d08e17f0410d
|
4
|
+
data.tar.gz: 6cc26babb8d847a711d48556b3285b3a3543cb70
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 475514d665725df63f3c2047df7b0dd7878f0c8b838045f80603829a938d0e1f4f3dc4e32a05e04e1edee4c9c9d24b5684a323e5c035b8c7fa7a30d9e6e1e101
|
7
|
+
data.tar.gz: effb9982ec4dea6dab0b50460f6c527b72686259dad4ff31d71d63a8a48a178ccf3e802d36bc8034142174ddf44b3052c22a33085d6bbd0efb4d24d80ff5d30a
|
data/CHANGELOG.md
CHANGED
@@ -1,8 +1,13 @@
|
|
1
1
|
# Changelog Fidor Admin API Schema
|
2
2
|
See [commit messages](https://github.com/fidor/fidor_starter_kits/commits/) for details.
|
3
3
|
|
4
|
-
##2015-
|
5
|
-
|
4
|
+
##2015-06
|
5
|
+
|
6
|
+
* fix usage of access_token in api URLs, now set in Authorization Header
|
7
|
+
|
8
|
+
##2015-01
|
9
|
+
|
10
|
+
*fix proper TLS handling for node example
|
6
11
|
|
7
12
|
##2014-12
|
8
13
|
|
data/README.md
CHANGED
@@ -11,7 +11,6 @@ information into the source files and delivers the example as zipped download.
|
|
11
11
|
If you choose the manual way to explore our example apps, simply checkout this
|
12
12
|
repo, register and app and add the required credentials, URL's to the sources.
|
13
13
|
|
14
|
-
|
15
14
|
For Ruby Heros, this repo is also available as ruby gem and provides a tiny
|
16
15
|
helper for app creation, see Install & Usage.
|
17
16
|
|
@@ -57,18 +56,18 @@ application manager. Before the following placeholders inside in your main
|
|
57
56
|
example.xy file are substituted with the according values from the app
|
58
57
|
(client_id/secret) and the values in .fidor_meta.json:
|
59
58
|
|
60
|
-
<APP_URL>
|
59
|
+
<APP_URL> # default http://localhost:8000/example.php
|
61
60
|
<CLIENT_ID>
|
62
61
|
<CLIENT_SECRET>
|
63
|
-
<FIDOR_OAUTH_URL>
|
64
|
-
<FIDOR_API_URL>
|
62
|
+
<FIDOR_OAUTH_URL> # e.g Sandbox: https://aps.fidor.de/oauth / Live: https://apm.fidor.de/oauth
|
63
|
+
<FIDOR_API_URL> # e.g Sandbox: https://aps.fidor.de / Live: https://api.fidor.de
|
65
64
|
|
66
65
|
So just add those to example.[rb, php, ..] and see existing examples and specs
|
67
66
|
for a reference.
|
68
67
|
|
69
68
|
## Contributing
|
70
69
|
|
71
|
-
1. Fork it (
|
70
|
+
1. Fork it (https://github.com/fidor/fidor_starter_kits/fork )
|
72
71
|
2. Create your feature branch (`git checkout -b my-new-feature`)
|
73
72
|
3. Commit your changes (`git commit -am 'Add some feature'`)
|
74
73
|
4. Push to the branch (`git push origin my-new-feature`)
|
@@ -1,3 +1,3 @@
|
|
1
1
|
module FidorStarterKits
|
2
|
-
VERSION = '0.3.
|
3
|
-
end
|
2
|
+
VERSION = '0.3.5'
|
3
|
+
end
|
data/lib/fidor_starter_kits.rb
CHANGED
@@ -6,7 +6,7 @@ require 'json'
|
|
6
6
|
|
7
7
|
module FidorStarterKits
|
8
8
|
|
9
|
-
STARTER_KITS = %w{ node_tx golang_plain
|
9
|
+
STARTER_KITS = %w{ node_tx golang_plain php_oauth_plain ruby_oauth_plain java_servlet }
|
10
10
|
|
11
11
|
class << self
|
12
12
|
|
@@ -70,7 +70,7 @@ module FidorStarterKits
|
|
70
70
|
if File.exists? meta
|
71
71
|
File.open(meta) {|f| @conf[kit] = JSON.parse(f.read)}
|
72
72
|
else
|
73
|
-
@conf[kit] = "
|
73
|
+
@conf[kit] = {"error" => ".fidor_meta.json not found"}
|
74
74
|
end
|
75
75
|
end
|
76
76
|
return @conf
|
@@ -80,8 +80,8 @@ module FidorStarterKits
|
|
80
80
|
all[app_name]
|
81
81
|
end
|
82
82
|
|
83
|
-
def each
|
84
|
-
all.each_value { |conf| yield conf }
|
83
|
+
def each
|
84
|
+
all.each_value { |conf| yield conf }
|
85
85
|
end
|
86
86
|
|
87
87
|
end
|
@@ -4,10 +4,10 @@ describe FidorStarterKits do
|
|
4
4
|
|
5
5
|
describe '.exists?' do
|
6
6
|
it 'is true' do
|
7
|
-
expect( FidorStarterKits.exists?('
|
7
|
+
expect( FidorStarterKits.exists?('ruby_oauth_plain') ).to be
|
8
8
|
end
|
9
9
|
it 'is false' do
|
10
|
-
expect( FidorStarterKits.exists?('
|
10
|
+
expect( FidorStarterKits.exists?('ruby_oauth_plain') ).to be
|
11
11
|
end
|
12
12
|
end
|
13
13
|
|
@@ -21,7 +21,7 @@ describe FidorStarterKits do
|
|
21
21
|
|
22
22
|
it 'creates zip file' do
|
23
23
|
opts = {
|
24
|
-
app_name: '
|
24
|
+
app_name: 'ruby_oauth_plain',
|
25
25
|
client_id: '123',
|
26
26
|
client_secret: '12345',
|
27
27
|
app_url: 'localhost'
|
@@ -32,7 +32,7 @@ describe FidorStarterKits do
|
|
32
32
|
|
33
33
|
it 'replaces placeholders in example.rb' do
|
34
34
|
opts = {
|
35
|
-
app_name: '
|
35
|
+
app_name: 'ruby_oauth_plain',
|
36
36
|
client_id: 'my-client-id',
|
37
37
|
client_secret: 'my-client-secret',
|
38
38
|
app_url: 'my-app-url',
|
@@ -49,7 +49,7 @@ describe FidorStarterKits do
|
|
49
49
|
end
|
50
50
|
end
|
51
51
|
|
52
|
-
describe '.all' do
|
52
|
+
describe '.all' do
|
53
53
|
it 'lists all starter kits' do
|
54
54
|
expect(FidorStarterKits.all.count).to eq(FidorStarterKits::STARTER_KITS.size)
|
55
55
|
end
|
@@ -58,8 +58,8 @@ describe FidorStarterKits do
|
|
58
58
|
conf = FidorStarterKits.all
|
59
59
|
expect(conf["golang_plain"]["display_name"]).to eq("Go Plain")
|
60
60
|
expect(conf["node_tx"]["description"]).to eq("A simple nodejs based app, showing how to get user transactions")
|
61
|
-
expect(conf["
|
62
|
-
expect(conf["
|
61
|
+
expect(conf["php_oauth_plain"]["app_name"]).to eq("php_oauth_plain")
|
62
|
+
expect(conf["ruby_oauth_plain"]["app_url"]).to eq("http://localhost:4567")
|
63
63
|
expect(conf["java_servlet"]["callback_urls"]).to eq("http://localhost:8080/JavaServlet/Example")
|
64
64
|
end
|
65
65
|
end
|
@@ -12,78 +12,189 @@ package main
|
|
12
12
|
// $ http://localhost:8080
|
13
13
|
|
14
14
|
import (
|
15
|
+
"crypto/rand"
|
16
|
+
"encoding/hex"
|
15
17
|
"encoding/json"
|
18
|
+
"errors"
|
16
19
|
"fmt"
|
20
|
+
"io"
|
17
21
|
"net/http"
|
18
22
|
"net/url"
|
19
|
-
"
|
23
|
+
"strings"
|
20
24
|
)
|
21
25
|
|
22
26
|
// The following sections define the settings you require for the
|
23
27
|
// app to be able to connect to and authorize itself against the api.
|
24
28
|
|
25
|
-
|
26
|
-
//
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
//
|
31
|
-
|
32
|
-
// The OAuth Endpoint this App provides
|
33
|
-
var oauth_cb_url = "<APP_URL>"
|
34
|
-
|
35
|
-
// The URL of the Fidor API (this changes between Sandbox and
|
36
|
-
// Production)
|
37
|
-
var fidor_api_url = "<FIDOR_API_URL>" // e.g https://fidor.com/api_sandbox vs /api
|
38
|
-
|
39
|
-
|
29
|
+
type Config struct {
|
30
|
+
AppUrl string // where to reach this application
|
31
|
+
ClientId string // OAuth Client_id parameter
|
32
|
+
ClientSecret string // OAuth Client_secret parameter
|
33
|
+
FidorApiUrl string // API endpoint (this changes between Sandbox and Production)
|
34
|
+
FidorOauthUrl string // OAuth endpoint (this changes between Sandbox and Production)
|
35
|
+
}
|
40
36
|
|
37
|
+
var fidorConfig = Config{
|
38
|
+
AppUrl: "<APP_URL>",
|
39
|
+
ClientId: "<CLIENT_ID>",
|
40
|
+
ClientSecret: "<CLIENT_SECRET>",
|
41
|
+
FidorApiUrl: "<FIDOR_API_URL>",
|
42
|
+
FidorOauthUrl: "<FIDOR_OAUTH_URL>",
|
43
|
+
}
|
41
44
|
|
42
45
|
func main() {
|
43
46
|
// register a handler function (see next function) to service
|
44
47
|
// requests ...
|
45
48
|
http.HandleFunc("/", indexHandler)
|
46
|
-
fmt.Printf("Now open
|
49
|
+
fmt.Printf("Now open %s\n", fidorConfig.AppUrl)
|
47
50
|
// ... and start listening.
|
48
|
-
|
51
|
+
if u, err := url.Parse(fidorConfig.AppUrl); err != nil {
|
52
|
+
fmt.Printf("Can't make sense of configured url: %s\nBye.\n", fidorConfig.AppUrl)
|
53
|
+
} else {
|
54
|
+
var hostPort = strings.Split(u.Host, ":")
|
55
|
+
var port = ":8080"
|
56
|
+
if len(hostPort) == 2 {
|
57
|
+
port = ":" + hostPort[1]
|
58
|
+
}
|
59
|
+
http.ListenAndServe(port, nil)
|
60
|
+
}
|
49
61
|
}
|
50
62
|
|
51
63
|
func indexHandler(w http.ResponseWriter, r *http.Request) {
|
64
|
+
if r.Method != "GET" {
|
65
|
+
w.WriteHeader(403)
|
66
|
+
return
|
67
|
+
}
|
52
68
|
|
53
|
-
|
54
|
-
|
69
|
+
switch r.URL.Path {
|
70
|
+
case "/":
|
71
|
+
renderWelcome(w)
|
72
|
+
case "/transactions":
|
73
|
+
render("/transactions", w, r)
|
74
|
+
case "/accounts":
|
75
|
+
render("/accounts", w, r)
|
76
|
+
case "/oauth":
|
77
|
+
handleOAuthCallback(w, r)
|
78
|
+
case "/logout":
|
79
|
+
handleLogout(w, r, "/")
|
80
|
+
default:
|
55
81
|
w.WriteHeader(404)
|
56
|
-
return
|
57
82
|
}
|
83
|
+
}
|
84
|
+
|
85
|
+
const COOKIE_NAME = "GO_SESSION"
|
86
|
+
|
87
|
+
// session database, available access_tokens are mapped to their cookie-session keys
|
88
|
+
var sessions = make(map[string]string)
|
89
|
+
|
90
|
+
// stores a retireved access_token both on the server and the reference in a client-side cookie.
|
91
|
+
func createSession(w http.ResponseWriter, accessToken string) {
|
92
|
+
println(accessToken)
|
93
|
+
rnd := make([]byte, 20, 20)
|
94
|
+
rand.Read(rnd)
|
95
|
+
session := hex.EncodeToString(rnd)
|
96
|
+
sessions[session] = accessToken
|
97
|
+
cookie := http.Cookie{
|
98
|
+
Name: COOKIE_NAME,
|
99
|
+
Value: session,
|
100
|
+
}
|
101
|
+
http.SetCookie(w, &cookie)
|
102
|
+
}
|
103
|
+
|
104
|
+
// proxies an API endpoint. In case the client is not logged in (i.e. no
|
105
|
+
// session cookie is set), the OAuth procedure is initiated. Once the
|
106
|
+
// client is logged, a call the the `endpoint` API endpoint is made and
|
107
|
+
// the results (including errors) are piped to the client.
|
108
|
+
func render(endpoint string, w http.ResponseWriter, r *http.Request) {
|
109
|
+
// check if request has cookie set
|
110
|
+
if cookie, err := r.Cookie(COOKIE_NAME); err != nil {
|
111
|
+
// else redirect to OAuth Authorization EP
|
112
|
+
redirectToOAuth(w, r, endpoint)
|
113
|
+
} else {
|
114
|
+
session := cookie.Value
|
115
|
+
accessToken := sessions[session]
|
58
116
|
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
if values["code"] != nil {
|
63
|
-
// retrieve the actual OAuth access token ....
|
64
|
-
code := values.Get("code")
|
65
|
-
if token, err := retrieveTokenFromCode(code); err != nil {
|
66
|
-
fmt.Printf("err: %v\n", err)
|
117
|
+
// pipe api endpoint
|
118
|
+
ep := fmt.Sprintf("%s/%s", fidorConfig.FidorApiUrl, endpoint)
|
119
|
+
if api_req, err := http.NewRequest("GET", ep, nil); err != nil {
|
67
120
|
w.WriteHeader(500)
|
68
|
-
|
121
|
+
w.Write([]byte(err.Error()))
|
69
122
|
} else {
|
70
|
-
|
71
|
-
|
123
|
+
api_req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", accessToken))
|
124
|
+
|
125
|
+
client := &http.Client{}
|
126
|
+
if api_resp, err := client.Do(api_req); err != nil {
|
127
|
+
w.WriteHeader(500)
|
128
|
+
w.Write([]byte(err.Error()))
|
129
|
+
} else {
|
130
|
+
if api_resp.StatusCode == 401 { // token probably expired
|
131
|
+
handleLogout(w, r, endpoint)
|
132
|
+
return
|
133
|
+
}
|
134
|
+
contentType := http.CanonicalHeaderKey("content-type")
|
135
|
+
w.Header().Set(contentType, api_resp.Header.Get(contentType))
|
136
|
+
w.WriteHeader(api_resp.StatusCode)
|
137
|
+
io.Copy(w, api_resp.Body)
|
138
|
+
}
|
72
139
|
}
|
140
|
+
}
|
141
|
+
}
|
142
|
+
|
143
|
+
// client browser is redirected to `authorize` oauth endpoints. The
|
144
|
+
// `target_endpoint` parameter indicates which application endpoint to
|
145
|
+
// redirect the client to once the access_token has been retrieved.
|
146
|
+
func redirectToOAuth(w http.ResponseWriter, r *http.Request, target_endpoint string) {
|
147
|
+
_redirectURI := fmt.Sprintf("%s/oauth?ep=%s", fidorConfig.AppUrl, target_endpoint)
|
148
|
+
redirectURI := url.QueryEscape(_redirectURI)
|
149
|
+
|
150
|
+
oauthRedirectURL := fmt.Sprintf("%s/authorize?client_id=%s&state=321&response_type=code&redirect_uri=%s", fidorConfig.FidorOauthUrl, fidorConfig.ClientId, redirectURI)
|
151
|
+
http.Redirect(w, r, oauthRedirectURL, 307)
|
152
|
+
}
|
153
|
+
|
154
|
+
// handles the oauth callback (i.e. the redirect that the oauth
|
155
|
+
// authorize call "returns" to the client)
|
156
|
+
func handleOAuthCallback(w http.ResponseWriter, r *http.Request) {
|
157
|
+
code := r.FormValue("code")
|
158
|
+
target := r.FormValue("ep")
|
159
|
+
|
160
|
+
if code == "" || target == "" {
|
161
|
+
w.WriteHeader(500)
|
162
|
+
w.Write([]byte("missing code or target ep"))
|
163
|
+
return
|
164
|
+
}
|
165
|
+
|
166
|
+
if token, err := retrieveTokenFromCode(code, target); err != nil {
|
167
|
+
w.WriteHeader(500)
|
168
|
+
w.Write([]byte(err.Error()))
|
169
|
+
return
|
73
170
|
} else {
|
74
|
-
|
75
|
-
|
76
|
-
oauth_url := fmt.Sprintf("%s/authorize?client_id=%s&state=123&response_type=code&redirect_uri=%s",
|
77
|
-
fidor_oauth_url,
|
78
|
-
client_id,
|
79
|
-
url.QueryEscape(oauth_cb_url))
|
80
|
-
|
81
|
-
header := w.Header()
|
82
|
-
header.Add("location", oauth_url)
|
83
|
-
w.WriteHeader(307)
|
171
|
+
createSession(w, token)
|
172
|
+
http.Redirect(w, r, target, 307)
|
84
173
|
}
|
85
174
|
}
|
86
175
|
|
176
|
+
// clear our application's session, forces user to call the oauth
|
177
|
+
// authorize endpoint again. This may or may not force the user to have
|
178
|
+
// to reenter credentials, depending on whether the user's Fidor session
|
179
|
+
// has expired.
|
180
|
+
func handleLogout(w http.ResponseWriter, r *http.Request, endpoint string) {
|
181
|
+
if cookie, err := r.Cookie(COOKIE_NAME); err == nil {
|
182
|
+
// we have a cookie
|
183
|
+
|
184
|
+
// remove it from our stored sessions
|
185
|
+
session := cookie.Value
|
186
|
+
delete(sessions, session)
|
187
|
+
|
188
|
+
// kill the cookie on the client
|
189
|
+
cookie := http.Cookie{
|
190
|
+
Name: COOKIE_NAME,
|
191
|
+
Value: "",
|
192
|
+
MaxAge: -1,
|
193
|
+
}
|
194
|
+
http.SetCookie(w, &cookie)
|
195
|
+
}
|
196
|
+
http.Redirect(w, r, endpoint, 307)
|
197
|
+
}
|
87
198
|
|
88
199
|
// Our TokenResponse representation used to pick it out from the JSON
|
89
200
|
// returned by the OAuth server.
|
@@ -92,18 +203,22 @@ type TokenResponse struct {
|
|
92
203
|
}
|
93
204
|
|
94
205
|
// Use the OAuth code that the user's browser picked up from the OAuth
|
95
|
-
// server to request an OAuth access_token to use in API requests.
|
96
|
-
|
206
|
+
// server to request an OAuth access_token to use in API requests. The
|
207
|
+
// `target_endpoint` parameter indicates which of this app's endpoints
|
208
|
+
// to redirect the client to once we have the access_token and stored a
|
209
|
+
// reference in the client's cookie.
|
210
|
+
func retrieveTokenFromCode(code string, target_endpoint string) (token string, err error) {
|
97
211
|
// assemble the API endpoint URL and request payload
|
98
|
-
|
212
|
+
redirect_uri := fmt.Sprintf("%s/oauth?ep=%s", fidorConfig.AppUrl, target_endpoint)
|
99
213
|
tokenPayload := url.Values{
|
100
|
-
"client_id": {
|
101
|
-
"client_secret": {
|
214
|
+
"client_id": {fidorConfig.ClientId},
|
215
|
+
"client_secret": {fidorConfig.ClientSecret},
|
102
216
|
"code": {code},
|
103
|
-
"redirect_uri": {url.QueryEscape(
|
217
|
+
"redirect_uri": {url.QueryEscape(redirect_uri)},
|
104
218
|
"grant_type": {"authorization_code"},
|
105
219
|
}
|
106
|
-
// Call
|
220
|
+
// Call the Oauth `token` endpoint
|
221
|
+
tokenUrl := fmt.Sprintf("%s/token", fidorConfig.FidorOauthUrl)
|
107
222
|
if resp, err := http.PostForm(tokenUrl, tokenPayload); err != nil {
|
108
223
|
println(err)
|
109
224
|
return "", err
|
@@ -122,44 +237,8 @@ func retrieveTokenFromCode(code string) (token string, err error) {
|
|
122
237
|
}
|
123
238
|
}
|
124
239
|
|
125
|
-
|
126
|
-
|
127
|
-
// information. This is our internal representation of the returned JSON
|
128
|
-
// used to pick out the user's email.
|
129
|
-
type UserResponse struct {
|
130
|
-
Email string `json:"email"`
|
131
|
-
}
|
132
|
-
|
133
|
-
// function to retrieve user information from the API
|
134
|
-
func getUser(token string) (u UserResponse, err error) {
|
135
|
-
// Assemble endpoint URL...
|
136
|
-
url := fmt.Sprintf("%s/users/current?access_token=%s", fidor_api_url, token)
|
137
|
-
if resp, err := http.Get(url); err != nil {
|
138
|
-
return u, err
|
139
|
-
} else {
|
140
|
-
decoder := json.NewDecoder(resp.Body)
|
141
|
-
if err = decoder.Decode(&u); err != nil {
|
142
|
-
return u, err
|
143
|
-
} else {
|
144
|
-
return u, nil
|
145
|
-
}
|
146
|
-
}
|
147
|
-
}
|
148
|
-
|
149
|
-
|
150
|
-
// once all the OAuth calls have been taken care of, this function is
|
151
|
-
// called from the http handler. It retrieves the user's email address
|
152
|
-
// and inserts links to `transaction` and `accounts` endpoints.
|
153
|
-
|
154
|
-
func renderWelcome(w http.ResponseWriter, token string) {
|
155
|
-
if user, err := getUser(token); err != nil {
|
156
|
-
fmt.Printf("err: %v\n", err)
|
157
|
-
w.WriteHeader(500)
|
158
|
-
} else {
|
159
|
-
txLink := fmt.Sprintf("%s/transactions?access_token=%s", fidor_api_url, token)
|
160
|
-
acctsLink := fmt.Sprintf("%s/accounts?access_token=%s", fidor_api_url, token)
|
161
|
-
fmt.Fprintf(w, indexTemplate, user.Email, token, txLink, acctsLink)
|
162
|
-
}
|
240
|
+
func renderWelcome(w http.ResponseWriter) {
|
241
|
+
w.Write([]byte(indexTemplate))
|
163
242
|
}
|
164
243
|
|
165
244
|
var indexTemplate = `
|
@@ -167,10 +246,10 @@ var indexTemplate = `
|
|
167
246
|
<head>
|
168
247
|
</head>
|
169
248
|
<body>
|
170
|
-
<h1>Welcome
|
171
|
-
<
|
172
|
-
<p><a href="
|
173
|
-
<p><a href="
|
249
|
+
<h1>Welcome!</h1>
|
250
|
+
<p><a href="/transactions">Transactions</a></p>
|
251
|
+
<p><a href="/accounts">Accounts</a></p>
|
252
|
+
<p><a href="/logout">Log Out</a></p>
|
174
253
|
</body>
|
175
254
|
</html>
|
176
255
|
`
|
@@ -4,35 +4,49 @@
|
|
4
4
|
//
|
5
5
|
// This sample intentionally does not require any further dependencies.
|
6
6
|
// We tried to keep things as simple as possible in order to illustrate the
|
7
|
-
// underlying mechanisms of the API.
|
7
|
+
// underlying mechanisms of the API. This comes at the expense of having
|
8
|
+
// to handled cookies and session in the sample...
|
8
9
|
//
|
9
10
|
// Using this code
|
10
11
|
// ---------------
|
11
12
|
//
|
13
|
+
// The provided source code is divided into three sections:
|
14
|
+
// 1.) Handling OAuth calls
|
15
|
+
// 2.) Cookie and Session Handling
|
16
|
+
// 3.) Handling Browser Requests
|
17
|
+
//
|
12
18
|
// In order to use this code, a sample app needs to be installed in the
|
13
19
|
// Fidor App Manager. Settings for this app are displayed in the app
|
14
|
-
// manager an need to be transfered into the config below
|
20
|
+
// manager an need to be transfered into the config below, if you
|
21
|
+
// downloaded the code directly from the Fidor App Manager, these
|
22
|
+
// settings should be filled in for you:
|
15
23
|
|
16
24
|
var fidor_config = {
|
17
25
|
app_url : "<APP_URL>",
|
18
26
|
client_id : "<CLIENT_ID>",
|
19
27
|
client_secret : "<CLIENT_SECRET>",
|
20
|
-
fidor_api_url : "<FIDOR_API_URL>"
|
28
|
+
fidor_api_url : "<FIDOR_API_URL>",
|
29
|
+
fidor_oauth_url: "<FIDOR_OAUTH_URL>"
|
21
30
|
}
|
22
31
|
|
23
32
|
|
33
|
+
/************************************************************************
|
34
|
+
/* BEGIN: OAuth Calls
|
35
|
+
************************************************************************/
|
24
36
|
|
25
|
-
|
37
|
+
//
|
26
38
|
// redirect the user to the OAuth authorization endpoint with the
|
27
39
|
// following params:
|
28
40
|
// - client_id
|
29
41
|
// - state
|
30
42
|
// - response_type
|
31
43
|
// - redirect_uri
|
32
|
-
|
33
|
-
|
34
|
-
var
|
35
|
-
|
44
|
+
//
|
45
|
+
function redirect_to_oauth(response, target_endpoint){
|
46
|
+
var _redirect_uri = fidor_config.app_url+"/oauth?ep="+target_endpoint
|
47
|
+
var redirect_uri = encodeURIComponent(_redirect_uri)
|
48
|
+
var oauth_url = fidor_config.fidor_oauth_url+
|
49
|
+
"/authorize?client_id="+fidor_config.client_id+
|
36
50
|
"&state=123&response_type=code&"+
|
37
51
|
"redirect_uri="+redirect_uri
|
38
52
|
response.writeHead(307, {"location" : oauth_url})
|
@@ -40,30 +54,45 @@ function redirect_to_oauth(response){
|
|
40
54
|
return
|
41
55
|
}
|
42
56
|
|
57
|
+
//
|
43
58
|
// Execute a POST request against the OAUTH token endpoint
|
44
59
|
// in order to exchange: code, client_id, client_secret,
|
45
|
-
//
|
46
|
-
|
47
|
-
|
60
|
+
// redirect_uri and grant_type for an auth_token.
|
61
|
+
//
|
62
|
+
// This corresponds to OAuth 3.2 Token Endpoint / 4.1.3 Access Token
|
63
|
+
// Request.
|
64
|
+
//
|
65
|
+
// Parameter:
|
66
|
+
// - the code that was returned from the Authorization Endpoint
|
67
|
+
// - the target endpoint (transactions/ or accounts/) that was requested
|
68
|
+
// in order to reconstruct the 'redirect-uri' parameter of the
|
69
|
+
// Authorization call.
|
70
|
+
// - callback(error, access_token)
|
71
|
+
//
|
72
|
+
function retrieve_access_token_from_code( code, target_endpoint, cb ) {
|
73
|
+
var oauth_url = url.parse(fidor_config.fidor_oauth_url)
|
74
|
+
|
48
75
|
// where to send the data ...
|
49
76
|
var postOptions = {
|
50
77
|
method: "POST",
|
51
|
-
path : oauth_url.path+"/
|
78
|
+
path : oauth_url.path+"/token",
|
52
79
|
port : oauth_url.port,
|
53
80
|
host : oauth_url.hostname
|
54
81
|
}
|
55
82
|
|
56
83
|
// ... what to send
|
84
|
+
var redirect_uri = fidor_config.app_url+"/oauth?ep="+target_endpoint
|
57
85
|
var postData = {
|
58
86
|
code : code,
|
59
87
|
client_id : fidor_config.client_id,
|
60
88
|
client_secret : fidor_config.client_secret,
|
61
|
-
redirect_uri : encodeURIComponent(
|
89
|
+
redirect_uri : encodeURIComponent(redirect_uri),
|
62
90
|
grant_type : "authorization_code"
|
63
91
|
}
|
64
92
|
postData = querystring.stringify(postData)
|
65
93
|
|
66
94
|
var http_module = oauth_url.protocol == "https:" ? https : http
|
95
|
+
|
67
96
|
var token_request = http_module.request(postOptions, function (res) {
|
68
97
|
// collect the data chunks we received and reassemble them
|
69
98
|
// on request end ...
|
@@ -74,7 +103,6 @@ function retrieve_access_token_from_code( code, cb ) {
|
|
74
103
|
|
75
104
|
res.on('end', function() {
|
76
105
|
var oauth_response = JSON.parse(data)
|
77
|
-
console.log(oauth_response)
|
78
106
|
cb(oauth_response.error, oauth_response.access_token)
|
79
107
|
})
|
80
108
|
})
|
@@ -87,39 +115,217 @@ function retrieve_access_token_from_code( code, cb ) {
|
|
87
115
|
token_request.end()
|
88
116
|
}
|
89
117
|
|
118
|
+
/************************************************************************
|
119
|
+
/* END: OAuth Calls
|
120
|
+
************************************************************************/
|
121
|
+
|
122
|
+
|
123
|
+
/************************************************************************
|
124
|
+
/* BEGIN: Cookie & Session Handling
|
125
|
+
************************************************************************/
|
126
|
+
var COOKIE_NAME="NODE_SESSION"
|
127
|
+
var sessions = {}
|
128
|
+
|
129
|
+
// retrieve the random session_id from the cookie.
|
130
|
+
function getSession(req) {
|
131
|
+
var cookies = req.headers.cookie
|
132
|
+
var session = null
|
133
|
+
if (cookies) {
|
134
|
+
var cookieArr = cookies.split(";")
|
135
|
+
for (var i = 0 ; i != cookieArr.length ; ++i) {
|
136
|
+
var keyValue = cookieArr[i].split("=")
|
137
|
+
if (keyValue && keyValue.length == 2 && keyValue[0].trim() == COOKIE_NAME) {
|
138
|
+
session = keyValue[1]
|
139
|
+
break
|
140
|
+
}
|
141
|
+
}
|
142
|
+
}
|
143
|
+
return session
|
144
|
+
}
|
145
|
+
function getAccessTokenFromSession(req) {
|
146
|
+
var session = getSession(req)
|
147
|
+
var access_token = null
|
148
|
+
if (session) {
|
149
|
+
access_token = sessions[session]
|
150
|
+
}
|
151
|
+
return access_token
|
152
|
+
}
|
153
|
+
function createSession(resp, access_token) {
|
154
|
+
function randomString(len) {
|
155
|
+
var hex = "0123456789abcdef"
|
156
|
+
var rnd = ""
|
157
|
+
for (var i = 0; i!= len; ++i) {
|
158
|
+
rnd += hex[Math.floor(Math.random()*hex.length)]
|
159
|
+
}
|
160
|
+
return rnd
|
161
|
+
}
|
162
|
+
var rnd = randomString(20)
|
163
|
+
sessions[rnd] = access_token
|
164
|
+
resp.setHeader("Set-Cookie", COOKIE_NAME+"="+rnd)
|
165
|
+
}
|
166
|
+
function removeSession(req, resp) {
|
167
|
+
// find cookie
|
168
|
+
var session = getSession(req)
|
169
|
+
// delete from sessions
|
170
|
+
delete sessions[session]
|
171
|
+
// set expired
|
172
|
+
resp.setHeader("Set-Cookie", COOKIE_NAME+"=nothing; expires=Thu, 01 Jan 1970 00:00:00 GMT")
|
173
|
+
}
|
174
|
+
|
175
|
+
/************************************************************************
|
176
|
+
/* END: Cookie & Session Handling
|
177
|
+
************************************************************************/
|
178
|
+
|
179
|
+
/************************************************************************
|
180
|
+
/* BEGIN: HTTP Handling
|
181
|
+
************************************************************************/
|
90
182
|
|
183
|
+
//
|
91
184
|
// Display a friendly message and links to the API Endpoints.
|
92
|
-
|
185
|
+
//
|
186
|
+
function renderWelcome(request, response) {
|
93
187
|
response.writeHead(200, {"Content-Type" : "text/html"})
|
94
|
-
|
95
|
-
console.log(content)
|
96
|
-
console.log(token)
|
97
|
-
content = content.replace(/{api_uri}/g, fidor_config.fidor_api_url)
|
98
|
-
response.end(content)
|
188
|
+
response.end(hello_template)
|
99
189
|
}
|
100
190
|
|
101
|
-
// main http functionality
|
102
|
-
function listener (request, response) {
|
103
191
|
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
192
|
+
|
193
|
+
|
194
|
+
function render (endpoint, req, res) {
|
195
|
+
//
|
196
|
+
// call the api endpoint and pipe the response from the API back to
|
197
|
+
// the caller
|
198
|
+
//
|
199
|
+
function pipeApi(endpoint, access_token, res) {
|
200
|
+
var api_endpoint = url.parse(fidor_config.fidor_api_url+endpoint)
|
201
|
+
var http_module = api_endpoint.protocol == "https:" ? https : http
|
202
|
+
var http_options = {
|
203
|
+
hostname: api_endpoint.hostname,
|
204
|
+
path: api_endpoint.path,
|
205
|
+
port: api_endpoint.port,
|
206
|
+
method: "GET",
|
207
|
+
headers: {
|
208
|
+
"Authorization": "Bearer "+access_token
|
209
|
+
}
|
210
|
+
}
|
211
|
+
|
212
|
+
var api_request = http_module.request(http_options, function(api_response) {
|
213
|
+
res.setHeader('Content-Type', api_response.headers['content-type'])
|
214
|
+
if (api_response.statusCode == 401) { // access_token has expired.
|
215
|
+
handleLogout(req, res, endpoint)
|
216
|
+
return
|
217
|
+
}
|
218
|
+
res.writeHead(api_response.statusCode, api_response.statusMessage)
|
219
|
+
api_response.on('data', function(chunk) {
|
220
|
+
res.write(chunk)
|
221
|
+
})
|
222
|
+
api_response.on('end', function(){
|
223
|
+
res.end()
|
224
|
+
})
|
225
|
+
})
|
226
|
+
|
227
|
+
api_request.on('error', function (err) {
|
228
|
+
res.writeHead(500, {'Content-Type': 'text/plain'})
|
229
|
+
res.end(err.toString())
|
230
|
+
})
|
231
|
+
api_request.end()
|
232
|
+
}
|
233
|
+
|
234
|
+
//
|
235
|
+
// utility to check whether access token is via session cookie, if not
|
236
|
+
// redirects account holder to OAuth Authorization Endpoint.
|
237
|
+
//
|
238
|
+
function getAccessToken(redirect, req, res, cb) {
|
239
|
+
var accesstoken = getAccessTokenFromSession(req)
|
240
|
+
if (!accesstoken) {
|
241
|
+
// start OAuth
|
242
|
+
redirect_to_oauth(res, redirect)
|
243
|
+
} else {
|
244
|
+
cb(null, accesstoken)
|
245
|
+
}
|
246
|
+
|
110
247
|
}
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
248
|
+
|
249
|
+
getAccessToken(endpoint, req, res, function (err, accesstoken) {
|
250
|
+
if (err) {
|
251
|
+
res.writeHead(500, {'Content-Type': 'text/plain'})
|
252
|
+
res.end(err.toString())
|
253
|
+
return
|
254
|
+
}
|
255
|
+
pipeApi(endpoint, accesstoken, res)
|
256
|
+
})
|
257
|
+
}
|
258
|
+
|
259
|
+
function renderTransactions (req, res){
|
260
|
+
render("/transactions", req, res)
|
261
|
+
}
|
262
|
+
function renderAccounts (req, res){
|
263
|
+
render("/accounts", req, res)
|
264
|
+
}
|
265
|
+
|
266
|
+
//
|
267
|
+
// retrieve the 'code' parameter from the redirect url the
|
268
|
+
// OAuth Authorization returns to the user's browser
|
269
|
+
//
|
270
|
+
function handleOAuthCallback(req, res) {
|
271
|
+
var u = url.parse(req.url)
|
272
|
+
var query = querystring.parse(u.query)
|
273
|
+
var code = query["code"]
|
274
|
+
var target = query["ep"]
|
275
|
+
|
276
|
+
if (code && target) {
|
277
|
+
retrieve_access_token_from_code( code, target, function (err, token) {
|
278
|
+
if (err) {
|
279
|
+
res.writeHead(500, {'Content-Type': 'text/plain'})
|
280
|
+
res.end(err.toString())
|
281
|
+
return
|
282
|
+
}
|
283
|
+
createSession(res, token)
|
284
|
+
res.writeHead(307, {"location" : target})
|
285
|
+
res.end()
|
116
286
|
})
|
117
287
|
} else {
|
118
|
-
|
119
|
-
|
120
|
-
|
288
|
+
res.writeHead(500, {'Content-Type': 'text/plain'})
|
289
|
+
res.end("missing code or target")
|
290
|
+
}
|
291
|
+
}
|
292
|
+
|
293
|
+
function handleLogout(req, res, endpoint) {
|
294
|
+
// clear session locally and in browser
|
295
|
+
removeSession(req, res)
|
296
|
+
res.writeHead(307, {"location" : endpoint})
|
297
|
+
res.end()
|
298
|
+
}
|
299
|
+
|
300
|
+
function listener (request, response) {
|
301
|
+
var u = url.parse(request.url)
|
302
|
+
|
303
|
+
if (request.method !== "GET") {
|
304
|
+
response.writeHead(403, "Forbidden")
|
305
|
+
response.end()
|
121
306
|
return
|
122
307
|
}
|
308
|
+
|
309
|
+
switch(u.pathname) {
|
310
|
+
case "/":
|
311
|
+
renderWelcome(request, response)
|
312
|
+
break
|
313
|
+
case "/transactions":
|
314
|
+
renderTransactions(request, response)
|
315
|
+
break
|
316
|
+
case "/accounts":
|
317
|
+
renderAccounts(request, response)
|
318
|
+
break
|
319
|
+
case "/oauth":
|
320
|
+
handleOAuthCallback(request, response)
|
321
|
+
break
|
322
|
+
case "/logout":
|
323
|
+
handleLogout(request, response, "/")
|
324
|
+
break
|
325
|
+
default:
|
326
|
+
response.writeHead(404, "Not Found")
|
327
|
+
}
|
328
|
+
|
123
329
|
}
|
124
330
|
|
125
331
|
// Execution starts here...
|
@@ -127,7 +333,7 @@ function listener (request, response) {
|
|
127
333
|
var url = require("url")
|
128
334
|
var querystring = require("querystring")
|
129
335
|
var http = require("http")
|
130
|
-
var https = require("
|
336
|
+
var https = require("https")
|
131
337
|
|
132
338
|
var _url = url.parse(fidor_config.app_url)
|
133
339
|
fidor_config.app_port = _url.port
|
@@ -145,8 +351,8 @@ var hello_template = ""+
|
|
145
351
|
"</head>"+
|
146
352
|
"<body>"+
|
147
353
|
" <h1>Welcome!</h1>"+
|
148
|
-
" <
|
149
|
-
" <p><a href='
|
150
|
-
" <p><a href='
|
354
|
+
" <p><a href='/transactions'>Transactions</a></p>"+
|
355
|
+
" <p><a href='/accounts'>Accounts</a></p>"+
|
356
|
+
" <p><a href='/logout'>Log Out</a></p>"+
|
151
357
|
"</body>"+
|
152
358
|
"</html>"
|
@@ -1,7 +1,7 @@
|
|
1
1
|
{
|
2
|
-
"display_name" : "PHP Plain",
|
2
|
+
"display_name" : "PHP oAuth Plain",
|
3
3
|
"description" : "A simple php script, showing how to get the access token",
|
4
|
-
"app_name":"
|
4
|
+
"app_name":"php_oauth_plain",
|
5
5
|
"app_url":"http://localhost:8000/example.php",
|
6
6
|
"callback_urls":"http://localhost:8000/example.php"
|
7
7
|
}
|
@@ -1,12 +1,13 @@
|
|
1
1
|
<?php
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
3
|
+
$app_url = "<APP_URL>"; # default http://localhost:8000/example.php
|
4
|
+
$app_id = "<CLIENT_ID>";
|
5
|
+
$app_secret = "<CLIENT_SECRET>";
|
6
|
+
$fidor_oauth_url= "<FIDOR_OAUTH_URL>"; # e.g Sandbox: https://aps.fidor.de/oauth / Live: https://apm.fidor.de/oauth
|
7
|
+
$fidor_api_url = "<FIDOR_API_URL>"; # e.g Sandbox: https://aps.fidor.de / Live: https://api.fidor.de
|
8
8
|
|
9
|
-
|
9
|
+
|
10
|
+
$code = $_REQUEST["code"];
|
10
11
|
|
11
12
|
# 1. redirect to authorize url
|
12
13
|
if(empty($code)) {
|
@@ -38,15 +39,13 @@
|
|
38
39
|
$context = stream_context_create($options);
|
39
40
|
$resp = json_decode(file_get_contents($token_url, false, $context));
|
40
41
|
|
41
|
-
|
42
|
-
$usr_url = $fidor_api_url . "/users/current?access_token=" . $resp->access_token;
|
43
|
-
$user = json_decode(file_get_contents($usr_url));
|
44
|
-
$transactions_url = $fidor_api_url . "/transactions?access_token=" . $resp->access_token;
|
45
|
-
echo( "<h2>Hello " . $user->email . "</h2>
|
42
|
+
echo( "<h2>Hello</h2>
|
46
43
|
<i>May I present the access token response:</i>
|
47
44
|
<blockquote>");
|
48
45
|
print_r($resp);
|
49
46
|
echo("</blockquote>
|
50
|
-
<p>Now use the access token
|
47
|
+
<p>Now use the access token in the request header in your favorite PHP HTTP method or via CURL: </p>
|
48
|
+
<blockquote>curl -v -H \"Authorization: Bearer ".$resp->access_token."\" ".$fidor_api_url."/transactions
|
49
|
+
</blockquote>");
|
51
50
|
|
52
|
-
?>
|
51
|
+
?>
|
@@ -0,0 +1,7 @@
|
|
1
|
+
{
|
2
|
+
"display_name" : "Ruby oAuth Plain",
|
3
|
+
"description" : "A simple Ruby app showing the oAuth dance to get and use the access token. Uses Sinatra as server.",
|
4
|
+
"app_name":"ruby_oauth_plain",
|
5
|
+
"app_url":"http://localhost:4567",
|
6
|
+
"callback_urls":"http://localhost:4567"
|
7
|
+
}
|
@@ -1,13 +1,13 @@
|
|
1
1
|
# Ruby Plain oAuth Login - Example
|
2
2
|
|
3
3
|
A single view that demonstrates the Fidor API OAuth login flow and how to get
|
4
|
-
an access token.
|
4
|
+
an access token. Uses Sinatra on its server side.
|
5
5
|
|
6
6
|
## Usage
|
7
7
|
|
8
8
|
This uses bundler to install the required gems:
|
9
9
|
|
10
|
-
cd
|
10
|
+
cd ruby_oauth_plain
|
11
11
|
bundle install
|
12
12
|
ruby example.rb
|
13
13
|
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'sinatra'
|
3
|
+
require 'httparty'
|
4
|
+
|
5
|
+
get '/' do
|
6
|
+
# settings
|
7
|
+
@app_url = '<APP_URL>' # default for local installs: http://localhost:4567
|
8
|
+
@client_id = '<CLIENT_ID>'
|
9
|
+
@client_secret = '<CLIENT_SECRET>'
|
10
|
+
@fidor_oauth_url = '<FIDOR_OAUTH_URL>' # e.g Sandbox: https://aps.fidor.de/oauth / Live: https://apm.fidor.de/oauth
|
11
|
+
@fidor_api_url = '<FIDOR_API_URL>' # e.g Sandbox: https://aps.fidor.de / Live: https://api.fidor.de
|
12
|
+
|
13
|
+
# 1. redirect to authorize url
|
14
|
+
unless code = params["code"]
|
15
|
+
dialog_url = "#{@fidor_oauth_url}/authorize?client_id=#{@client_id}&redirect_uri=#{CGI::escape(@app_url)}&state=1234&response_type=code"
|
16
|
+
redirect dialog_url
|
17
|
+
end
|
18
|
+
|
19
|
+
# 2. get the access token, with code returned from auth dialog above
|
20
|
+
token_url = URI("#{@fidor_oauth_url}/token")
|
21
|
+
post_params = { client_id: @client_id,
|
22
|
+
redirect_uri: CGI::escape(@app_url),
|
23
|
+
code: code,
|
24
|
+
client_secret: @client_secret,
|
25
|
+
grant_type: 'authorization_code' }
|
26
|
+
resp = HTTParty.post(token_url, body: post_params )
|
27
|
+
|
28
|
+
# GET current user setting the access-token in the request header
|
29
|
+
user = HTTParty.get( "#{@fidor_api_url}/users/current",
|
30
|
+
headers: { 'Authorization' => "Bearer #{resp['access_token']}"} )
|
31
|
+
|
32
|
+
"<h2>Hello #{user['email']}</h2>
|
33
|
+
<i>May i present the access token response:</i>
|
34
|
+
<blockquote>#{resp.body}</blockquote>
|
35
|
+
<p>Now use the access token in the Header of your Requests, e.g. using CURL</p>
|
36
|
+
<blockquote>
|
37
|
+
curl -v -H \"Authorization: Bearer #{resp['access_token']}\" #{@fidor_api_url}/accounts
|
38
|
+
</blockquote>"
|
39
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fidor_starter_kits
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Georg Leciejewski
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-06-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rubyzip
|
@@ -109,13 +109,13 @@ files:
|
|
109
109
|
- starter_kits/java_servlet/src/de/fidor/api/example/Example.java
|
110
110
|
- starter_kits/node_tx/.fidor_meta.json
|
111
111
|
- starter_kits/node_tx/example.js
|
112
|
-
- starter_kits/
|
113
|
-
- starter_kits/
|
114
|
-
- starter_kits/
|
115
|
-
- starter_kits/
|
116
|
-
- starter_kits/
|
117
|
-
- starter_kits/
|
118
|
-
- starter_kits/
|
112
|
+
- starter_kits/php_oauth_plain/.fidor_meta.json
|
113
|
+
- starter_kits/php_oauth_plain/README.md
|
114
|
+
- starter_kits/php_oauth_plain/example.php
|
115
|
+
- starter_kits/ruby_oauth_plain/.fidor_meta.json
|
116
|
+
- starter_kits/ruby_oauth_plain/Gemfile
|
117
|
+
- starter_kits/ruby_oauth_plain/README.md
|
118
|
+
- starter_kits/ruby_oauth_plain/example.rb
|
119
119
|
homepage: ''
|
120
120
|
licenses:
|
121
121
|
- MIT
|
@@ -1,40 +0,0 @@
|
|
1
|
-
require 'rubygems'
|
2
|
-
require 'sinatra'
|
3
|
-
require 'active_support/json'
|
4
|
-
require 'net/http'
|
5
|
-
|
6
|
-
get '/' do
|
7
|
-
# settings
|
8
|
-
@app_url = '<APP_URL>' # default for local installs: http://localhost:4567
|
9
|
-
@client_id = '<CLIENT_ID>'
|
10
|
-
@client_secret = '<CLIENT_SECRET>'
|
11
|
-
@fidor_oauth_url = '<FIDOR_OAUTH_URL>' # e.g https://fidor.com/oauth
|
12
|
-
@fidor_api_url = '<FIDOR_API_URL>' # e.g https://fidor.com/api_sandbox, https://fidor.com/api
|
13
|
-
|
14
|
-
# 1. redirect to authorize url
|
15
|
-
unless code = params["code"]
|
16
|
-
dialog_url = "#{@fidor_oauth_url}/authorize?client_id=#{@client_id}&redirect_uri=#{CGI::escape(@app_url)}&state=1234&response_type=code"
|
17
|
-
redirect dialog_url
|
18
|
-
end
|
19
|
-
|
20
|
-
# 2. get the access token, with code returned from auth dialog above
|
21
|
-
token_url = URI("#{@fidor_oauth_url}/token")
|
22
|
-
# GET and parse access_token response json
|
23
|
-
res = Net::HTTP.post_form(token_url, 'client_id' => @client_id,
|
24
|
-
'redirect_uri' => CGI::escape(@app_url),
|
25
|
-
'code' =>code,
|
26
|
-
'client_secret'=>@client_secret,
|
27
|
-
'grant_type'=>'authorization_code')
|
28
|
-
|
29
|
-
resp = ActiveSupport::JSON.decode(res.body)
|
30
|
-
|
31
|
-
# GET current user
|
32
|
-
usr_url = "#{@fidor_api_url}/users/current?access_token=#{resp['access_token']}"
|
33
|
-
user = ActiveSupport::JSON.decode( Net::HTTP.get URI(usr_url) )
|
34
|
-
account_url = "#{@fidor_api_url}/accounts?access_token=#{resp['access_token']}"
|
35
|
-
"<h2>Hello #{user['email']}</h2>
|
36
|
-
<i>May i present the access token response:</i>
|
37
|
-
<blockquote>#{resp.inspect}</blockquote>
|
38
|
-
<p>Now use the access token in <br> <a href='#{account_url}'>#{account_url}</a></p>
|
39
|
-
"
|
40
|
-
end
|