c4e144fa298662c2cc44a25e52ae21b859de72ef
[msb/apigateway.git] / msb-core / apiroute / apiroute-service / src / main / resources / api-doc / lib / swagger-oauth.js
1 var appName;
2 var popupMask;
3 var popupDialog;
4 var clientId;
5 var realm;
6 var oauth2KeyName;
7 var redirect_uri;
8
9 function handleLogin() {
10   var scopes = [];
11
12   var auths = window.swaggerUi.api.authSchemes || window.swaggerUi.api.securityDefinitions;
13   if(auths) {
14     var key;
15     var defs = auths;
16     for(key in defs) {
17       var auth = defs[key];
18       if(auth.type === 'oauth2' && auth.scopes) {
19         oauth2KeyName = key;
20         var scope;
21         if(Array.isArray(auth.scopes)) {
22           // 1.2 support
23           var i;
24           for(i = 0; i < auth.scopes.length; i++) {
25             scopes.push(auth.scopes[i]);
26           }
27         }
28         else {
29           // 2.0 support
30           for(scope in auth.scopes) {
31             scopes.push({scope: scope, description: auth.scopes[scope]});
32           }
33         }
34       }
35     }
36   }
37
38   if(window.swaggerUi.api
39     && window.swaggerUi.api.info) {
40     appName = window.swaggerUi.api.info.title;
41   }
42
43   popupDialog = $(
44     [
45       '<div class="api-popup-dialog">',
46       '<div class="api-popup-title">Select OAuth2.0 Scopes</div>',
47       '<div class="api-popup-content">',
48         '<p>Scopes are used to grant an application different levels of access to data on behalf of the end user. Each API may declare one or more scopes.',
49           '<a href="#">Learn how to use</a>',
50         '</p>',
51         '<p><strong>' + appName + '</strong> API requires the following scopes. Select which ones you want to grant to Swagger UI.</p>',
52         '<ul class="api-popup-scopes">',
53         '</ul>',
54         '<p class="error-msg"></p>',
55         '<div class="api-popup-actions"><button class="api-popup-authbtn api-button green" type="button">Authorize</button><button class="api-popup-cancel api-button gray" type="button">Cancel</button></div>',
56       '</div>',
57       '</div>'].join(''));
58   $(document.body).append(popupDialog);
59
60   popup = popupDialog.find('ul.api-popup-scopes').empty();
61   for (i = 0; i < scopes.length; i ++) {
62     scope = scopes[i];
63     str = '<li><input type="checkbox" id="scope_' + i + '" scope="' + scope.scope + '"/>' + '<label for="scope_' + i + '">' + scope.scope;
64     if (scope.description) {
65       str += '<br/><span class="api-scope-desc">' + scope.description + '</span>';
66     }
67     str += '</label></li>';
68     popup.append(str);
69   }
70
71   var $win = $(window),
72     dw = $win.width(),
73     dh = $win.height(),
74     st = $win.scrollTop(),
75     dlgWd = popupDialog.outerWidth(),
76     dlgHt = popupDialog.outerHeight(),
77     top = (dh -dlgHt)/2 + st,
78     left = (dw - dlgWd)/2;
79
80   popupDialog.css({
81     top: (top < 0? 0 : top) + 'px',
82     left: (left < 0? 0 : left) + 'px'
83   });
84
85   popupDialog.find('button.api-popup-cancel').click(function() {
86     popupMask.hide();
87     popupDialog.hide();
88     popupDialog.empty();
89     popupDialog = [];
90   });
91
92   $('button.api-popup-authbtn').unbind();
93   popupDialog.find('button.api-popup-authbtn').click(function() {
94     popupMask.hide();
95     popupDialog.hide();
96
97     var authSchemes = window.swaggerUi.api.authSchemes;
98     var host = window.location;
99     var pathname = location.pathname.substring(0, location.pathname.lastIndexOf("/"));
100     var redirectUrl = host.protocol + '//' + host.host + pathname + '/o2c.html';
101     var url = null;
102
103     for (var key in authSchemes) {
104       if (authSchemes.hasOwnProperty(key)) {
105         var flow = authSchemes[key].flow;
106         
107         if(authSchemes[key].type === 'oauth2' && flow && (flow === 'implicit' || flow === 'accessCode')) {
108           var dets = authSchemes[key];
109           url = dets.authorizationUrl + '?response_type=' + (flow === 'implicit' ? 'token' : 'code');
110           window.swaggerUi.tokenName = dets.tokenName || 'access_token';
111           window.swaggerUi.tokenUrl = (flow === 'accessCode' ? dets.tokenUrl : null);          
112         }
113         else if(authSchemes[key].grantTypes) {
114           // 1.2 support
115           var o = authSchemes[key].grantTypes;
116           for(var t in o) {
117             if(o.hasOwnProperty(t) && t === 'implicit') {
118               var dets = o[t];
119               var ep = dets.loginEndpoint.url;
120               url = dets.loginEndpoint.url + '?response_type=token';
121               window.swaggerUi.tokenName = dets.tokenName;
122             }
123             else if (o.hasOwnProperty(t) && t === 'accessCode') {
124               var dets = o[t];
125               var ep = dets.tokenRequestEndpoint.url;
126               url = dets.tokenRequestEndpoint.url + '?response_type=code';
127               window.swaggerUi.tokenName = dets.tokenName;
128             }
129           }
130         }
131       }
132     }
133     var scopes = []
134     var o = $('.api-popup-scopes').find('input:checked');
135
136     for(k =0; k < o.length; k++) {
137       var scope = $(o[k]).attr('scope');
138       
139       if (scopes.indexOf(scope) === -1)
140         scopes.push(scope);
141     }
142
143     window.enabledScopes=scopes;
144
145     redirect_uri = redirectUrl;
146
147     url += '&redirect_uri=' + encodeURIComponent(redirectUrl);
148     url += '&realm=' + encodeURIComponent(realm);
149     url += '&client_id=' + encodeURIComponent(clientId);
150     url += '&scope=' + encodeURIComponent(scopes);
151
152     window.open(url);
153   });
154
155   popupMask.show();
156   popupDialog.show();
157   return;
158 }
159
160
161 function handleLogout() {
162   for(key in window.authorizations.authz){
163     window.authorizations.remove(key)
164   }
165   window.enabledScopes = null;
166   $('.api-ic.ic-on').addClass('ic-off');
167   $('.api-ic.ic-on').removeClass('ic-on');
168
169   // set the info box
170   $('.api-ic.ic-warning').addClass('ic-error');
171   $('.api-ic.ic-warning').removeClass('ic-warning');
172 }
173
174 function initOAuth(opts) {
175   var o = (opts||{});
176   var errors = [];
177
178   appName = (o.appName||errors.push('missing appName'));
179   popupMask = (o.popupMask||$('#api-common-mask'));
180   popupDialog = (o.popupDialog||$('.api-popup-dialog'));
181   clientId = (o.clientId||errors.push('missing client id'));
182   realm = (o.realm||errors.push('missing realm'));
183
184   if(errors.length > 0){
185     log('auth unable initialize oauth: ' + errors);
186     return;
187   }
188
189   $('pre code').each(function(i, e) {hljs.highlightBlock(e)});
190   $('.api-ic').unbind();
191   $('.api-ic').click(function(s) {
192     if($(s.target).hasClass('ic-off'))
193       handleLogin();
194     else {
195       handleLogout();
196     }
197     false;
198   });
199 }
200
201 function processOAuthCode(data) {
202   var params = {
203     'client_id': clientId,
204     'code': data.code,
205     'grant_type': 'authorization_code',
206     'redirect_uri': redirect_uri
207   }
208   $.ajax(
209   {
210     url : window.swaggerUi.tokenUrl,
211     type: "POST",
212     data: params,
213     success:function(data, textStatus, jqXHR) 
214     {
215       onOAuthComplete(data);
216     },
217     error: function(jqXHR, textStatus, errorThrown) 
218     {
219       onOAuthComplete("");
220     }
221   });
222 }
223
224 function onOAuthComplete(token) {
225   if(token) {
226     if(token.error) {
227       var checkbox = $('input[type=checkbox],.secured')
228       checkbox.each(function(pos){
229         checkbox[pos].checked = false;
230       });
231       alert(token.error);
232     }
233     else {
234       var b = token[window.swaggerUi.tokenName];
235       if(b){
236         // if all roles are satisfied
237         var o = null;
238         $.each($('.auth #api_information_panel'), function(k, v) {
239           var children = v;
240           if(children && children.childNodes) {
241             var requiredScopes = [];
242             $.each((children.childNodes), function (k1, v1){
243               var inner = v1.innerHTML;
244               if(inner)
245                 requiredScopes.push(inner);
246             });
247             var diff = [];
248             for(var i=0; i < requiredScopes.length; i++) {
249               var s = requiredScopes[i];
250               if(window.enabledScopes && window.enabledScopes.indexOf(s) == -1) {
251                 diff.push(s);
252               }
253             }
254             if(diff.length > 0){
255               o = v.parentNode;
256               $(o.parentNode).find('.api-ic.ic-on').addClass('ic-off');
257               $(o.parentNode).find('.api-ic.ic-on').removeClass('ic-on');
258
259               // sorry, not all scopes are satisfied
260               $(o).find('.api-ic').addClass('ic-warning');
261               $(o).find('.api-ic').removeClass('ic-error');
262             }
263             else {
264               o = v.parentNode;
265               $(o.parentNode).find('.api-ic.ic-off').addClass('ic-on');
266               $(o.parentNode).find('.api-ic.ic-off').removeClass('ic-off');
267
268               // all scopes are satisfied
269               $(o).find('.api-ic').addClass('ic-info');
270               $(o).find('.api-ic').removeClass('ic-warning');
271               $(o).find('.api-ic').removeClass('ic-error');          
272             }
273           }
274         });
275         window.authorizations.add(oauth2KeyName, new ApiKeyAuthorization('Authorization', 'Bearer ' + b, 'header'));
276       }
277     }
278   }
279 }