コード例 #1
0
        private static async Task <Dictionary <string, string> > PrepareAccessTokensAsync(ProvisioningActionModel model)
        {
            // Prepare the variable to hold the result
            var accessTokens = new Dictionary <string, string>();

            // Retrieve the Microsoft Graph Access Token
            var graphAccessToken = await ProvisioningAppManager.AccessTokenProvider.GetAccessTokenAsync(
                AuthenticationConfig.GetGraphScopes());

            // Retrieve the SPO Access Token
            var spoAccessToken = await ProvisioningAppManager.AccessTokenProvider.GetAccessTokenAsync(
                AuthenticationConfig.ClientId,
                AuthenticationConfig.ClientSecret,
                AuthenticationConfig.RedirectUri,
                AuthenticationConfig.GetSpoScopes(model.SPORootSiteUrl));

            // Retrieve the SPO URL for the Admin Site
            var adminSiteUrl = model.SPORootSiteUrl.Replace(".sharepoint.com", "-admin.sharepoint.com");

            // Retrieve the SPO Access Token
            var spoAdminAccessToken = await ProvisioningAppManager.AccessTokenProvider.GetAccessTokenAsync(
                AuthenticationConfig.ClientId,
                AuthenticationConfig.ClientSecret,
                AuthenticationConfig.RedirectUri,
                AuthenticationConfig.GetSpoScopes(adminSiteUrl));

            // Configure the resulting dictionary
            accessTokens.Add(new Uri(AuthenticationConfig.GraphBaseUrl).Authority, graphAccessToken);
            accessTokens.Add(new Uri(model.SPORootSiteUrl).Authority, spoAccessToken);
            accessTokens.Add(new Uri(adminSiteUrl).Authority, spoAdminAccessToken);

            return(accessTokens);
        }
コード例 #2
0
        private async Task <CanProvisionResult> CanProvisionInternal(CanProvisionModel model)
        {
            var canProvisionResult = new CanProvisionResult();

            String provisioningScope       = ConfigurationManager.AppSettings["SPPA:ProvisioningScope"];
            String provisioningEnvironment = ConfigurationManager.AppSettings["SPPA:ProvisioningEnvironment"];

            var graphAccessToken =
                model.AccessTokens != null && model.AccessTokens.ContainsKey("graph.microsoft.com") ?
                model.AccessTokens["graph.microsoft.com"] : null;

            if (graphAccessToken == null)
            {
                throw new ApplicationException("Invalid request, the request should contain a valid access token!");
            }

            // Retrieve the provisioning package from the database and from the Blob Storage
            var context = dbContext;

            DomainModel.Package package = null;

            // Get the package
            if (ProvisioningAppManager.IsTestingEnvironment)
            {
                // Process all packages in the test environment
                package = context.Packages.FirstOrDefault(p => p.Id == new Guid(model.PackageId));
            }
            else
            {
                // Process not-preview packages in the production environment
                package = context.Packages.FirstOrDefault(p => p.Id == new Guid(model.PackageId) && p.Preview == false);
            }

            if (package != null)
            {
                // Retrieve parameters from the package/template definition
                var packageFileUrl     = new Uri(package.PackageUrl);
                var packageLocalFolder = packageFileUrl.AbsolutePath.Substring(1,
                                                                               packageFileUrl.AbsolutePath.LastIndexOf('/') - 1);
                var packageFileName = packageFileUrl.AbsolutePath.Substring(packageLocalFolder.Length + 2);

                ProvisioningHierarchy hierarchy = GetHierarchyFromStorage(packageLocalFolder, packageFileName);

                // If we have the hierarchy
                if (hierarchy != null)
                {
                    var accessTokens = new Dictionary <String, String>();

                    AuthenticationManager authManager = new AuthenticationManager();
                    var ptai = new ProvisioningTemplateApplyingInformation();

                    // Retrieve the SPO URL for the Admin Site
                    var rootSiteUrl = model.SPORootSiteUrl;

                    // Retrieve the SPO Access Token for SPO
                    var spoAuthority = new Uri(rootSiteUrl).Authority;

                    var spoAccessToken =
                        model.AccessTokens != null && model.AccessTokens.ContainsKey(spoAuthority) ?
                        model.AccessTokens[spoAuthority] : null;

                    if (string.IsNullOrEmpty(spoAccessToken))
                    {
                        throw new ApplicationException($"Invalid request, the requested is missing a valid access token for {spoAuthority}!");
                    }

                    // Store the SPO Access Token for any further context cloning
                    accessTokens.Add(spoAuthority, spoAccessToken);

                    // Define a PnPProvisioningContext scope to share the security context across calls
                    using (var pnpProvisioningContext = new PnPProvisioningContext(async(r, s) =>
                    {
                        if (accessTokens.ContainsKey(r))
                        {
                            // In this scenario we just use the dictionary of access tokens
                            // in fact the overall operation for sure will take less than 1 hour
                            // (in fact, it's a matter of few seconds)
                            return(await Task.FromResult(accessTokens[r]));
                        }
                        else
                        {
                            var resourceUri = $"https://{r}";

                            // Try to get a fresh new Access Token
                            var token = await ProvisioningAppManager.AccessTokenProvider.GetAccessTokenAsync(
                                AuthenticationConfig.ClientId,
                                AuthenticationConfig.ClientSecret,
                                AuthenticationConfig.RedirectUri,
                                resourceUri.Equals(AuthenticationConfig.GraphBaseUrl, StringComparison.InvariantCultureIgnoreCase) ?
                                AuthenticationConfig.GetGraphScopes() :
                                AuthenticationConfig.GetSpoScopes(resourceUri));

                            accessTokens.Add(r, token);

                            return(token);
                        }
                    }))
                    {
                        // If the user is an admin (SPO or Tenant) we run the Tenant level CanProvision rules
                        if (model.UserIsSPOAdmin || model.UserIsTenantAdmin)
                        {
                            // Retrieve the SPO URL for the Admin Site
                            var adminSiteUrl       = model.SPORootSiteUrl.Replace(".sharepoint.com", "-admin.sharepoint.com");
                            var adminSiteAuthority = new Uri(adminSiteUrl).Authority;

                            // Retrieve the SPO Access Token for the Admin Site
                            var spoAdminAccessToken =
                                model.AccessTokens != null && model.AccessTokens.ContainsKey(adminSiteAuthority) ?
                                model.AccessTokens[adminSiteAuthority] :
                                await ProvisioningAppManager.AccessTokenProvider.GetAccessTokenAsync(
                                    AuthenticationConfig.ClientId,
                                    AuthenticationConfig.ClientSecret,
                                    AuthenticationConfig.RedirectUri,
                                    AuthenticationConfig.GetSpoScopes(adminSiteUrl));

                            // Store the SPO Admin Access Token for any further context cloning
                            accessTokens.Add(adminSiteAuthority, spoAdminAccessToken);

                            // Connect to SPO Admin Site and evaluate the CanProvision rules for the hierarchy
                            using (var tenantContext = authManager.GetAccessTokenContext(adminSiteUrl, spoAdminAccessToken))
                            {
                                using (var pnpTenantContext = PnPClientContext.ConvertFrom(tenantContext))
                                {
                                    // Creat the Tenant object for the current SPO Admin Site context
                                    TenantAdmin.Tenant tenant = new TenantAdmin.Tenant(pnpTenantContext);

                                    // Run the CanProvision rules against the current tenant
                                    canProvisionResult = CanProvisionRulesManager.CanProvision(tenant, hierarchy, null, ptai);
                                }
                            }
                        }
                        else
                        {
                            // Otherwise we run the Site level CanProvision rules

                            // Connect to SPO Root Site and evaluate the CanProvision rules for the hierarchy
                            using (var clientContext = authManager.GetAccessTokenContext(rootSiteUrl, spoAccessToken))
                            {
                                using (var pnpContext = PnPClientContext.ConvertFrom(clientContext))
                                {
                                    // Run the CanProvision rules against the root site
                                    canProvisionResult = CanProvisionRulesManager.CanProvision(pnpContext.Web, hierarchy.Templates[0], ptai);
                                }
                            }
                        }
                    }
                }
            }
            else
            {
                throw new ApplicationException("Invalid request, the requested package/template is not available!");
            }

            return(canProvisionResult);
        }