Exemplo n.º 1
0
        //BT_SignOut will close out the session and clear the grid of auth data.
        private void BT_SignOut_Click(object sender, EventArgs e)
        {
            System.Threading.Tasks.Task AuthTask = null;                                                            //Declare task.

            AuthTask = System.Threading.Tasks.Task.Run((Action)(() => { O365.MSALWork(O365.AADAction.SignOut); })); //AAD Sign out - no prompt.

            if (AuthTask.IsCompleted != true)                                                                       //While operation in progress, update button to show that we are signing out.
            {
                BT_SignOut.Text    = "Signing out";
                BT_SignOut.Enabled = false;
                AuthTask.Wait();
            }

            BT_SignOut.Enabled = false;
            BT_SignOut.Text    = "Refreshing...";//Sign out complete, wait 1 second for refresh below

            if (AuthTask.IsCompleted == true)
            {
                System.Threading.Thread.Sleep(1000);
                callonload();// Refresh grid.

                //Update buttons to properly state status.
                BT_SignIn.Enabled = true;
                BT_SignIn.Text    = "Sign in";
                BT_SignOut.Text   = "Sign out";
            }
        }
Exemplo n.º 2
0
        //BT_Reauth serves the function of AADAction.ForceSignIn - operation availiable while signed in or out.
        private void BT_Reauth_Click(object sender, EventArgs e)
        {
            System.Threading.Tasks.Task AuthTask = null;                                                                //Declare auth task

            AuthTask = System.Threading.Tasks.Task.Run((Action)(() => { O365.MSALWork(O365.AADAction.ForceSignIn); })); // AAD Login prompt.

            if (AuthTask.IsCompleted != true)                                                                           //Similar to the sign in action, the auth state can be renewed manually via ForceSignIn
            {
                BT_SignIn.Text    = "Logging in";
                BT_SignIn.Enabled = false;
                AuthTask.Wait();
            }

            BT_SignIn.Enabled = false;
            BT_SignIn.Text    = "Refreshing...";

            if (AuthTask.IsCompleted == true || O365.isLoggedIn == false)
            {
                MessageBox.Show("Authentication failed. Please try again.", "Warning"); //Error catch in case auth fails.
            }

            if (AuthTask.IsCompleted == true)
            {
                System.Threading.Thread.Sleep(1000);
                callonload();// Datagrid refresh.
                BT_SignIn.Text = "Signed in";
            }
        }
Exemplo n.º 3
0
        /// <summary>
        /// Perform an HTTP GET request to a URL using an HTTP Authorization header
        /// </summary>
        /// <param name="url">The URL</param>
        /// <returns>String containing the results of the GET operation</returns>
        public static async Task <string> GetHttpContentWithToken(string url)
        {
            OOFSponder.Logger.Info(OOFSponderInsights.CurrentMethod());

            //check and refresh token if necessary
            await O365.MSALWork(O365.AADAction.SignIn);

            var httpClient = new System.Net.Http.HttpClient();

            System.Net.Http.HttpResponseMessage response;
            try
            {
                var request = new System.Net.Http.HttpRequestMessage(System.Net.Http.HttpMethod.Get, UrlCombine(_graphAPIEndpoint, url));
                //Add the token in Authorization header
                request.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", authResult.AccessToken);
                response = await httpClient.SendAsync(request);

                var content = await response.Content.ReadAsStringAsync();

                return(content);
            }
            catch (Exception ex)
            {
                OOFSponder.Logger.Error(ex);
                return(ex.ToString());
            }
        }
Exemplo n.º 4
0
        /// <summary>
        /// Perform an HTTP GET request to a URL using an HTTP Authorization header
        /// </summary>
        /// <param name="url">The URL</param>
        /// <param name="token">The token</param>
        /// <returns>String containing the results of the GET operation</returns>
        public static async Task <System.Net.Http.HttpResponseMessage> PatchHttpContentWithToken(string url, Microsoft.Graph.AutomaticRepliesSetting OOF)
        {
            OOFSponderInsights.TrackInfo(OOFSponderInsights.CurrentMethod());

            //check and refresh token if necessary
            await O365.MSALWork(O365.AADAction.SignIn);

            var httpClient = new System.Net.Http.HttpClient();

            System.Net.Http.HttpMethod          method = new System.Net.Http.HttpMethod("PATCH");
            System.Net.Http.HttpResponseMessage response;

            //         var response = client.PostAsync("api/AgentCollection", new StringContent(
            //new JavaScriptSerializer().Serialize(user), Encoding.UTF8, "application/json")).Result;

            try
            {
                Microsoft.Graph.MailboxSettings mbox = new Microsoft.Graph.MailboxSettings();
                mbox.AutomaticRepliesSetting = OOF;

                var request  = new System.Net.Http.HttpRequestMessage(method, UrlCombine(_graphAPIEndpoint, url));
                var jsonBody = Newtonsoft.Json.JsonConvert.SerializeObject(mbox);
                System.Net.Http.StringContent iContent = new System.Net.Http.StringContent(jsonBody, Encoding.UTF8, "application/json");
                request.Content = iContent;
                //Add the token in Authorization header
                request.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", authResult.AccessToken);
                response = await httpClient.SendAsync(request);

                return(response);
            }
            catch (Exception ex)
            {
                throw new Exception("Unable to set OOF: " + ex.Message, ex);
            }
        }
Exemplo n.º 5
0
        void signOutToolStripMenuItem_Click(object sender, EventArgs e)
        {
            OOFSponderInsights.TrackInfo(OOFSponderInsights.CurrentMethod());
            //prep for async work
            System.Threading.Tasks.Task AuthTask = null;

            if (saveToolStripMenuItem.Tag.ToString() == "LoggedIn")
            {
                AuthTask = System.Threading.Tasks.Task.Run((Action)(() => { O365.MSALWork(O365.AADAction.SignOut); }));
            }
            else
            {
                AuthTask = System.Threading.Tasks.Task.Run((Action)(() => { O365.MSALWork(O365.AADAction.SignIn); }));
            }

            //wait on async auth stuff if not null
            if (AuthTask != null)
            {
                AuthTask.Wait();
            }
        }
Exemplo n.º 6
0
        private void BT_SignIn_Click(object sender, System.EventArgs e)
        {
            System.Threading.Tasks.Task AuthTask = null;                                                           //Declare auth task

            AuthTask = System.Threading.Tasks.Task.Run((Action)(() => { O365.MSALWork(O365.AADAction.SignIn); })); // AAD Login prompt.

            if (AuthTask.IsCompleted != true)                                                                      //Check if the login is complete, if not, update button to say that login is in process.
            {
                BT_SignIn.Text    = "Logging in";
                BT_SignIn.Enabled = false;
                AuthTask.Wait();
            }

            //Need to wait for the auth session.
            BT_SignIn.Enabled = false;
            BT_SignIn.Text    = "Refreshing...";

            if (AuthTask.IsCompleted == true) //After authentication is complete, wait for 1 second to allow for refresh of the auth data.
            {
                System.Threading.Thread.Sleep(1000);
                callonload(); //Call reload of grid.
                BT_SignIn.Text = "Signed in";
            }
        }
Exemplo n.º 7
0
        public async System.Threading.Tasks.Task <bool> TrySetOOF365(string oofMessageExternal, string oofMessageInternal, DateTime StartTime, DateTime EndTime)
        {
            OOFSponderInsights.TrackInfo(OOFSponderInsights.CurrentMethod());
            toolStripStatusLabel1.Text = DateTime.Now.ToString() + " - Sending to O365";

            //need to convert the times from local datetime to DateTimeTimeZone and UTC
            DateTimeTimeZone oofStart = new DateTimeTimeZone {
                DateTime = StartTime.ToUniversalTime().ToString("u").Replace("Z", ""), TimeZone = "UTC"
            };
            DateTimeTimeZone oofEnd = new DateTimeTimeZone {
                DateTime = EndTime.ToUniversalTime().ToString("u").Replace("Z", ""), TimeZone = "UTC"
            };

            //create local OOF object
            AutomaticRepliesSetting localOOF = new AutomaticRepliesSetting();

            localOOF.ExternalReplyMessage   = oofMessageExternal;
            localOOF.InternalReplyMessage   = oofMessageInternal;
            localOOF.ScheduledStartDateTime = oofStart;
            localOOF.ScheduledEndDateTime   = oofEnd;
            localOOF.Status = AutomaticRepliesStatus.Scheduled;

            try
            {
                OOFSponderInsights.Track("Getting OOF settings from O365");
                string getOOFraw = await O365.GetHttpContentWithToken(O365.AutomatedReplySettingsURL);

                AutomaticRepliesSetting remoteOOF = JsonConvert.DeserializeObject <AutomaticRepliesSetting>(getOOFraw);
                OOFSponderInsights.Track("Successfully got OOF settings");

                bool externalReplyMessageEqual = remoteOOF.ExternalReplyMessage.CleanReplyMessage() == localOOF.ExternalReplyMessage.CleanReplyMessage();
                bool internalReplyMessageEqual = remoteOOF.InternalReplyMessage.CleanReplyMessage() == localOOF.InternalReplyMessage.CleanReplyMessage();

                //local and remote are both UTC, so just compare times
                //Not sure it can ever happen to have the DateTime empty, but wrap this in a TryCatch just in case
                //set both to false - that way, we don't care if either one blows up
                //because if one is false, the overall evaluation is false anyway
                bool scheduledStartDateTimeEqual = false;
                bool scheduledEndDateTimeEqual   = false;
                try
                {
                    scheduledStartDateTimeEqual = DateTime.Parse(remoteOOF.ScheduledStartDateTime.DateTime) == DateTime.Parse(localOOF.ScheduledStartDateTime.DateTime);
                    scheduledEndDateTimeEqual   = DateTime.Parse(remoteOOF.ScheduledEndDateTime.DateTime) == DateTime.Parse(localOOF.ScheduledEndDateTime.DateTime);
                }
                catch (Exception)
                {
                    //do nothing because we will just take the initialized false values;
                }

                if (!externalReplyMessageEqual ||
                    !internalReplyMessageEqual ||
                    !scheduledStartDateTimeEqual ||
                    !scheduledEndDateTimeEqual
                    )
                {
                    OOFSponderInsights.Track("Local OOF doesn't match remote OOF");
                    System.Net.Http.HttpResponseMessage result = await O365.PatchHttpContentWithToken(O365.MailboxSettingsURL, localOOF);

                    if (result.StatusCode == System.Net.HttpStatusCode.OK)
                    {
                        UpdateStatusLabel(toolStripStatusLabel1, DateTime.Now.ToString() + " - OOF message set - Start: " + StartTime + " - End: " + EndTime);

                        //report back to AppInsights
                        OOFSponderInsights.Track("Successfully set OOF");
                        return(true);
                    }
                    else
                    {
                        OOFSponderInsights.Track("Unable to set OOF");
                        UpdateStatusLabel(toolStripStatusLabel1, DateTime.Now.ToString() + " - Unable to set OOF message");
                        return(false);
                    }
                }
                else
                {
                    OOFSponderInsights.Track("Remote OOF matches - no changes");
                    UpdateStatusLabel(toolStripStatusLabel1, DateTime.Now.ToString() + " - No changes needed, OOF Message not changed - Start: " + StartTime + " - End: " + EndTime);
                    return(true);
                }
            }
            catch (Exception ex)
            {
                notifyIcon1.ShowBalloonTip(100, "OOF Exception", "Unable to set OOF: " + ex.Message, ToolTipIcon.Error);
                UpdateStatusLabel(toolStripStatusLabel1, DateTime.Now.ToString() + " - Unable to set OOF");
                OOFSponderInsights.TrackException("Unable to set OOF: " + ex.Message, ex);

                return(false);
            }
        }
Exemplo n.º 8
0
        public Form1()
        {
            OOFSponderInsights.TrackInfo(OOFSponderInsights.CurrentMethod());

            InitializeComponent();

            #region SetBuildInfo
            foreach (Assembly a in Thread.GetDomain().GetAssemblies())
            {
                if (a.GetName().Name == "OOFScheduling")
                {
                    OOFData.version = lblBuild.Text = a.GetName().Version.ToString();
                    break;
                }
            }
            #endregion

            OOFSponderInsights.ConfigureApplicationInsights();

            OOFSponderInsights.Track("OOFSponderStart");

            //Set icon in code
            this.Icon = Properties.Resources.OOFSponderIcon;

            #region Add to Startup
            // The path to the key where Windows looks for startup applications
            RegistryKey rkApp = Registry.CurrentUser.OpenSubKey(
                @"SOFTWARE\Microsoft\Windows\CurrentVersion\Run", true);

            //Path to launch shortcut
            string startPath = Environment.GetFolderPath(Environment.SpecialFolder.Programs)
                               + @"\Microsoft\OOFSponder.appref-ms";

            rkApp.SetValue("OOFSponder", startPath);
            #endregion
            #region Tray Menu Initialize
            // Create a simple tray menu with only one item.
            trayMenu = new ContextMenu();
            trayMenu.MenuItems.Add("Exit", OnExit);

            // Add menu to tray icon and show it.
            notifyIcon1.ContextMenu = trayMenu;
            notifyIcon1.Icon        = Properties.Resources.OOFSponderIcon;
            #endregion
            #region Read the list of teams to populate with templates
            //Read in the list of teams and build the dictionary list of team name
            //and template location

            //for each team, add an entry to the the Team Settings menu item (teamSettingsToolStripMenuItem)

            //If Use Team Settings is checked and a team is selected
            //then pull the remote files in as the text and then set the
            //controls to ReadOnly
            //Use a naming convention of "ExternalOOF.html" and "InternalOOF.html"?

            //Will also need to add some #Start/#End/#TimeZone logic
            //could even get fancy and have that be some sort of pop-up
            //so that each team could have its own
            //this is definitely future work :)

            #endregion


            //prep for async work
            System.Threading.Tasks.Task AuthTask = null;
            AuthTask = System.Threading.Tasks.Task.Run((Action)(() => { O365.MSALWork(O365.AADAction.SignIn); }));

#if DEBUGFLOW
            MessageBox.Show("Attach now", "OOFSponder", MessageBoxButtons.OK);
#endif

            if (OOFData.Instance.IsPermaOOFOn)
            {
                SetUIforSecondary();
            }
            else
            {
                SetUIforPrimary();
            }

            if (OOFData.Instance.WorkingHours != "")
            {
                string[] workingHours = OOFData.Instance.WorkingHours.Split('|');

                //Zero means you are off that day (not working) therefore the box is checked
                string[] dayHours = workingHours[0].Split('~');
                if (dayHours[2] == "0")
                {
                    sundayOffWorkCB.Checked = true;
                }
                else
                {
                    sundayOffWorkCB.Checked = false;
                }
                sundayStartTimepicker.Value = DateTime.Parse(dayHours[0]);
                sundayEndTimepicker.Value   = DateTime.Parse(dayHours[1]);

                dayHours = workingHours[1].Split('~');
                if (dayHours[2] == "0")
                {
                    mondayOffWorkCB.Checked = true;
                }
                else
                {
                    mondayOffWorkCB.Checked = false;
                }
                mondayStartTimepicker.Value = DateTime.Parse(dayHours[0]);
                mondayEndTimepicker.Value   = DateTime.Parse(dayHours[1]);

                dayHours = workingHours[2].Split('~');
                if (dayHours[2] == "0")
                {
                    tuesdayOffWorkCB.Checked = true;
                }
                else
                {
                    tuesdayOffWorkCB.Checked = false;
                }
                tuesdayStartTimepicker.Value = DateTime.Parse(dayHours[0]);
                tuesdayEndTimepicker.Value   = DateTime.Parse(dayHours[1]);

                dayHours = workingHours[3].Split('~');
                if (dayHours[2] == "0")
                {
                    wednesdayOffWorkCB.Checked = true;
                }
                else
                {
                    wednesdayOffWorkCB.Checked = false;
                }
                wednesdayStartTimepicker.Value = DateTime.Parse(dayHours[0]);
                wednesdayEndTimepicker.Value   = DateTime.Parse(dayHours[1]);

                dayHours = workingHours[4].Split('~');
                if (dayHours[2] == "0")
                {
                    thursdayOffWorkCB.Checked = true;
                }
                else
                {
                    thursdayOffWorkCB.Checked = false;
                }
                thursdayStartTimepicker.Value = DateTime.Parse(dayHours[0]);
                thursdayEndTimepicker.Value   = DateTime.Parse(dayHours[1]);

                dayHours = workingHours[5].Split('~');
                if (dayHours[2] == "0")
                {
                    fridayOffWorkCB.Checked = true;
                }
                else
                {
                    fridayOffWorkCB.Checked = false;
                }
                fridayStartTimepicker.Value = DateTime.Parse(dayHours[0]);
                fridayEndTimepicker.Value   = DateTime.Parse(dayHours[1]);

                dayHours = workingHours[6].Split('~');
                if (dayHours[2] == "0")
                {
                    saturdayOffWorkCB.Checked = true;
                }
                else
                {
                    saturdayOffWorkCB.Checked = false;
                }
                saturdayStartTimepicker.Value = DateTime.Parse(dayHours[0]);
                saturdayEndTimepicker.Value   = DateTime.Parse(dayHours[1]);
            }

            bool haveNecessaryData = false;


            //we need the OOF messages and working hours
            if (OOFData.Instance.PrimaryOOFExternalMessage != "" && OOFData.Instance.PrimaryOOFInternalMessage != "" &&
                OOFData.Instance.WorkingHours != "")
            {
                haveNecessaryData = true;
            }

            if (haveNecessaryData)
            {
                toolStripStatusLabel1.Text = "Ready";
                OOFSponderInsights.TrackInfo("HaveNecessaryData");
            }
            else
            {
                toolStripStatusLabel1.Text = "Please setup OOFsponder";
                OOFSponderInsights.TrackInfo("MissingData");
            }

            toolStripStatusLabel2.Text = "";
            Loopy();

            //set up handlers to persist OOF messages
            htmlEditorControl1.Validated += htmlEditorValidated;
            htmlEditorControl2.Validated += htmlEditorValidated;

            //wait on async auth stuff if not null
            if (AuthTask != null)
            {
                AuthTask.Wait();
            }

            //trigger a check on current status
            System.Threading.Tasks.Task.Run(() => RunSetOofO365());

            radPrimary.CheckedChanged             += new System.EventHandler(radPrimary_CheckedChanged);
            fileToolStripMenuItem.DropDownOpening += fileToolStripMenuItem_DropDownOpening;
        }
Exemplo n.º 9
0
        private async System.Threading.Tasks.Task <bool> RunSetOofO365()
        {
            OOFSponder.Logger.Info(OOFSponderInsights.CurrentMethod());

            bool haveNecessaryData = false;

            //if CredMan is turned on, then we don't need the email or password
            //but we still need the OOF messages and working hours
            //also, don't need to check SecondaryOOF messages for two reasons:
            //1) they won't always be set
            //2) the UI flow won't let you get here with permaOOF if they aren't set
            if (OOFData.Instance.PrimaryOOFExternalMessage != "" &&
                OOFData.Instance.PrimaryOOFInternalMessage != "" &&
                OOFData.Instance.WorkingHours != "")
            {
                haveNecessaryData = true;
                OOFSponderInsights.Track("HaveNecessaryData");
            }

            bool result = false;

            if (haveNecessaryData)
            {
                DateTime[] oofTimes = getOofTime(OOFData.Instance.WorkingHours);

                ////if PermaOOF is turned on, need to adjust the end time
                //if (OOFData.Instance.PermaOOFDate < oofTimes[0])
                //{
                //    //set all the UI stuff back to primary
                //    //to set up for normal OOF schedule
                //    SetUIforPrimary();

                //}

                //persist settings just in case
                string oofMessageExternal = htmlEditorControl1.BodyHtml;
                string oofMessageInternal = htmlEditorControl2.BodyHtml;
                //if (!OOFData.Instance.IsPermaOOFOn)
                //{
                //    OOFData.Instance.PrimaryOOFExternalMessage = htmlEditorControl1.BodyHtml;
                //    OOFData.Instance.PrimaryOOFInternalMessage = htmlEditorControl2.BodyHtml;
                //}
                //else
                //{
                //    OOFData.Instance.SecondaryOOFExternalMessage = htmlEditorControl1.BodyHtml;
                //    OOFData.Instance.SecondaryOOFInternalMessage = htmlEditorControl2.BodyHtml;
                //}

                //if not logged in, give the user a chance to log in
                if (!O365.isLoggedIn)
                {
                    OOFSponder.Logger.Error("Not logged in when trying to Save Settings. Giving them one more try.");

                    System.Threading.Tasks.Task AuthTask = null;
                    AuthTask = System.Threading.Tasks.Task.Run((Action)(() => { O365.MSALWork(O365.AADAction.SignIn); }));
                    AuthTask.Wait(10000);

                    //if still not logged in, bail
                    if (!O365.isLoggedIn)
                    {
                        OOFSponder.Logger.Error("STILL not logged in, so stopping from saving");
                        MessageBox.Show("Not logged in!. Please hit Save Settings again and log in with a valid user");
                        return(false);
                    }
                }

                //if PermaOOF isn't turned on, use the standard logic based on the stored schedule
                if ((oofTimes[0] != oofTimes[1]) && !OOFData.Instance.IsPermaOOFOn)
                {
                    OOFSponderInsights.Track("TrySetNormalOOF");
#if !NOOOF
                    result = await System.Threading.Tasks.Task.Run(() => TrySetOOF365(oofMessageExternal, oofMessageInternal, oofTimes[0], oofTimes[1]));
#else
                    result = true;
#endif
                }
                else
                //since permaOOF is on, need to adjust the end date such that is permaOOFDate
                //if permaOOF>oofTimes[0] and permaOOF<oofTimes[1], then AddDays((permaOOFDate - oofTimes[1]).Days
                //due to the way the math works out, need to add extra day if permaOOF>oofTimes[1]
                {
                    int adjustmentDays = 0;
                    if (OOFData.Instance.PermaOOFDate > oofTimes[0] && OOFData.Instance.PermaOOFDate < oofTimes[1])
                    {
                        adjustmentDays = 1;
                    }

                    //in order to accomodate someone going OOF mid-schedule
                    //check if now is before the next scheduled "OFF" slot
                    //if it is, then adjust start time to NOW
                    if (oofTimes[0] > DateTime.Now)
                    {
                        oofTimes[0] = DateTime.Now;
                    }

                    OOFSponderInsights.Track("TrySetPermaOOF");
#if !NOOOF
                    result = await System.Threading.Tasks.Task.Run(() => TrySetOOF365(oofMessageExternal, oofMessageInternal, oofTimes[0], oofTimes[1].AddDays((OOFData.Instance.PermaOOFDate - oofTimes[1]).Days + adjustmentDays)));
#else
                    result = true;
#endif
                }
            }

            return(result);
        }