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