1 | var path = require('path');
|
2 | var fs = require('fs');
|
3 | var http = require('http');
|
4 |
|
5 | exports = module.exports = function()
|
6 | {
|
7 | var r = {};
|
8 |
|
9 | /**
|
10 | * Helper method that can be called for a given request ahead of any processing. This method checks to see whether
|
11 | * a Gitana driver is mounted onto the request. If so and if the request is for an OAuth2 token exchange and it
|
12 | * lacks client key + secret information, then this method injects the correct OAuth2 client bearer authorization
|
13 | * header into the request.
|
14 | *
|
15 | * This allows the OAuth2 token request to proceed and work as intended.
|
16 | *
|
17 | * The reason this exists is to support pure HTML5/JavaScript applications that run entirely in the browser.
|
18 | * Since the browser is not secure, we allow for those applications to use the Gitana driver *without* providing
|
19 | * the clientKey and clientSecret.
|
20 | *
|
21 | * The clientKey and clientSecret are mandatory and required for connection to the Cloud CMS server. If the
|
22 | * connection were direct from the browser to the Cloud CMS server, there would be not exceptions to this rule.
|
23 | *
|
24 | * However, to support the browser application, a Cloud CMS customer may deploy an "application server" which
|
25 | * consists of this Node.js application. The application server is wired via the gitana.json file to a single
|
26 | * application and client key/secret. The browser is allowed to communicate openly and publicly with the
|
27 | * application server. Any calls to the application server are already understood to originate from the clientKey
|
28 | * and clientSecret for the application server (in so far as Cloud CMS is concerned).
|
29 | *
|
30 | * Thus, the browser does not need to have the client key and secret made available to it. The customer is free
|
31 | * to deploy new client keys and secrets to the application server at any time. The browser makes calls to the
|
32 | * application server, the application server then plugs in the appropriate client key/secret via this method,
|
33 | * and the browser never gets to discover the client key/secret pair.
|
34 | *
|
35 | * @return {Function}
|
36 | */
|
37 | r.autoProxy = function(req)
|
38 | {
|
39 | if (req.gitanaConfig)
|
40 | {
|
41 | //if (req.method.toLowerCase() === "get" || req.method.toLowerCase() === "post")
|
42 | //{
|
43 | if (req.url.indexOf("/oauth/token") === 0)
|
44 | {
|
45 | autoClientBearer(req);
|
46 | }
|
47 | /*
|
48 | else if (req.url.indexOf("/oauth/authorize") == 0)
|
49 | {
|
50 | console.log("PROXY OAUTH2 AUTHORIZE");
|
51 | autoClientBearer(req);
|
52 | }
|
53 | */
|
54 | //}
|
55 | }
|
56 | };
|
57 |
|
58 | var autoClientBearer = function(req)
|
59 | {
|
60 | var validAuthorizationHeader = false;
|
61 | var authorizationHeaderName = null;
|
62 |
|
63 | if (req.headers)
|
64 | {
|
65 | for (var k in req.headers)
|
66 | {
|
67 | if (k.toLowerCase() == "authorization")
|
68 | {
|
69 | authorizationHeaderName = k;
|
70 | break;
|
71 | }
|
72 | }
|
73 |
|
74 | if (authorizationHeaderName)
|
75 | {
|
76 | var authorizationHeader = req.headers[authorizationHeaderName];
|
77 | if (authorizationHeader)
|
78 | {
|
79 | var z = authorizationHeader.indexOf("Basic ");
|
80 | if (z === 0)
|
81 | {
|
82 | var byte64string = authorizationHeader.substring(6);
|
83 | var clientKeySecret = new Buffer(byte64string, 'base64').toString('ascii');
|
84 | if (clientKeySecret)
|
85 | {
|
86 | z = clientKeySecret.indexOf(":");
|
87 | if (z > -1)
|
88 | {
|
89 | var clientKey = clientKeySecret.substring(0, z);
|
90 | var clientSecret = clientKeySecret.substring(z+1);
|
91 | if (clientKey && clientKey.length > 0)
|
92 | {
|
93 | if (clientSecret && clientSecret.length > 0)
|
94 | {
|
95 | validAuthorizationHeader = true;
|
96 | }
|
97 | }
|
98 | }
|
99 | }
|
100 | }
|
101 | }
|
102 | }
|
103 | }
|
104 |
|
105 | if (validAuthorizationHeader)
|
106 | {
|
107 | // we get out of the way
|
108 | return;
|
109 | }
|
110 |
|
111 | // if no gitanaConfig, don't do this
|
112 | if (!req.gitanaConfig)
|
113 | {
|
114 | return;
|
115 | }
|
116 |
|
117 | // only do this if we have gitanaConfig client key/secret
|
118 | if (req.gitanaConfig.clientKey && req.gitanaConfig.clientSecret)
|
119 | {
|
120 | // process by hand so that we can inject the client key/secret
|
121 |
|
122 | var clientKeySecret = req.gitanaConfig.clientKey + ":" + req.gitanaConfig.clientSecret;
|
123 |
|
124 | var clientAuthorizationHeader = "Basic " + new Buffer(clientKeySecret).toString('base64');
|
125 |
|
126 | if (!req.headers)
|
127 | {
|
128 | req.headers = {};
|
129 | }
|
130 |
|
131 | req.headers[authorizationHeaderName] = clientAuthorizationHeader;
|
132 | }
|
133 | };
|
134 |
|
135 | return r;
|
136 | };
|
137 |
|