Skip to content

Commit fd08012

Browse files
committed
Merge pull request #211 from Turbo87/doc
Add routing documentations
2 parents 12dc981 + 62c1c86 commit fd08012

File tree

8 files changed

+110
-2
lines changed

8 files changed

+110
-2
lines changed

app/routes/github-authorize.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,19 @@
11
import Ember from 'ember';
22
import ajax from 'ic-ajax';
33

4+
/**
5+
* This route will be called from the GitHub OAuth flow once the user has
6+
* accepted or rejected the data access permissions. It will forward the
7+
* temporary `code` received from the GitHub API to our own API server which
8+
* will exchange it for an access token.
9+
*
10+
* After the exchange the API will return an API token and the user information.
11+
* The result will be stored and the popup window closed. The `/login` route
12+
* will then continue to evaluate the response.
13+
*
14+
* @see https://developer.github.com/v3/oauth/#github-redirects-back-to-your-site
15+
* @see `/login` route
16+
*/
417
export default Ember.Route.extend({
518
beforeModel: function(transition) {
619
return ajax('/authorize', {data: transition.queryParams}).then(function(d) {

app/routes/github-login.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,19 @@
11
import Ember from 'ember';
22
import ajax from 'ic-ajax';
33

4+
/**
5+
* Calling this route will query the `/authorize_url` API endpoint
6+
* and redirect to the received URL to initiate the OAuth flow.
7+
*
8+
* Example URL:
9+
* https://github.com/login/oauth/authorize?client_id=...&state=...&scope=read%3Aorg
10+
*
11+
* Once the user has allowed the OAuth flow access the page will redirect him
12+
* to the `/github_authorize` route of this application.
13+
*
14+
* @see https://developer.github.com/v3/oauth/#redirect-users-to-request-github-access
15+
* @see `/github_authorize` route
16+
*/
417
export default Ember.Route.extend({
518
beforeModel: function() {
619
return ajax('/authorize_url').then(function(url) {

app/routes/login.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
11
import Ember from 'ember';
22

3+
/**
4+
* This route will open a popup window directed at the `/github_login` route.
5+
* After the window has opened it will wait for the window to close and
6+
* then evaluate whether the OAuth flow was successful.
7+
*
8+
* @see `/github_authorize` route
9+
*/
310
export default Ember.Route.extend({
411
beforeModel: function(transition) {
512
try { localStorage.removeItem('github_response'); } catch (e) {}
@@ -45,4 +52,3 @@ export default Ember.Route.extend({
4552
transition.abort();
4653
}
4754
});
48-

src/keyword.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,7 @@ impl Model for Keyword {
139139
fn table_name(_: Option<Keyword>) -> &'static str { "keywords" }
140140
}
141141

142+
/// Handles the `GET /keywords` route.
142143
pub fn index(req: &mut Request) -> CargoResult<Response> {
143144
let conn = try!(req.tx());
144145
let (offset, limit) = try!(req.pagination(10, 100));
@@ -175,6 +176,7 @@ pub fn index(req: &mut Request) -> CargoResult<Response> {
175176
}))
176177
}
177178

179+
/// Handles the `GET /keywords/:keyword_id` route.
178180
pub fn show(req: &mut Request) -> CargoResult<Response> {
179181
let name = &req.params()["keyword_id"];
180182
let conn = try!(req.tx());
@@ -185,4 +187,3 @@ pub fn show(req: &mut Request) -> CargoResult<Response> {
185187
struct R { keyword: EncodableKeyword }
186188
Ok(req.json(&R { keyword: kw.encodable() }))
187189
}
188-

src/krate.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -452,6 +452,7 @@ impl Model for Crate {
452452
fn table_name(_: Option<Crate>) -> &'static str { "crates" }
453453
}
454454

455+
/// Handles the `GET /crates` route.
455456
#[allow(trivial_casts)]
456457
pub fn index(req: &mut Request) -> CargoResult<Response> {
457458
let conn = try!(req.tx());
@@ -574,6 +575,7 @@ pub fn index(req: &mut Request) -> CargoResult<Response> {
574575
}))
575576
}
576577

578+
/// Handles the `GET /summary` route.
577579
pub fn summary(req: &mut Request) -> CargoResult<Response> {
578580
let tx = try!(req.tx());
579581
let num_crates = {
@@ -620,6 +622,7 @@ pub fn summary(req: &mut Request) -> CargoResult<Response> {
620622
}))
621623
}
622624

625+
/// Handles the `GET /crates/:crate_id` route.
623626
pub fn show(req: &mut Request) -> CargoResult<Response> {
624627
let name = &req.params()["crate_id"];
625628
let conn = try!(req.tx());
@@ -643,6 +646,7 @@ pub fn show(req: &mut Request) -> CargoResult<Response> {
643646
}))
644647
}
645648

649+
/// Handles the `PUT /crates/new` route.
646650
pub fn new(req: &mut Request) -> CargoResult<Response> {
647651
let app = req.app().clone();
648652

@@ -817,6 +821,7 @@ fn read_fill<R: Read + ?Sized>(r: &mut R, mut slice: &mut [u8])
817821
Ok(())
818822
}
819823

824+
/// Handles the `GET /crates/:crate_id/:version/download` route.
820825
pub fn download(req: &mut Request) -> CargoResult<Response> {
821826
let crate_name = &req.params()["crate_id"];
822827
let version = &req.params()["version"];
@@ -872,6 +877,7 @@ pub fn download(req: &mut Request) -> CargoResult<Response> {
872877
}
873878
}
874879

880+
/// Handles the `GET /crates/:crate_id/downloads` route.
875881
pub fn downloads(req: &mut Request) -> CargoResult<Response> {
876882
let crate_name = &req.params()["crate_id"];
877883
let tx = try!(req.tx());
@@ -931,6 +937,7 @@ fn user_and_crate(req: &mut Request) -> CargoResult<(User, Crate)> {
931937
Ok((user.clone(), krate))
932938
}
933939

940+
/// Handles the `PUT /crates/:crate_id/follow` route.
934941
pub fn follow(req: &mut Request) -> CargoResult<Response> {
935942
let (user, krate) = try!(user_and_crate(req));
936943
let tx = try!(req.tx());
@@ -946,6 +953,7 @@ pub fn follow(req: &mut Request) -> CargoResult<Response> {
946953
Ok(req.json(&R { ok: true }))
947954
}
948955

956+
/// Handles the `DELETE /crates/:crate_id/follow` route.
949957
pub fn unfollow(req: &mut Request) -> CargoResult<Response> {
950958
let (user, krate) = try!(user_and_crate(req));
951959
let tx = try!(req.tx());
@@ -957,6 +965,7 @@ pub fn unfollow(req: &mut Request) -> CargoResult<Response> {
957965
Ok(req.json(&R { ok: true }))
958966
}
959967

968+
/// Handles the `GET /crates/:crate_id/following` route.
960969
pub fn following(req: &mut Request) -> CargoResult<Response> {
961970
let (user, krate) = try!(user_and_crate(req));
962971
let tx = try!(req.tx());
@@ -968,6 +977,7 @@ pub fn following(req: &mut Request) -> CargoResult<Response> {
968977
Ok(req.json(&R { following: rows.next().is_some() }))
969978
}
970979

980+
/// Handles the `GET /crates/:crate_id/versions` route.
971981
pub fn versions(req: &mut Request) -> CargoResult<Response> {
972982
let crate_name = &req.params()["crate_id"];
973983
let tx = try!(req.tx());
@@ -981,6 +991,7 @@ pub fn versions(req: &mut Request) -> CargoResult<Response> {
981991
Ok(req.json(&R{ versions: versions }))
982992
}
983993

994+
/// Handles the `GET /crates/:crate_id/owners` route.
984995
pub fn owners(req: &mut Request) -> CargoResult<Response> {
985996
let crate_name = &req.params()["crate_id"];
986997
let tx = try!(req.tx());
@@ -993,10 +1004,12 @@ pub fn owners(req: &mut Request) -> CargoResult<Response> {
9931004
Ok(req.json(&R{ users: owners }))
9941005
}
9951006

1007+
/// Handles the `PUT /crates/:crate_id/owners` route.
9961008
pub fn add_owners(req: &mut Request) -> CargoResult<Response> {
9971009
modify_owners(req, true)
9981010
}
9991011

1012+
/// Handles the `DELETE /crates/:crate_id/owners` route.
10001013
pub fn remove_owners(req: &mut Request) -> CargoResult<Response> {
10011014
modify_owners(req, false)
10021015
}
@@ -1054,6 +1067,7 @@ fn modify_owners(req: &mut Request, add: bool) -> CargoResult<Response> {
10541067
Ok(req.json(&R{ ok: true }))
10551068
}
10561069

1070+
/// Handles the `GET /crates/:crate_id/reverse_dependencies` route.
10571071
pub fn reverse_dependencies(req: &mut Request) -> CargoResult<Response> {
10581072
let name = &req.params()["crate_id"];
10591073
let conn = try!(req.tx());

src/lib.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
//! This crate implements the backend server for https://crates.io/
2+
//!
3+
//! All implemented routes are defined in the [middleware](fn.middleware.html) function and
4+
//! implemented in the [keyword](keyword/index.html), [krate](krate/index.html),
5+
//! [user](user/index.html) and [version](version/index.html) modules.
6+
17
#[macro_use] extern crate log;
28
extern crate postgres as pg;
39
extern crate rustc_serialize;

src/user/mod.rs

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,23 @@ impl Model for User {
136136
fn table_name(_: Option<User>) -> &'static str { "users" }
137137
}
138138

139+
/// Handles the `GET /authorize_url` route.
140+
///
141+
/// This route will return an authorization URL for the GitHub OAuth flow including the crates.io
142+
/// `client_id` and a randomly generated `state` secret.
143+
///
144+
/// see https://developer.github.com/v3/oauth/#redirect-users-to-request-github-access
145+
///
146+
/// ## Response Body Example
147+
///
148+
/// ```json
149+
/// {
150+
/// "state": "b84a63c4ea3fcb4ac84",
151+
/// "url": "https://github.com/login/oauth/authorize?client_id=...&state=...&scope=read%3Aorg"
152+
/// }
153+
/// ```
139154
pub fn github_authorize(req: &mut Request) -> CargoResult<Response> {
155+
// Generate a random 16 char ASCII string
140156
let state: String = thread_rng().gen_ascii_chars().take(16).collect();
141157
req.session().insert("github_oauth_state".to_string(), state.clone());
142158

@@ -147,6 +163,34 @@ pub fn github_authorize(req: &mut Request) -> CargoResult<Response> {
147163
Ok(req.json(&R { url: url.to_string(), state: state }))
148164
}
149165

166+
/// Handles the `GET /authorize` route.
167+
///
168+
/// This route is called from the GitHub API OAuth flow after the user accepted or rejected
169+
/// the data access permissions. It will check the `state` parameter and then call the GitHub API
170+
/// to exchange the temporary `code` for an API token. The API token is returned together with
171+
/// the corresponding user information.
172+
///
173+
/// see https://developer.github.com/v3/oauth/#github-redirects-back-to-your-site
174+
///
175+
/// ## Query Parameters
176+
///
177+
/// - `code` – temporary code received from the GitHub API **(Required)**
178+
/// - `state` – state parameter received from the GitHub API **(Required)**
179+
///
180+
/// ## Response Body Example
181+
///
182+
/// ```json
183+
/// {
184+
/// "api_token": "b84a63c4ea3fcb4ac84",
185+
/// "user": {
186+
/// "email": "[email protected]",
187+
/// "name": "Foo Bar",
188+
/// "login": "foobar",
189+
/// "avatar": "https://avatars.githubusercontent.com/u/1234",
190+
/// "url": null
191+
/// }
192+
/// }
193+
/// ```
150194
pub fn github_access_token(req: &mut Request) -> CargoResult<Response> {
151195
// Parse the url query
152196
let mut query = req.query();
@@ -197,11 +241,13 @@ pub fn github_access_token(req: &mut Request) -> CargoResult<Response> {
197241
me(req)
198242
}
199243

244+
/// Handles the `GET /logout` route.
200245
pub fn logout(req: &mut Request) -> CargoResult<Response> {
201246
req.session().remove(&"user_id".to_string());
202247
Ok(req.json(&true))
203248
}
204249

250+
/// Handles the `GET /me/reset_token` route.
205251
pub fn reset_token(req: &mut Request) -> CargoResult<Response> {
206252
let user = try!(req.user());
207253

@@ -215,6 +261,7 @@ pub fn reset_token(req: &mut Request) -> CargoResult<Response> {
215261
Ok(req.json(&R { api_token: token }))
216262
}
217263

264+
/// Handles the `GET /me` route.
218265
pub fn me(req: &mut Request) -> CargoResult<Response> {
219266
let user = try!(req.user());
220267

@@ -224,6 +271,7 @@ pub fn me(req: &mut Request) -> CargoResult<Response> {
224271
Ok(req.json(&R{ user: user.clone().encodable(), api_token: token }))
225272
}
226273

274+
/// Handles the `GET /me/updates` route.
227275
pub fn updates(req: &mut Request) -> CargoResult<Response> {
228276
let user = try!(req.user());
229277
let (offset, limit) = try!(req.pagination(10, 100));

src/version.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,7 @@ impl Model for Version {
210210
fn table_name(_: Option<Version>) -> &'static str { "versions" }
211211
}
212212

213+
/// Handles the `GET /versions` route.
213214
pub fn index(req: &mut Request) -> CargoResult<Response> {
214215
let conn = try!(req.tx());
215216

@@ -247,6 +248,7 @@ pub fn index(req: &mut Request) -> CargoResult<Response> {
247248
Ok(req.json(&R { versions: versions }))
248249
}
249250

251+
/// Handles the `GET /versions/:version_id` route.
250252
pub fn show(req: &mut Request) -> CargoResult<Response> {
251253
let (version, krate) = match req.params().find("crate_id") {
252254
Some(..) => try!(version_and_crate(req)),
@@ -281,6 +283,7 @@ fn version_and_crate(req: &mut Request) -> CargoResult<(Version, Crate)> {
281283
Ok((version, krate))
282284
}
283285

286+
/// Handles the `GET /crates/:crate_id/:version/dependencies` route.
284287
pub fn dependencies(req: &mut Request) -> CargoResult<Response> {
285288
let (version, _) = try!(version_and_crate(req));
286289
let tx = try!(req.tx());
@@ -294,6 +297,7 @@ pub fn dependencies(req: &mut Request) -> CargoResult<Response> {
294297
Ok(req.json(&R{ dependencies: deps }))
295298
}
296299

300+
/// Handles the `GET /crates/:crate_id/:version/downloads` route.
297301
pub fn downloads(req: &mut Request) -> CargoResult<Response> {
298302
let (version, _) = try!(version_and_crate(req));
299303

@@ -313,6 +317,7 @@ pub fn downloads(req: &mut Request) -> CargoResult<Response> {
313317
Ok(req.json(&R{ version_downloads: downloads }))
314318
}
315319

320+
/// Handles the `GET /crates/:crate_id/:version/authors` route.
316321
pub fn authors(req: &mut Request) -> CargoResult<Response> {
317322
let (version, _) = try!(version_and_crate(req));
318323
let tx = try!(req.tx());
@@ -331,10 +336,12 @@ pub fn authors(req: &mut Request) -> CargoResult<Response> {
331336
Ok(req.json(&R{ users: users, meta: Meta { names: names } }))
332337
}
333338

339+
/// Handles the `DELETE /crates/:crate_id/:version/yank` route.
334340
pub fn yank(req: &mut Request) -> CargoResult<Response> {
335341
modify_yank(req, true)
336342
}
337343

344+
/// Handles the `PUT /crates/:crate_id/:version/unyank` route.
338345
pub fn unyank(req: &mut Request) -> CargoResult<Response> {
339346
modify_yank(req, false)
340347
}

0 commit comments

Comments
 (0)