public async Task <ActionResult> Index()
        {
            return(await SafeExecuteView(() =>
            {
                // Create the basic model for the view
                var newSp = new ServicePrincipalModel
                {
                    UserMessage = "Please submit your request!",
                    AppId = Guid.Empty.ToString(),
                    ShowSpDetails = true,
                    SubmitConsentEnabled = false,
                    SubmitSpEnabled = true
                };

                // If not all tokens are available, update the user action and update the user message
                if (AuthenticationConfig.SessionItems.GraphAuthToken == null || AuthenticationConfig.SessionItems.ManagementAuthToken == null)
                {
                    newSp.ShowSpDetails = false;
                    newSp.SubmitConsentEnabled = true;
                    newSp.SubmitSpEnabled = false;
                    newSp.UserMessage = "Please initate a consent with the button below as it looks we were unable to get access to management APIs right away! This might be possible because you need admin consent, consent expired or you used Microsoft Accounts (MSA) for signing in!";
                }
                else
                {
                    newSp.TenantId = AuthenticationConfig.SessionItems.GraphTargetTenant;
                }

                // Admin-Consent is enabled, only, if a target tenant is given
                newSp.SubmitAdminConsentEnabled = !string.IsNullOrEmpty(AuthenticationConfig.SessionItems.GraphTargetTenant);

                // Show the view witht he model
                return Task.FromResult <ActionResult>(View(newSp));
            }));
        }
        public ActionResult DeleteConfirmed(string tenantId, ServicePrincipalModel editedServicePrincipalList)
        {
            // Delete all rows for this servicePrincipal list, that is,
            // Subscriber rows as well as ServicePrincipal rows.
            // Therefore, no need to specify row key.
            var listRows       = ServicePrincipalModel.GetAllFromStorage(tenantId);
            var batchOperation = new TableBatchOperation();
            int itemsInBatch   = 0;

            foreach (DynamicTableEntity listRow in listRows)
            {
                batchOperation.Delete(listRow);
                itemsInBatch++;
                if (itemsInBatch == 100)
                {
                    StorageFactory.Instance.IpcAzureAppTenantStateTable.ExecuteBatch(batchOperation);
                    itemsInBatch   = 0;
                    batchOperation = new TableBatchOperation();
                }
            }
            if (itemsInBatch > 0)
            {
                StorageFactory.Instance.IpcAzureAppTenantStateTable.ExecuteBatch(batchOperation);
            }
            return(RedirectToAction("Index"));
        }
        public async Task <ActionResult> InitiateAdminConsent(ServicePrincipalModel principalModel)
        {
            return(await SafeExecuteView(async() =>
            {
                // Validate the basic input data
                if (string.IsNullOrEmpty(AuthenticationConfig.SessionItems.GraphTargetTenant))
                {
                    throw new Exception("Cannot initate Admin Consent without a default tenant known!");
                }
                else
                {
                    // Start the consent flow for the target tenant
                    var redirectUrl = string.Format("{0}{1}",
                                                    Request.Url.GetLeftPart(UriPartial.Authority),
                                                    Url.Action("CatchConsentResult"));
                    var authorizationUrl = await AuthenticationLogic.ConstructConsentUrlAsync
                                           (
                        AuthenticationConfig.SessionItems.GraphTargetTenant,
                        AuthenticationConfig.ConfiguratinItems.ManagementAppUri,
                        redirectUrl,
                        true
                                           );

                    return Redirect(authorizationUrl);
                }
            }));
        }
        public async Task <ActionResult> InitiateConsent(ServicePrincipalModel principalModel)
        {
            return(await SafeExecuteView(async() =>
            {
                // Validate the basic input data
                if (string.IsNullOrEmpty(principalModel.ConsentAzureAdTenantDomainOrId))
                {
                    ModelState.AddModelError("ConsentAzureAdTenantDomainOrId", "Please enter a Tenant ID (GUID) or a Tenant Domain (e.g. xyz.onmicrosoft.com) for initiaiting the consent!");
                }

                if (ModelState.IsValid)
                {
                    // Start the consent flow for the target tenant
                    var redirectUrl = string.Format("{0}{1}",
                                                    Request.Url.GetLeftPart(UriPartial.Authority),
                                                    Url.Action("CatchConsentResult"));
                    var authorizationUrl = await AuthenticationLogic.ConstructConsentUrlAsync
                                           (
                        principalModel.ConsentAzureAdTenantDomainOrId,
                        AuthenticationConfig.ConfiguratinItems.ManagementAppUri,
                        redirectUrl
                                           );

                    return Redirect(authorizationUrl);
                }
                else
                {
                    principalModel.SubmitConsentEnabled = true;
                    principalModel.SubmitSpEnabled = false;
                    principalModel.SubmitAdminConsentEnabled = false;
                    principalModel.UserMessage = "Please fix errors and try initiating the consent again!";
                    return View("Index", principalModel);
                }
            }));
        }
        public ActionResult Create(ServicePrincipalModel servicePrincipal)
        {
            if (ModelState.IsValid)
            {
                servicePrincipal.SaveToStorage();
                return(RedirectToAction("Index"));
            }

            return(View("Error"));
        }
 // GET: /ServicePrincipal/
 public ActionResult Index()
 {
     try
     {
         IEnumerable <ServicePrincipalModel> servicePrincipals = ServicePrincipalModel.GetAllFromStorage();
         return(View(servicePrincipals));
     }
     catch (StorageException se)
     {
         ViewBag.errorMessage = "Timeout error, try again. ";
         Trace.TraceError(se.Message);
         return(View("Error"));
     }
 }
 public ActionResult Edit(string tenantId, ServicePrincipalModel editedServicePrincipal)
 {
     if (ModelState.IsValid)
     {
         var servicePrincipal = new ServicePrincipalModel();
         UpdateModel(servicePrincipal);
         try
         {
             var replaceOperation = TableOperation.Replace(servicePrincipal);
             servicePrincipal.SaveToStorage();
             return(RedirectToAction("Index"));
         }
         catch (StorageException ex)
         {
             if (ex.RequestInformation.HttpStatusCode == 412)
             {
                 // Concurrency error
                 var currentServicePrincipal = ServicePrincipalModel.GetFromStorage(tenantId);
                 if (currentServicePrincipal.Key != editedServicePrincipal.Key)
                 {
                     ModelState.AddModelError("Key", "Current value: " + currentServicePrincipal.Key);
                 }
                 if (currentServicePrincipal.AppId != editedServicePrincipal.AppId)
                 {
                     ModelState.AddModelError("AppId", "Current value: " + currentServicePrincipal.AppId);
                 }
                 if (currentServicePrincipal.TenantId != editedServicePrincipal.TenantId)
                 {
                     ModelState.AddModelError("TenantId", "Current value: " + currentServicePrincipal.TenantId);
                 }
                 ModelState.AddModelError(string.Empty, "The record you attempted to edit "
                                          + "was modified by another user after you got the original value. The "
                                          + "edit operation was canceled and the current values in the database "
                                          + "have been displayed. If you still want to edit this record, click "
                                          + "the Save button again. Otherwise click the Back to List hyperlink.");
                 ModelState.SetModelValue("ETag", new ValueProviderResult(currentServicePrincipal.ETag, currentServicePrincipal.ETag, null));
             }
             else
             {
                 throw;
             }
         }
     }
     return(View(editedServicePrincipal));
 }
예제 #8
0
        public ActionResult Index(TemplatePublisherModel templatePublisherModel)
        {
            try
            {
                //check if the templates already exist in table cache
                ServicePrincipalModel       servicePrincipal = ServicePrincipalModel.GetFromStorage(templatePublisherModel.ServicePrincipal.TenantId);
                IEnumerable <TemplateModel> templates        = TemplateModel.GetFromStorage(templatePublisherModel.ServicePrincipal.TenantId);
                if (templates == null || templates.Count <TemplateModel>() == 0)
                {
                    //prepare a message and send via queue to worker role
                    RmsCommand        rmsCommand        = new RmsCommand(RmsCommand.Command.GetTemplate, servicePrincipal.TenantId);
                    CloudQueueMessage cloudQueueMessage = new CloudQueueMessage(rmsCommand.ToString());
                    DataModel.StorageFactory.Instance.IpcAzureAppWorkerJobQueue.AddMessage(cloudQueueMessage);

                    TemplateModel template = new TemplateModel();
                    template.TenantId = servicePrincipal.TenantId;

                    //Poll for completetion of job by worker role. Don't poll for more than a minute
                    DateTime startTime = DateTime.Now;
                    IEnumerable <TemplateModel> tList = null;
                    while (startTime.AddMinutes(1) > DateTime.Now)
                    {
                        System.Threading.Thread.Sleep(1 * 500);
                        tList = TemplateModel.GetFromStorage(template.TenantId);
                        if (tList != null && tList.Count <TemplateModel>() > 0)
                        {
                            templates = tList;
                            break;
                        }
                    }
                }
                templatePublisherModel.Templates = templates;
                templatePublisherModel.ServicePrincipal.TenantName = servicePrincipal.TenantName;
                templatePublisherModel.ServicePrincipal.TenantId   = servicePrincipal.TenantId;
                return(View(templatePublisherModel));
            }
            catch (StorageException se)
            {
                ViewBag.errorMessage = "Timeout error, try again. ";
                Trace.TraceError(se.Message);
                return(View("Error"));
            }
        }
예제 #9
0
 /// <summary>
 /// Default get request
 /// </summary>
 /// <returns>Action Result</returns>
 public ActionResult Index()
 {
     try
     {
         TemplatePublisherModel templatePublisherModel         = new TemplatePublisherModel();
         IEnumerable <ServicePrincipalModel> servicePrincipals = ServicePrincipalModel.GetAllFromStorage();
         if (servicePrincipals == null || servicePrincipals.Count <ServicePrincipalModel>() == 0)
         {
             return(RedirectToAction("Index", "ServicePrincipal"));
         }
         else
         {
             templatePublisherModel.ServicePrincipals = servicePrincipals;
             return(View(templatePublisherModel));
         }
     }
     catch (StorageException se)
     {
         ViewBag.errorMessage = "Timeout error, try again. ";
         Trace.TraceError(se.Message);
         return(View("Error"));
     }
 }
        // GET: /ServicePrincipal/Edit/{id}
        public ActionResult Edit(string tenantId)
        {
            var servicePrincipal = ServicePrincipalModel.GetFromStorage(tenantId);

            return(View(servicePrincipal));
        }
        // GET: /ServicePrincipal/Delete/{id}
        public ActionResult Delete(string tenantId)
        {
            var servicePrincipalList = ServicePrincipalModel.GetFromStorage(tenantId);

            return(View(servicePrincipalList));
        }
        public async Task <ActionResult> SubmitServicePrincipal(ServicePrincipalModel newPrincipal)
        {
            return(await SafeExecuteView(async() =>
            {
                // Add the default values to the model
                newPrincipal.TenantId = AuthenticationConfig.SessionItems.GraphTargetTenant;

                // Validate required attributes for Service Principal Submission
                if (string.IsNullOrEmpty(newPrincipal.Password))
                {
                    ModelState.AddModelError("Password", "Missing password!");
                }
                if (string.IsNullOrEmpty(newPrincipal.DisplayName))
                {
                    ModelState.AddModelError("DisplayName", "Missing display name for the principal!");
                }
                if (string.IsNullOrEmpty(newPrincipal.AppIdUri))
                {
                    ModelState.AddModelError("AppIdUri", "Missing AppId Uri for the app created for the principal!");
                }

                var tenantIdGuid = default(Guid);
                if (!Guid.TryParse(newPrincipal.TenantId, out tenantIdGuid))
                {
                    ModelState.AddModelError("TenantId", "Invalid TenantId - TenantId must be GUID!");
                }

                // Depending on model state, create the principal or skip creation
                if (ModelState.IsValid)
                {
                    var appForSp = await ServicePrincipalLogic.CreateAppAndServicePrincipal
                                   (
                        newPrincipal.DisplayName,
                        newPrincipal.AppIdUri,
                        newPrincipal.Password,
                        newPrincipal.TenantId
                                   );

                    newPrincipal.DisplayName = appForSp.App.DisplayName;
                    newPrincipal.AppIdUri = appForSp.App.IdentifierUris.First();
                    newPrincipal.AppId = appForSp.App.AppId;

                    var messageBuilder = new StringBuilder();
                    messageBuilder.Append($"Request executed successfully at {DateTime.Now.ToString("yyyy-MM-dd hh:mm")}:{Environment.NewLine}");
                    messageBuilder.AppendFormat("- {0}{1}", (appForSp.IsNewApp ? "Created new App!" : "Re-used existing App!"), Environment.NewLine);
                    messageBuilder.AppendFormat("- {0}{1}", (appForSp.IsNewPrincipal ? "Created new Service Principal on App!" : "Re-used existing Service Principal on App and added new password!"), Environment.NewLine);

                    newPrincipal.UserMessage = messageBuilder.ToString();
                }
                else
                {
                    newPrincipal.UserMessage = "Please fix validation errors in your data entry!";
                }

                newPrincipal.SubmitSpEnabled = true;
                newPrincipal.ShowSpDetails = true;
                newPrincipal.SubmitConsentEnabled = false;
                newPrincipal.SubmitAdminConsentEnabled = true;
                return View("Index", newPrincipal);
            }));
        }
예제 #13
0
        private void ProcessQueueMessage(object state)
        {
            CloudQueueMessage msg = state as CloudQueueMessage;

            try
            {
                // Log and delete if this is a "poison" queue message (repeatedly processed
                // and always causes an error that prevents processing from completing).
                // Production applications should move the "poison" message to a "dead message"
                // queue for analysis rather than deleting the message.
                if (msg.DequeueCount > 5)
                {
                    Trace.TraceError("Deleting poison message: message {0} Role Instance {1}.",
                                     msg.ToString(), GetRoleInstance());
                    DataModel.StorageFactory.Instance.IpcAzureAppWorkerJobQueue.DeleteMessage(msg);
                    return;
                }

                RmsCommand rmsCommand = new RmsCommand(msg.AsString);
                switch (rmsCommand.RmsOperationCommand)
                {
                case RmsCommand.Command.GetTemplate:
                {
                    ServicePrincipalModel   sp           = ServicePrincipalModel.GetFromStorage(rmsCommand.Parameters.First <object>().ToString());
                    RMS.RmsContentPublisher rmsPublisher = RMS.RmsContentPublisher.Create(sp.TenantId, sp.AppId, sp.Key);
                    var templates = rmsPublisher.GetRmsTemplates();
                    List <TemplateModel> templateEntityList = new List <TemplateModel>();
                    foreach (var temp in templates)
                    {
                        TemplateModel templateEntity = new TemplateModel();
                        templateEntity.TenantId            = sp.TenantId;
                        templateEntity.TemplateId          = temp.TemplateId;
                        templateEntity.TemplateName        = temp.Name;
                        templateEntity.TemplateDescription = temp.Description;
                        templateEntityList.Add(templateEntity);
                    }
                    TemplateModel.SaveToStorage(templateEntityList);
                    break;
                }

                case RmsCommand.Command.PublishTemplate:
                {
                    PublishModel          publishJob       = PublishModel.GetFromStorage(rmsCommand.Parameters[0].ToString(), rmsCommand.Parameters[1].ToString());
                    ServicePrincipalModel sp               = ServicePrincipalModel.GetFromStorage(rmsCommand.Parameters[0].ToString());
                    CloudBlockBlob        originalFileBlob = DataModel.StorageFactory.Instance.IpcAzureAppFileBlobContainer.GetBlockBlobReference(publishJob.OriginalFileBlobRef);

                    Stream sinkStream   = null;
                    string tempFilePath = null;

                    try
                    {
                        //if file length is less than 100,000 bytes, keep it in memory
                        if (publishJob.OriginalFileSizeInBytes < 100000)
                        {
                            sinkStream = new MemoryStream();
                        }
                        else
                        {
                            tempFilePath = Path.GetRandomFileName();
                            sinkStream   = new FileStream(tempFilePath, FileMode.Create);
                        }


                        using (Stream sourceStream = originalFileBlob.OpenRead())
                            using (sinkStream)
                            {
                                RMS.RmsContent rmsContent = new RMS.RmsContent(sourceStream, sinkStream);
                                rmsContent.RmsTemplateId = publishJob.TemplateId;
                                rmsContent.OriginalFileNameWithExtension = publishJob.OriginalFileName;
                                RMS.RmsContentPublisher rmsContentPublisher = RMS.RmsContentPublisher.Create(sp.TenantId, sp.AppId, sp.Key);
                                rmsContentPublisher.PublishContent(rmsContent);

                                publishJob.PublishedFileName = rmsContent.PublishedFileNameWithExtension;
                                sinkStream.Flush();
                                sinkStream.Seek(0, SeekOrigin.Begin);

                                //published file is uploaded to blob storage.
                                //Note: This sample code doesn't manage lifetime of this original and published file blob
                                //Actual code must manage the lifetime as appropriate
                                CloudBlockBlob destFileBlob = DataModel.StorageFactory.Instance.IpcAzureAppFileBlobContainer.GetBlockBlobReference(publishJob.PublishedFileBlobRef);
                                using (CloudBlobStream blobStream = destFileBlob.OpenWrite())
                                {
                                    int    tempSize   = 1024;
                                    byte[] tempBuffer = new byte[tempSize];
                                    while (true)
                                    {
                                        int readSize = sinkStream.Read(tempBuffer, 0, tempSize);
                                        if (readSize <= 0)
                                        {
                                            break;
                                        }

                                        blobStream.Write(tempBuffer, 0, readSize);
                                    }
                                    blobStream.Flush();
                                }
                            }

                        publishJob.JState = PublishModel.JobState.Completed.ToString();
                        publishJob.SaveToStorage();
                        break;
                    }
                    finally
                    {
                        if (!string.IsNullOrWhiteSpace(tempFilePath) && File.Exists(tempFilePath))
                        {
                            File.Delete(tempFilePath);
                        }
                    }
                }
                }

                //delete the message from the queue
                DataModel.StorageFactory.Instance.IpcAzureAppWorkerJobQueue.DeleteMessage(msg);
            }
            catch (Exception ex)
            {
                Process p   = Process.GetCurrentProcess();
                string  a   = p.ProcessName;
                string  b   = p.MainModule.FileName;
                string  err = ex.Message;
                if (ex.InnerException != null)
                {
                    err += " Inner Exception: " + ex.InnerException.Message;
                }
                if (msg != null)
                {
                    err += " Last queue message retrieved: " + msg.AsString;
                }
                Trace.TraceError(err);
            }
        }