WIP authorizationDecision
This commit is contained in:
		
							parent
							
								
									23ea5046bb
								
							
						
					
					
						commit
						9f923b5f65
					
				| @ -228,6 +228,201 @@ | |||||||
|         }); |         }); | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|  |   , isIframe: function isIframe () { | ||||||
|  |       try { | ||||||
|  |         return window.self !== window.top; | ||||||
|  |       } catch (e) { | ||||||
|  |         return true; | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   , parseUrl: function (url) { | ||||||
|  |       var parser = document.createElement('a'); | ||||||
|  |       parser.href = url; | ||||||
|  |       return parser; | ||||||
|  |     } | ||||||
|  |   , isRedirectHostSafe: function (referrerUrl, redirectUrl) { | ||||||
|  |       var src = browser.parseUrl(referrerUrl); | ||||||
|  |       var dst = browser.parseUrl(redirectUrl); | ||||||
|  | 
 | ||||||
|  |       // TODO how should we handle subdomains?
 | ||||||
|  |       // It should be safe for api.example.com to redirect to example.com
 | ||||||
|  |       // But it may not be safe for to example.com to redirect to aj.example.com
 | ||||||
|  |       // It is also probably not safe for sally.example.com to redirect to john.example.com
 | ||||||
|  |       // The client should have a list of allowed URLs to choose from and perhaps a wildcard will do
 | ||||||
|  |       //
 | ||||||
|  |       // api.example.com.evil.com SHOULD NOT match example.com
 | ||||||
|  |       return dst.hostname !== src.hostname; | ||||||
|  |     } | ||||||
|  |   , checkRedirect: function (client, query) { | ||||||
|  |       console.warn("[security] URL path checking not yet implemented"); | ||||||
|  | 
 | ||||||
|  |       var clientUrl = OAUTH3.core.normalizeUrl(client.url); | ||||||
|  |       var redirectUrl = OAUTH3.core.normalizeUrl(query.redirect_uri); | ||||||
|  | 
 | ||||||
|  |       // General rule:
 | ||||||
|  |       // I can callback to a shorter domain (fewer subs) or a shorter path (on the same domain)
 | ||||||
|  |       // but not a longer (more subs) or different domain or a longer path (on the same domain)
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |       // We can callback to an explicitly listed domain (TODO and path)
 | ||||||
|  |       if (browser.isRedirectHostSafe(clientUrl, redirectUrl)) { | ||||||
|  |         return true; | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       return false; | ||||||
|  |     } | ||||||
|  |   /* | ||||||
|  |   , redirect: function (redirect) { | ||||||
|  |       if (parser.search) { | ||||||
|  |         parser.search += '&'; | ||||||
|  |       } else { | ||||||
|  |         parser.search += '?'; | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       parser.search += 'error=E_NO_SESSION'; | ||||||
|  |       redirectUri = parser.href; | ||||||
|  | 
 | ||||||
|  |       window.location.href = redirectUri; | ||||||
|  |     } | ||||||
|  |   */ | ||||||
|  | 
 | ||||||
|  |   , hackFormSubmit: function (opts) { | ||||||
|  |       opts = opts || {}; | ||||||
|  |       scope.authorizationDecisionUri = DaplieApiConfig.providerUri + '/api/org.oauth3.provider/authorization_decision'; | ||||||
|  |       scope.updateScope(); | ||||||
|  | 
 | ||||||
|  |       var redirectUri = scope.appQuery.redirect_uri.replace(/^https?:\/\//i, 'https://'); | ||||||
|  |       var separator; | ||||||
|  | 
 | ||||||
|  |       // TODO check that we appropriately use '#' for implicit and '?' for code
 | ||||||
|  |       // (server-side) in an OAuth2 backwards-compatible way
 | ||||||
|  |       if ('token' === scope.appQuery.response_type) { | ||||||
|  |         separator = '#'; | ||||||
|  |       } | ||||||
|  |       else if ('code' === scope.appQuery.response_type) { | ||||||
|  |         separator = '?'; | ||||||
|  |       } | ||||||
|  |       else { | ||||||
|  |         separator = '#'; | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       if (scope.pendingScope.length && !opts.allow) { | ||||||
|  |         redirectUri += separator + Oauth3.querystringify({ | ||||||
|  |           error: 'access_denied' | ||||||
|  |           , error_description: 'None of the permissions were accepted' | ||||||
|  |           , error_uri: 'https://oauth3.org/docs/errors#access_denied' | ||||||
|  |           , state: scope.appQuery.state | ||||||
|  |         }); | ||||||
|  |         $window.location.href = redirectUri; | ||||||
|  |         return; | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       // TODO move to Oauth3? or not?
 | ||||||
|  |       // this could be implementation-specific,
 | ||||||
|  |       // but it may still be nice to provide it as de-facto
 | ||||||
|  |       var url = DaplieApiConfig.apiBaseUri + '/api/org.oauth3.provider/grants/:client_id/:account_id' | ||||||
|  |         .replace(/:client_id/g, scope.appQuery.client_id || scope.appQuery.client_uri) | ||||||
|  |         .replace(/:account_id/g, scope.selectedAccountId) | ||||||
|  |         ; | ||||||
|  | 
 | ||||||
|  |       var account = scope.sessionAccount; | ||||||
|  |       var session = { accessToken: account.token, refreshToken: account.refreshToken }; | ||||||
|  |       var preq = { | ||||||
|  |         url: url | ||||||
|  |       , method: 'POST' | ||||||
|  |       , data: { | ||||||
|  |           scope: updateAccepted() | ||||||
|  |         , response_type: scope.appQuery.response_type | ||||||
|  |         , referrer: document.referrer || document.referer || '' | ||||||
|  |         , referer: document.referrer || document.referer || '' | ||||||
|  |         , tenant_id: scope.appQuery.tenant_id | ||||||
|  |         , client_id: scope.appQuery.client_id | ||||||
|  |         , client_uri: scope.appQuery.client_uri | ||||||
|  |         } | ||||||
|  |       , session: session | ||||||
|  |       }; | ||||||
|  |       preq.clientId = preq.appId = DaplieApiConfig.appId || DaplieApiConfig.clientId; | ||||||
|  |       preq.clientUri = preq.appUri = DaplieApiConfig.appUri || DaplieApiConfig.clientUri; | ||||||
|  |       console.log('hackFormSubmit preq', preq); | ||||||
|  |       // TODO need a way to have middleware in Oauth3.request for TherapySession et al
 | ||||||
|  |       return Oauth3.request(preq).then(function (resp) { | ||||||
|  |         console.log('[DEBUG] grant code'); | ||||||
|  |         console.log(resp); | ||||||
|  | 
 | ||||||
|  |         var err; | ||||||
|  |         var data = resp.data || {}; | ||||||
|  | 
 | ||||||
|  |         if (data.error) { | ||||||
|  |           err = new Error(data.error.message || data.errorDescription); | ||||||
|  |           err.message = data.error.message || data.errorDescription; | ||||||
|  |           err.code = resp.data.error.code || resp.data.error; | ||||||
|  |           err.uri = 'https://oauth3.org/docs/errors#' + (resp.data.error.code || resp.data.error); | ||||||
|  |           return $q.reject(err); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         if (!(data.code || data.accessToken)) { | ||||||
|  |           err = new Error("No grant code"); | ||||||
|  |           return $q.reject(err); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         return data; | ||||||
|  |       }).then(function (data) { | ||||||
|  |         redirectUri += separator + Oauth3.querystringify({ | ||||||
|  |           state: scope.appQuery.state | ||||||
|  | 
 | ||||||
|  |         , code: data.code | ||||||
|  | 
 | ||||||
|  |         , access_token: data.accessToken | ||||||
|  |         , expires_at: data.expiresAt | ||||||
|  |         , expires_in: data.expiresIn | ||||||
|  |         , scope: data.scope | ||||||
|  | 
 | ||||||
|  |         , refresh_token: data.refreshToken | ||||||
|  |         , refresh_expires_at: data.refreshExpiresAt | ||||||
|  |         , refresh_expires_in: data.refreshExpiresIn | ||||||
|  |         }); | ||||||
|  | 
 | ||||||
|  |         if ('token' === scope.appQuery.response_type) { | ||||||
|  |           $window.location.href = redirectUri; | ||||||
|  |           return; | ||||||
|  |         } | ||||||
|  |         else if ('code' === scope.appQuery.response_type) { | ||||||
|  |           scope.hackFormSubmitHelper(redirectUri); | ||||||
|  |           return; | ||||||
|  |         } | ||||||
|  |         else { | ||||||
|  |           console.warn("Grant Code NOT IMPLEMENTED for '" + scope.appQuery.response_type + "'"); | ||||||
|  |           console.warn(redirectUri); | ||||||
|  |           throw new Error("Grant Code NOT IMPLEMENTED for '" + scope.appQuery.response_type + "'"); | ||||||
|  |         } | ||||||
|  |       }, function (err) { | ||||||
|  |         redirectUri += separator + Oauth3.querystringify({ | ||||||
|  |           error: err.code || 'server_error' | ||||||
|  |         , error_description: err.message || "Server Error: It's not your fault" | ||||||
|  |         , error_uri: err.uri || 'https://oauth3.org/docs/errors#server_error' | ||||||
|  |         , state: scope.appQuery.state | ||||||
|  |         }); | ||||||
|  | 
 | ||||||
|  |         console.error('Grant Code Error NOT IMPLEMENTED'); | ||||||
|  |         console.error(err); | ||||||
|  |         console.error(redirectUri); | ||||||
|  |         //$window.location.href = redirectUri;
 | ||||||
|  |       }); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |   , hackFormSubmitHelper: function (uri) { | ||||||
|  |       // TODO de-jQuerify
 | ||||||
|  |       //$window.location.href = redirectUri;
 | ||||||
|  |       //return;
 | ||||||
|  | 
 | ||||||
|  |       // the only way to do a POST that redirects the current window
 | ||||||
|  |       window.jQuery('form.js-hack-hidden-form').attr('action', uri); | ||||||
|  | 
 | ||||||
|  |       // give time for the apply to take place
 | ||||||
|  |       window.setTimeout(function () { | ||||||
|  |         window.jQuery('form.js-hack-hidden-form').submit(); | ||||||
|  |       }, 50); | ||||||
|  |     } | ||||||
|   }; |   }; | ||||||
| 
 | 
 | ||||||
|   Object.keys(browser).forEach(function (key) { |   Object.keys(browser).forEach(function (key) { | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user