Example #1
0
        public virtual void OnAuthorization(AuthorizationContext filterContext)
        {
            if (filterContext == null)
            {
                throw new ArgumentNullException("filterContext");
            }

            IEnumerable <FacebookAuthorizeAttribute> authorizeAttributes = filterContext.ActionDescriptor
                                                                           .GetCustomAttributes(typeof(FacebookAuthorizeAttribute), inherit: true)
                                                                           .Union(filterContext.ActionDescriptor.ControllerDescriptor
                                                                                  .GetCustomAttributes(typeof(FacebookAuthorizeAttribute), inherit: true))
                                                                           .OfType <FacebookAuthorizeAttribute>();

            if (!authorizeAttributes.Any())
            {
                return;
            }

            FacebookClient  client        = _config.ClientProvider.CreateClient();
            HttpRequestBase request       = filterContext.HttpContext.Request;
            dynamic         signedRequest = FacebookRequestHelpers.GetSignedRequest(
                filterContext.HttpContext,
                rawSignedRequest =>
            {
                return(client.ParseSignedRequest(rawSignedRequest));
            });
            string userId      = null;
            string accessToken = null;

            if (signedRequest != null)
            {
                userId      = signedRequest.user_id;
                accessToken = signedRequest.oauth_token;
            }

            NameValueCollection parsedQueries       = HttpUtility.ParseQueryString(request.Url.Query);
            HashSet <string>    requiredPermissions = PermissionHelper.GetRequiredPermissions(authorizeAttributes);

            bool handleError = !String.IsNullOrEmpty(parsedQueries["error"]);

            // This must occur AFTER the handleError calculation because it modifies the parsed queries.
            string redirectUrl = GetRedirectUrl(request, parsedQueries);

            // Check if there was an error and we should handle it.
            if (handleError)
            {
                Uri errorUrl;

                if (String.IsNullOrEmpty(_config.AuthorizationRedirectPath))
                {
                    errorUrl = DefaultAuthorizationRedirectUrl;
                }
                else
                {
                    errorUrl = GetErroredAuthorizeUri(redirectUrl, requiredPermissions);
                }

                filterContext.Result = CreateRedirectResult(errorUrl);

                // There was an error so short circuit
                return;
            }

            FacebookContext facebookContext = new FacebookContext
            {
                Client        = client,
                SignedRequest = signedRequest,
                AccessToken   = accessToken,
                UserId        = userId,
                Configuration = _config
            };

            PermissionContext permissionContext = new PermissionContext
            {
                FacebookContext     = facebookContext,
                FilterContext       = filterContext,
                RequiredPermissions = requiredPermissions,
            };

            // Check if we need to prompt for default permissions.
            if (signedRequest == null || String.IsNullOrEmpty(userId) || String.IsNullOrEmpty(accessToken))
            {
                PromptDefaultPermissions(permissionContext, redirectUrl);
            }
            else if (requiredPermissions.Any())
            {
                PermissionsStatus currentPermissionsStatus = _config.PermissionService.GetUserPermissionsStatus(userId, accessToken);
                // Instead of performing another request to gather "granted" permissions just parse the status
                IEnumerable <string> currentPermissions = PermissionHelper.GetGrantedPermissions(currentPermissionsStatus);
                IEnumerable <string> missingPermissions = requiredPermissions.Except(currentPermissions);

                // If we have missing permissions than we need to present a prompt or redirect to an error
                // page if there's an error.
                if (missingPermissions.Any())
                {
                    permissionContext.MissingPermissions  = missingPermissions;
                    permissionContext.DeclinedPermissions = PermissionHelper.GetDeclinedPermissions(currentPermissionsStatus);
                    permissionContext.SkippedPermissions  = PermissionHelper.GetSkippedPermissions(
                        filterContext.HttpContext.Request,
                        missingPermissions,
                        permissionContext.DeclinedPermissions);

                    // Add a query string parameter that enables us to identify if we've already prompted for missing permissions
                    // and therefore can detect cookies.
                    AddCookieVerificationQuery(parsedQueries);
                    // Rebuild the redirect Url so it contains the new query string parameter.
                    redirectUrl = GetRedirectUrl(request, parsedQueries);

                    PromptMissingPermissions(permissionContext, redirectUrl);
                }
            }
        }