1 | var OAuth2 = require('oauth').OAuth2,
|
2 | querystring = require('querystring'),
|
3 | util = require('util'),
|
4 | task = require('./base');
|
5 |
|
6 |
|
7 |
|
8 | var googleConfig = project.config.consumerConfig.google;
|
9 | var googleScopes = (googleConfig ? googleConfig.scopes : null);
|
10 |
|
11 | if (!googleScopes) {
|
12 |
|
13 | util.extend (googleConfig, {
|
14 | "scopes": {
|
15 | "profile" : "https://www.googleapis.com/auth/userinfo.profile",
|
16 | "userinfo" : "https://www.googleapis.com/auth/userinfo.email",
|
17 | "analytics" : "https://www.google.com/analytics/feeds/",
|
18 | "google_base" : "https://www.google.com/base/feeds/",
|
19 | "google_buzz" : "https://www.googleapis.com/auth/buzz",
|
20 | "book_search" : "https://www.google.com/books/feeds/",
|
21 | "blogger" : "https://www.blogger.com/feeds/",
|
22 | "calendar" : "https://www.google.com/calendar/feeds/",
|
23 | "contacts" : "https://www.google.com/m8/feeds/",
|
24 | "chrome_web store" : "https://www.googleapis.com/auth/chromewebstore.readonly",
|
25 | "documents_list" : "https://docs.google.com/feeds/",
|
26 | "finance" : "https://finance.google.com/finance/feeds/",
|
27 | "gmail" : "https://mail.google.com/mail/feed/atom",
|
28 | "health" : "https://www.google.com/health/feeds/",
|
29 | "h9" : "https://www.google.com/h9/feeds/",
|
30 | "maps" : "https://maps.google.com/maps/feeds/",
|
31 | "moderator" : "https://www.googleapis.com/auth/moderator",
|
32 | "opensocial" : "https://www-opensocial.googleusercontent.com/api/people/",
|
33 | "orkut" : "https://orkut.gmodules.com/social/rest",
|
34 | "picasa_web" : "https://picasaweb.google.com/data/",
|
35 | "sidewiki" : "https://www.google.com/sidewiki/feeds/",
|
36 | "sites" : "https://sites.google.com/feeds/",
|
37 | "spreadsheets" : "https://spreadsheets.google.com/feeds/",
|
38 | "tasks" : "https://www.googleapis.com/auth/tasks",
|
39 | "url_shortener" : "https://www.googleapis.com/auth/urlshortener",
|
40 | "wave" : "http://wave.googleusercontent.com/api/rpc",
|
41 | "webmaster_tools" : "https://www.google.com/webmasters/tools/feeds/",
|
42 | "youtube" : "https://gdata.youtube.com"
|
43 | }
|
44 | });
|
45 |
|
46 | googleScopes = googleConfig.scopes;
|
47 |
|
48 | for (var scope in googleScopes) {
|
49 | googleScopes[scope] = [googleScopes[scope], querystring.escape(googleScopes[scope])];
|
50 | }
|
51 |
|
52 |
|
53 |
|
54 | }
|
55 |
|
56 |
|
57 |
|
58 | var google = module.exports = function(config) {
|
59 |
|
60 | this.scopes = [
|
61 | "profile",
|
62 | "userinfo"
|
63 | ];
|
64 |
|
65 | this.init (config);
|
66 | this.oa = new OAuth2(googleConfig.clientId, googleConfig.clientSecret, googleConfig.baseUrl, googleConfig.authorizePath, googleConfig.requestTokenUrl);
|
67 |
|
68 | };
|
69 |
|
70 | util.inherits (google, task);
|
71 |
|
72 | util.extend (google.prototype, {
|
73 |
|
74 | run: function() {
|
75 |
|
76 | var self = this;
|
77 | self.failed('use method [login|callback|profile]');
|
78 |
|
79 | },
|
80 |
|
81 | login: function () {
|
82 |
|
83 | var self = this;
|
84 | var req = self.req;
|
85 |
|
86 | var scopes = [];
|
87 |
|
88 | self.scopes.map(function(scope) {
|
89 | scopes.push(googleScopes[scope][1]);
|
90 | });
|
91 |
|
92 | var getParams = {
|
93 | client_id: googleConfig.clientId,
|
94 | redirect_uri: googleConfig.callbackUrl,
|
95 | response_type: 'code',
|
96 | state: 'profile'
|
97 | };
|
98 |
|
99 | var redirectUrl = this.oa.getAuthorizeUrl(getParams)+'&scope='+scopes.join('+');
|
100 |
|
101 | self.completed(redirectUrl);
|
102 |
|
103 | },
|
104 |
|
105 | callback: function() {
|
106 |
|
107 | var self = this,
|
108 | req = self.req,
|
109 | query = req.url.query;
|
110 |
|
111 | req.user = {
|
112 | tokens : {}
|
113 | };
|
114 |
|
115 | if (query.error || !query.code) {
|
116 | self.failed (query.error_description || "token was not accepted");
|
117 | }
|
118 |
|
119 | this.oa.getOAuthAccessToken(
|
120 | query.code,
|
121 | {
|
122 | redirect_uri: googleConfig.callbackUrl,
|
123 | grant_type: 'authorization_code'
|
124 | },
|
125 | function( error, access_token, refresh_token ){
|
126 |
|
127 | if (error) {
|
128 |
|
129 | self.failed(error);
|
130 |
|
131 | } else {
|
132 |
|
133 | req.user.tokens.oauth_access_token = access_token;
|
134 | if (refresh_token) req.user.tokens.oauth_refresh_token = refresh_token;
|
135 |
|
136 | var redirectUrl = (query.action && query.action != "") ? query.action : "/";
|
137 | self.completed (redirectUrl)
|
138 |
|
139 | }
|
140 | });
|
141 | },
|
142 |
|
143 | profile: function() {
|
144 | var self = this;
|
145 | var req = self.req;
|
146 | var tokens = req.user.tokens;
|
147 |
|
148 | this.oa.getProtectedResource(
|
149 | googleConfig.apiUrl+"/userinfo/v2/me",
|
150 | tokens.oauth_access_token,
|
151 | function (error, data, response) {
|
152 |
|
153 | if (error) {
|
154 | self.failed(error);
|
155 | } else {
|
156 | try {
|
157 | var user = JSON.parse(data);
|
158 | self.completed(self.mappingUser(user));
|
159 | } catch (e) {
|
160 | self.failed(e);
|
161 | }
|
162 | }
|
163 | });
|
164 | },
|
165 |
|
166 | mappingUser: function(user) {
|
167 |
|
168 | return {
|
169 | name: user.name,
|
170 | email: user.email,
|
171 | externalId: user.id,
|
172 | avatar: user.picture,
|
173 | link: user.link,
|
174 | authType: 'google'
|
175 | };
|
176 |
|
177 | }
|
178 | });
|