コード例 #1
0
        private void saveSettings()
        {
            OOFSponderInsights.TrackInfo(OOFSponderInsights.CurrentMethod());

            if (primaryToolStripMenuItem.Checked)
            {
                OOFData.Instance.PrimaryOOFExternalMessage = htmlEditorControl1.BodyHtml;
                OOFData.Instance.PrimaryOOFInternalMessage = htmlEditorControl2.BodyHtml;
            }
            else
            //since customer is editing Secondary message, save text in Secondary
            {
                OOFData.Instance.SecondaryOOFExternalMessage = htmlEditorControl1.BodyHtml;
                OOFData.Instance.SecondaryOOFInternalMessage = htmlEditorControl2.BodyHtml;
            }

            OOFData.Instance.WorkingHours = ScheduleString();
            OOFData.Instance.WriteProperties();

            toolStripStatusLabel1.Text = "Settings Saved";
            OOFSponderInsights.TrackInfo("Settings saved");

            //go implement the settings if possible
            System.Threading.Tasks.Task.Run(() => RunSetOofO365());
        }
コード例 #2
0
        private async void timer_Elapsed(object sender, ElapsedEventArgs e)
        {
            OOFSponderInsights.TrackInfo(OOFSponderInsights.CurrentMethod());
            await System.Threading.Tasks.Task.Run(() => RunSetOofO365());

            //await checkOOFStatus();
        }
コード例 #3
0
ファイル: OOF.cs プロジェクト: karyjac/OOFSponder
        public void WriteProperties(bool disposing = false)
        {
            OOFSponderInsights.TrackInfo(OOFSponderInsights.CurrentMethod());

            System.Diagnostics.Trace.TraceInformation("Persisting properties");

            Properties.Settings.Default.PrimaryOOFExternal = instance.PrimaryOOFExternalMessage;
            System.Diagnostics.Trace.TraceInformation("Persisting PrimaryOOFExternalMessage");

            Properties.Settings.Default.PrimaryOOFInternal = instance.PrimaryOOFInternalMessage;
            System.Diagnostics.Trace.TraceInformation("Persisting PrimaryOOFInternalMessage");

            Properties.Settings.Default.SecondaryOOFExternal = instance.SecondaryOOFExternalMessage;
            System.Diagnostics.Trace.TraceInformation("Persisting SecondaryOOFExternalMessage");

            Properties.Settings.Default.SecondaryOOFInternal = instance.SecondaryOOFInternalMessage;
            System.Diagnostics.Trace.TraceInformation("Persisting SecondaryOOFInternalMessage");

            Properties.Settings.Default.PermaOOFDate = instance.PermaOOFDate;
            System.Diagnostics.Trace.TraceInformation("Persisting PermaOOFDate");

            Properties.Settings.Default.workingHours = instance.WorkingHours;
            System.Diagnostics.Trace.TraceInformation("Persisting WorkingHours");

            Properties.Settings.Default.Save();

            if (disposing)
            {
                Dispose();
            }
        }
コード例 #4
0
        private void SetUIforSecondary()
        {
            OOFSponderInsights.TrackInfo(OOFSponderInsights.CurrentMethod());

            primaryToolStripMenuItem.Checked   = false;
            secondaryToolStripMenuItem.Checked = !primaryToolStripMenuItem.Checked;
            lblExternalMesage.Text             = "Extended OOF External Message";
            lblInternalMessage.Text            = "Extended OOF Internal Message";

            htmlEditorControl1.BodyHtml = OOFData.Instance.SecondaryOOFExternalMessage;
            htmlEditorControl2.BodyHtml = OOFData.Instance.SecondaryOOFInternalMessage;

            //update the UI
            if (OOFData.Instance.IsPermaOOFOn)
            {
                btnPermaOOF.Text   = "Disable Extended OOF";
                btnPermaOOF.Tag    = "Disable";
                dtPermaOOF.Enabled = false;
            }
            else
            {
                btnPermaOOF.Text   = "Enable Extended OOF";
                btnPermaOOF.Tag    = "Enable";
                dtPermaOOF.Value   = DateTime.Now.AddDays(1);
                dtPermaOOF.Enabled = true;
            }

            //lastly, enable the permaOOF controls to help with some UI flow issues
            btnPermaOOF.Enabled = true;

            OOFSponderInsights.Track("Configured for secondary");
        }
コード例 #5
0
ファイル: O365.cs プロジェクト: BartonsGit/OOFSponder
        /// <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());
            }
        }
コード例 #6
0
ファイル: Form1.cs プロジェクト: vivesg/OOFSponder
        private void secondaryToolStripMenuItem_Click(object sender, EventArgs e)
        {
            OOFSponder.Logger.Info(OOFSponderInsights.CurrentMethod());

            //now, set up the UI for PermaOOF
            SetUIforSecondary();
        }
コード例 #7
0
        private void primaryToolStripMenuItem_Click(object sender, EventArgs e)
        {
            OOFSponderInsights.TrackInfo(OOFSponderInsights.CurrentMethod());

            //now, set up the UI for primary
            SetUIforPrimary();
        }
コード例 #8
0
        private void SetUIforPrimary()
        {
            OOFSponderInsights.TrackInfo(OOFSponderInsights.CurrentMethod());

            //since we are in the process of flipping from secondary to primary
            //we know that the UI is currently in Secondary mode (or first run)
            //so HTML controls have the Secondary messages

            //disable PermaOOF by setting date to time in the past
            OOFData.Instance.PermaOOFDate = DateTime.Now.AddMinutes(-1);

            primaryToolStripMenuItem.Checked   = true;
            secondaryToolStripMenuItem.Checked = !primaryToolStripMenuItem.Checked;
            lblExternalMesage.Text             = "Primary External Message";
            lblInternalMessage.Text            = "Primary Internal Message";

            htmlEditorControl1.BodyHtml = OOFData.Instance.PrimaryOOFExternalMessage;
            htmlEditorControl2.BodyHtml = OOFData.Instance.PrimaryOOFInternalMessage;

            //lastly, disable the permaOOF controls to help with some UI flow issues
            btnPermaOOF.Enabled = false;
            dtPermaOOF.Enabled  = false;
            dtPermaOOF.Value    = DateTime.Now;

            OOFSponderInsights.Track("Configured for primary");
        }
コード例 #9
0
ファイル: O365.cs プロジェクト: karyjac/OOFSponder
        /// <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);
            }
        }
コード例 #10
0
        void Loopy()
        {
            OOFSponderInsights.TrackInfo(OOFSponderInsights.CurrentMethod());
            //Every 10 minutes for automation
            var timer = new System.Timers.Timer(600000);

            timer.Enabled  = true;
            timer.Elapsed += new ElapsedEventHandler(timer_Elapsed);
            timer.Start();
        }
コード例 #11
0
ファイル: OOF.cs プロジェクト: karyjac/OOFSponder
        private void ReadProperties()
        {
            OOFSponderInsights.TrackInfo(OOFSponderInsights.CurrentMethod());

            instance.PermaOOFDate = OOFScheduling.Properties.Settings.Default.PermaOOFDate;
            instance.WorkingHours = OOFScheduling.Properties.Settings.Default.workingHours == baseValue ? string.Empty : Properties.Settings.Default.workingHours;
            instance.PrimaryOOFExternalMessage   = OOFScheduling.Properties.Settings.Default.PrimaryOOFExternal == baseValue ? string.Empty : Properties.Settings.Default.PrimaryOOFExternal;
            instance.PrimaryOOFInternalMessage   = OOFScheduling.Properties.Settings.Default.PrimaryOOFInternal == baseValue ? string.Empty : Properties.Settings.Default.PrimaryOOFInternal;
            instance.SecondaryOOFExternalMessage = OOFScheduling.Properties.Settings.Default.SecondaryOOFExternal == baseValue ? string.Empty : Properties.Settings.Default.SecondaryOOFExternal;
            instance.SecondaryOOFInternalMessage = OOFScheduling.Properties.Settings.Default.SecondaryOOFInternal == baseValue ? string.Empty : Properties.Settings.Default.SecondaryOOFInternal;
        }
コード例 #12
0
ファイル: Program.cs プロジェクト: vivesg/OOFSponder
        static void Main()
        {
            try
            {
                //http://covingtoninnovations.com/mc/SingleInstance.html
                bool gotMutex;
                //GUID is generated using the built-in VS capability
                System.Threading.Mutex m = new System.Threading.Mutex(true, "{6FE49292-F7B3-4EB7-B8F2-0CDDFE20B737}", out gotMutex);

                //http://covingtoninnovations.com/mc/SingleInstance.html
                if (gotMutex)
                {
                    Application.EnableVisualStyles();
                    Application.SetCompatibleTextRenderingDefault(false);
                    Application.Run(new Form1());
                    GC.KeepAlive(m);
                }
                else
                {
                    //http://www.codebetter.com/paullaudeman/2004/07/17/windows-forms-tip-ensure-only-one-instance-of-your-application-is-running-at-a-time/
                    // see if we can find the other app and Bring it to front
                    //NOTE: the link referenced for this specifies a string for the first value, but
                    //I ended up being able to just use the Window name
                    IntPtr hWnd = NativeMethods.FindWindow(null, "OOFSponder");

                    if (hWnd != IntPtr.Zero)
                    {
                        NativeMethods.WINDOWPLACEMENT placement = new NativeMethods.WINDOWPLACEMENT();
                        placement.length = System.Runtime.InteropServices.Marshal.SizeOf(placement);

                        NativeMethods.GetWindowPlacement(hWnd, ref placement);

                        if (placement.showCmd != NativeMethods.SW_MINIMIZE)
                        {
                            placement.showCmd = NativeMethods.SW_RESTORE;

                            NativeMethods.SetWindowPlacement(hWnd, ref placement);
                            NativeMethods.SetForegroundWindow(hWnd);
                        }
                    }

                    return;
                }
            }
            catch (Exception ex)
            {
                OOFSponderInsights.TrackException("Fatal error on startup", ex);
                MessageBox.Show("Uh oh! Fatal error for OOFSponder. Please try again.");
                return;
            }
        }
コード例 #13
0
        private async void btnPermaOOF_Click(object sender, EventArgs e)
        {
            OOFSponderInsights.TrackInfo(OOFSponderInsights.CurrentMethod());

            //bail if permaOOF not in the future
            if (DateTime.Now >= dtPermaOOF.Value)
            {
                MessageBox.Show("You must pick a date in future", "OOFSponder", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            //only set up for permaOOF if we have OOF messages
            if (OOFData.Instance.SecondaryOOFExternalMessage == String.Empty | OOFData.Instance.SecondaryOOFInternalMessage == String.Empty)
            {
                MessageBox.Show("Unable to turn on extended OOF - Secondary OOF messages not set", "OOFSponder", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            bool result = false;

            if (((Button)sender).Tag.ToString() == "Enable")
            {
                OOFData.Instance.PermaOOFDate = dtPermaOOF.Value;
            }
            else
            {
                OOFData.Instance.PermaOOFDate = DateTime.Now;
            }

            //actually go OOF now
            result = await RunSetOofO365();

            if (result)
            {
                if (((Button)sender).Tag.ToString() == "Enable")
                {
                    OOFSponderInsights.Track("Enabled PermaOOF");
                }
                else
                {
                    OOFSponderInsights.Track("Disabled PermaOOF");
                }
            }
            else
            {
                //if we fail to set OOF, disable PermaOOF to reset the UI
                OOFData.Instance.PermaOOFDate = DateTime.Now;
            }

            SetUIforSecondary();
        }
コード例 #14
0
 private void fileToolStripMenuItem_DropDownOpening(object sender, EventArgs e)
 {
     OOFSponderInsights.TrackInfo(OOFSponderInsights.CurrentMethod());
     if (!O365.isLoggedIn)
     {
         saveToolStripMenuItem.Tag  = "LoggedOut";
         saveToolStripMenuItem.Text = "Sign in";
     }
     else
     {
         saveToolStripMenuItem.Tag  = "LoggedIn";
         saveToolStripMenuItem.Text = "Sign out";
     }
 }
コード例 #15
0
 //common call for both controls, regardless of primary or secondary
 private void htmlEditorValidated(object sender, EventArgs e)
 {
     if (radPrimary.Checked)
     {
         OOFSponderInsights.Track("PermaOOF off - persisting primary messages");
         OOFData.Instance.PrimaryOOFExternalMessage = htmlEditorControl1.BodyHtml;
         OOFData.Instance.PrimaryOOFInternalMessage = htmlEditorControl2.BodyHtml;
     }
     else
     {
         OOFSponderInsights.Track("PermaOOF on - persisting secondary messages");
         OOFData.Instance.SecondaryOOFExternalMessage = htmlEditorControl1.BodyHtml;
         OOFData.Instance.SecondaryOOFInternalMessage = htmlEditorControl2.BodyHtml;
     }
 }
コード例 #16
0
        private void radPrimary_CheckedChanged(object sender, EventArgs e)
        {
            OOFSponderInsights.TrackInfo(OOFSponderInsights.CurrentMethod());

            if (radPrimary.Checked)
            {
                //Persist the opposite message
                OOFData.Instance.SecondaryOOFExternalMessage = htmlEditorControl1.BodyHtml;
                OOFData.Instance.SecondaryOOFInternalMessage = htmlEditorControl2.BodyHtml;

                SetUIforPrimary();
            }
            else
            {
                //Persist the opposite message
                OOFData.Instance.PrimaryOOFExternalMessage = htmlEditorControl1.BodyHtml;
                OOFData.Instance.PrimaryOOFInternalMessage = htmlEditorControl2.BodyHtml;

                SetUIforSecondary();
            }
        }
コード例 #17
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();
            }
        }
コード例 #18
0
ファイル: O365.cs プロジェクト: karyjac/OOFSponder
        /// <summary>
        /// Call AcquireTokenAsync - to acquire a token requiring user to sign-in
        /// </summary>
        internal async static Task <bool> MSALWork(AADAction action)
        {
            OOFSponderInsights.TrackInfo(OOFSponderInsights.CurrentMethod());

            bool _result = false;

            if (action == AADAction.SignIn | action == AADAction.ForceSignIn)
            {
                try
                {
                    authResult = await PublicClientApp.AcquireTokenSilentAsync(_scopes, PublicClientApp.Users.FirstOrDefault());
                }
                catch (MsalUiRequiredException ex)
                {
                    // A MsalUiRequiredException happened on AcquireTokenSilentAsync. This indicates you need to call AcquireTokenAsync to acquire a token
                    //Don't track this one since it can basically be considered expected.
                    //OOFSponderInsights.TrackException($"MsalUiRequiredException: {ex.Message}", ex);

                    try
                    {
                        authResult = await PublicClientApp.AcquireTokenAsync(_scopes);
                    }
                    catch (MsalException msalex)
                    {
                        OOFSponderInsights.TrackException("MsalException", new Exception($"Error Acquiring Token:{System.Environment.NewLine}", msalex));
                    }
                }
                catch (Exception ex)
                {
                    OOFSponderInsights.TrackException("Error Acquiring Token Silently", ex);
                    return(false);
                }

                if (PublicClientApp.Users.Count() > 0)
                {
                    //BuddyOptions.authResult = BuddyOptions.authResult;
                    _result = true;

                    //also, update the Application Insights info with the authenticated user
                    OOFSponderInsights.AIClient.Context.User.Id = authResult.User.DisplayableId.Split('@')[0];
                }
                else
                {
                    _result = false;
                }
            }
            else
            {
                if (PublicClientApp.Users.Any())
                {
                    try
                    {
                        PublicClientApp.Remove(PublicClientApp.Users.FirstOrDefault());
                        _result = true;
                    }
                    catch (MsalException ex)
                    {
                        OOFSponder.Logger.Error($"Error signing-out user: {ex.Message}");
                        OOFSponderInsights.TrackException($"Error signing-out user: {ex.Message}", ex);
                    }
                }
            }

            return(_result);
        }
コード例 #19
0
ファイル: O365.cs プロジェクト: EvanBasalik/OOFSponder
        /// <summary>
        /// Call AcquireTokenAsync - to acquire a token requiring user to sign-in
        /// </summary>
        internal async static Task <bool> MSALWork(AADAction action)
        {
            OOFSponder.Logger.Info(OOFSponderInsights.CurrentMethod());

            bool _result = false;

            //lock this so we don't get multiple auth prompts
            OOFSponder.Logger.Info("Attempting to enter critical section for auth code");
            await semaphoreSlim.WaitAsync();

            OOFSponder.Logger.Info("Inside critical section for auth code");

            OOFSponder.Logger.Info("Attempting to build PublicClientApp with multitenant endpoint");
            lock (pcaInitLock)
            {
                PublicClientApp = PublicClientApplicationBuilder.Create(ClientId)
                                  .WithRedirectUri("https://login.microsoftonline.com/common/oauth2/nativeclient")
                                  .WithAuthority(logonUrl)
                                  .Build();

                MSALTokenCacheHelper.EnableSerialization(PublicClientApp.UserTokenCache);
            }

            //grab the logged in user UPN so we can decide whether or not to force the prompt

            try
            {
                Task <IEnumerable <IAccount> > accountTask = PublicClientApp.GetAccountsAsync();
                accountTask.Wait(10000);

                //  give UserTokenCache a go
                IAccount account = null;
                try { account = accountTask.Result.FirstOrDefault(p => p.Username.ToLower() == DefaultUserUPN.ToLower()); } catch (Exception) { }

                if (account != null && account.Username.ToLower() == DefaultUserUPN.ToLower())
                {
                    try
                    {
                        Task <AuthenticationResult> authUITask = PublicClientApp.AcquireTokenSilent(_scopes, account)
                                                                 .ExecuteAsync();
                        authUITask.Wait(10000);
                        authResult = authUITask.Result;
                        if (authResult != null)
                        {
                            OOFSponder.Logger.Info("AcquireTokenSilent -> OK");
                        }
                        _result = true;
                    }
                    catch (Exception x)
                    {
                        OOFSponder.Logger.Error("AcquireTokenSilent -> " + x.GetType().ToString());
                    }
                }
                try
                {
                    Task <AuthenticationResult> authUITask = PublicClientApp.AcquireTokenInteractive(_scopes)
                                                             .WithLoginHint(DefaultUserUPN)
                                                             .WithPrompt(Prompt.NoPrompt)
                                                             .ExecuteAsync();
                    authUITask.Wait(10000);
                    authResult = authUITask.Result;
                    _result    = true;
                }
                catch (Exception ex)
                {
                    if (ex is MsalUiRequiredException || ex.InnerException is MsalUiRequiredException ||
                        ex is MsalClientException || ex.InnerException is MsalClientException ||
                        ex is MsalServiceException || ex.InnerException is MsalServiceException)
                    // MSAL service or client exception here is most likely down to need for UI
                    // even if it is not MsalUiRequiredException
                    {
                        //try
                        //{
                        //    if (!UPN.ToLower().EndsWith("@microsoft.com"))
                        //        throw new Exception("Skip IWA for outsourcer logon");
                        //    Task<AuthenticationResult> authIWATask = PublicClientApp.AcquireTokenByIntegratedWindowsAuth(scopes).ExecuteAsync();
                        //    authIWATask.Wait(10000);
                        //    authResult = authIWATask.Result;
                        //}
                        //catch (Exception ex1)
                        //{
                        try
                        {
                            Task <AuthenticationResult> authUITask = PublicClientApp.AcquireTokenInteractive(_scopes)
                                                                     .WithPrompt(Prompt.NoPrompt)
                                                                     .WithLoginHint(DefaultUserUPN).ExecuteAsync();
                            authUITask.Wait(10000);
                            authResult = authUITask.Result;
                            _result    = true;
                        }
                        catch (Exception ex2)
                        {
                            string _error2 = "GetTokenFromAAD: Failed to get interactive auth token: " + ExceptionChain(ex2);
                            OOFSponder.Logger.Error(new Exception(_error2, ex2));
                        }
                        //}
                    }
                    else
                    {
                        string _error = "GetTokenFromAAD: UI might be required for MSAL logon: " + ExceptionChain(ex);
                        OOFSponder.Logger.Error(new Exception(_error));
                    }
                }
                //}
            }
            catch (Exception ex)
            {
                OOFSponder.Logger.Error(new Exception("Generalized auth failure: ** ", ex));
            }
            finally
            {
                //store the UPN for future use
                if (authResult != null)
                {
                    DefaultUserUPN = authResult.Account.Username;
                }

                //release the critical section we are using to prevent multiple auth prompts
                OOFSponder.Logger.Info("Leaving critical section for auth code");
                semaphoreSlim.Release();
                OOFSponder.Logger.Info("Left critical section for auth code");
            }


            return(_result);
        }
コード例 #20
0
ファイル: Form1.cs プロジェクト: vivesg/OOFSponder
 private void exitToolStripMenuItem_Click(object sender, EventArgs e)
 {
     OOFSponder.Logger.Info(OOFSponderInsights.CurrentMethod());
     minimize = false;
     System.Windows.Forms.Application.Exit();
 }
コード例 #21
0
 private void exitToolStripMenuItem_Click(object sender, EventArgs e)
 {
     OOFSponderInsights.TrackInfo(OOFSponderInsights.CurrentMethod());
     minimize = false;
     Application.Exit();
 }
コード例 #22
0
 private void saveToolStripMenuItem_Click(object sender, EventArgs e)
 {
     OOFSponderInsights.TrackInfo(OOFSponderInsights.CurrentMethod());
     saveSettings();
 }
コード例 #23
0
ファイル: O365.cs プロジェクト: BartonsGit/OOFSponder
        /// <summary>
        /// Call AcquireTokenAsync - to acquire a token requiring user to sign-in
        /// </summary>
        internal async static Task <bool> MSALWork(AADAction action)
        {
            OOFSponder.Logger.Info(OOFSponderInsights.CurrentMethod());

            //lock this so we don't get multiple auth prompts
            OOFSponder.Logger.Info("Attempting to enter critical section for auth code");
            await semaphoreSlim.WaitAsync();

            OOFSponder.Logger.Info("Inside critical section for auth code");

            bool _result  = false;
            var  accounts = await PublicClientApp.GetAccountsAsync();

            var firstAccount = accounts.FirstOrDefault();

            try
            {
                if (action == AADAction.SignIn | action == AADAction.ForceSignIn)
                {
                    try
                    {
                        //MSAL 1.0 style - deprecated
                        //authResult = await PublicClientApp.AcquireTokenSilentAsync(_scopes, PublicClientApp.Users.FirstOrDefault());

                        //MSAL 3.0 style
                        authResult = await PublicClientApp.AcquireTokenSilent(_scopes, firstAccount).ExecuteAsync();
                    }
                    catch (MsalUiRequiredException ex)
                    {
                        // A MsalUiRequiredException happened on AcquireTokenSilentAsync. This indicates you need to call AcquireTokenAsync to acquire a token
                        //Don't track this one since it can basically be considered expected.
                        OOFSponder.Logger.Warning(new Exception($"Unable to acquire token silently: ", ex));

                        try
                        {
                            //MSAL 1.0 style
                            //authResult = await PublicClientApp.AcquireTokenAsync(_scopes);

                            //MSAL 3.0 style
                            authResult = await PublicClientApp.AcquireTokenInteractive(_scopes).ExecuteAsync();
                        }
                        catch (MsalException msalex)
                        {
                            OOFSponder.Logger.Error(new Exception($"Error acquiring token interactively: ", msalex));
                        }
                    }
                    catch (Exception ex)
                    {
                        OOFSponder.Logger.Error(new Exception($"Error acquiring token: ", ex));
                        return(false);
                    }

                    //MSAL 1.0 style
                    //if (PublicClientApp.Users.Count() > 0)

                    //MSAL 3.0 style
                    if (authResult != null)
                    {
                        _result = true;

                        //also, update the Application Insights info with the authenticated user
                        //MSAL 1.0 style
                        //OOFSponderInsights.AIClient.Context.User.Id = authResult.User.DisplayableId.Split('@')[0];

                        //MSAL 3.0 style
                        OOFSponderInsights.AIClient.Context.User.Id = authResult.Account.Username;
                    }
                    else
                    {
                        _result = false;
                    }
                }
                else
                {
                    //MSAL 1.0
                    //if (PublicClientApp.Users.Any())

                    //MSAL 3.0
                    if (firstAccount != null)
                    {
                        try
                        {
                            //MSAL 1.0
                            //PublicClientApp.Remove(PublicClientApp.Users.FirstOrDefault());

                            //MSAL 3.0
                            await PublicClientApp.RemoveAsync(firstAccount);

                            _result = true;
                        }
                        catch (MsalException ex)
                        {
                            OOFSponder.Logger.Error(new Exception("Error signing out user: "******"MSAL code failed miserably for user: "******"Leaving critical section for auth code");
                semaphoreSlim.Release();
                OOFSponder.Logger.Info("Left critical section for auth code");
            }

            return(_result);
        }
コード例 #24
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);
            }
        }
コード例 #25
0
        private async System.Threading.Tasks.Task <bool> RunSetOofO365()
        {
            OOFSponderInsights.TrackInfo(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 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);
        }
コード例 #26
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;
        }