Пример #1
0
 /// <summary>
 /// Show message as an alert or in the status bar
 /// </summary>
 /// <param name="msg"></param>
 /// <param name="isStatusMessage"></param>
 private void ShowMessage(string msg, bool isStatusMessage = false)
 {
     if (isStatusMessage)
     {
         m_host.MainWindow.SetStatusEx(Defs.ProductName() + ": " + msg);
     }
     else
     {
         MessageBox.Show(msg, Defs.ProductName());
     }
 }
        private void GoogleOAuthCredentialsForm_Load(object sender, EventArgs e)
        {
            lblTitle.Text   = Defs.ProductName() + " 配置";
            lblVersion.Text = Defs.VersionString();

            cbAccount.Items.Add("自定义 KeePass UUID");
            foreach (PwEntry entry in m_accounts)
            {
                cbAccount.Items.Add(entry.Strings.GetSafe(PwDefs.UserNameField).ReadString() + " - " + entry.Strings.GetSafe(PwDefs.TitleField).ReadString());
            }

            // preselect first account found when not configured
            //if (m_accidx < 0 && m_accounts.UCount > 0)
            //	m_accidx = 0;

            cbAccount.SelectedIndex = m_accidx + 1;
            if (m_accidx >= 0)
            {
                PwEntry entry = m_accounts.GetAt((uint)cbAccount.SelectedIndex - 1);
                txtUuid.Text = entry.Uuid.ToHexString();
                ProtectedString pstr = entry.Strings.Get(Defs.ConfigClientId);
                if (pstr != null)
                {
                    txtClientId.Text = pstr.ReadString();
                }
                pstr = entry.Strings.Get(Defs.ConfigClientSecret);
                if (pstr != null)
                {
                    txtClientSecret.Text = pstr.ReadString();
                }
            }
            txtUuid.Enabled = m_accidx < 0;

            chkOAuth.Checked        = !String.IsNullOrEmpty(txtClientId.Text) || !String.IsNullOrEmpty(txtClientSecret.Text);
            txtClientId.Enabled     = chkOAuth.Checked;
            txtClientSecret.Enabled = chkOAuth.Checked;

            cbAutoSync.SelectedIndex = (int)m_autoSync;
        }
        private void btnOk_Click(object sender, EventArgs e)
        {
            string strUuid = txtUuid.Text.Trim().ToUpper();

            if (String.IsNullOrEmpty(strUuid))
            {
                DialogResult dlgr = MessageBox.Show("从 KeePass 配置中删除 Google 账户关联?", Defs.ProductName(), MessageBoxButtons.YesNoCancel);
                if (DialogResult.Yes != dlgr)
                {
                    DialogResult = DialogResult.None;
                }
                return;
            }

            if (!Regex.IsMatch(strUuid, "^[0-9A-F]{32}$"))
            {
                MessageBox.Show("输入的 UUID 无效!", Defs.ProductName());
                DialogResult = DialogResult.None;
                return;
            }

            if (chkOAuth.Checked && (String.IsNullOrEmpty(txtClientId.Text.Trim()) || String.IsNullOrEmpty(txtClientSecret.Text.Trim())))
            {
                MessageBox.Show("请为 " + Defs.ProductName() + " 输入有效的 Google OAuth 2.0 客户端ID和客户端密匙,或使用默认设置", Defs.ProductName());
                DialogResult = DialogResult.None;
                return;
            }

            m_uuid = strUuid;
            if (chkOAuth.Checked)
            {
                m_clientId     = txtClientId.Text.Trim();
                m_clientSecret = txtClientSecret.Text.Trim();
            }
            m_autoSync = (AutoSyncMode)cbAutoSync.SelectedIndex;
        }
        private void btnOk_Click(object sender, EventArgs e)
        {
            string strUuid = txtUuid.Text.Trim().ToUpper();

            if (String.IsNullOrEmpty(strUuid))
            {
                DialogResult dlgr = MessageBox.Show("Remove Google Account association from KeePass config?", Defs.ProductName(), MessageBoxButtons.YesNoCancel);
                if (DialogResult.Yes != dlgr)
                {
                    DialogResult = DialogResult.None;
                }
                return;
            }

            if (!Regex.IsMatch(strUuid, "^[0-9A-F]{32}$"))
            {
                MessageBox.Show("The entered UUID is not valid.", Defs.ProductName());
                DialogResult = DialogResult.None;
                return;
            }

            if (chkOAuth.Checked && (String.IsNullOrEmpty(txtClientId.Text.Trim()) || String.IsNullOrEmpty(txtClientSecret.Text.Trim())))
            {
                MessageBox.Show("Please enter a valid custom Google OAuth 2.0 Client ID and Client Secrect for " + Defs.ProductName() + " or use default values.", Defs.ProductName());
                DialogResult = DialogResult.None;
                return;
            }

            m_uuid = strUuid;
            if (chkOAuth.Checked)
            {
                m_clientId     = txtClientId.Text.Trim();
                m_clientSecret = txtClientSecret.Text.Trim();
            }
            m_autoSync = (AutoSyncMode)cbAutoSync.SelectedIndex;
        }
Пример #5
0
        /// <summary>
        /// Sync the current database with Google Drive. Create a new file if it does not already exists
        /// </summary>
        private void syncWithGoogle(SyncCommand syncCommand, bool autoSync)
        {
            if (!m_host.Database.IsOpen)
            {
                ShowMessage("你需要先打开一个数据库");
                return;
            }
            else if (!m_host.Database.IOConnectionInfo.IsLocalFile())
            {
                ShowMessage("只支持本地数据库或网络共享数据库。\n" +
                            "将您的数据库保存到本地或网络共享中,再重试。");
                return;
            }

            string status = "请稍后 ...";

            try
            {
                m_host.MainWindow.FileSaved  -= OnFileSaved;                // disable to not trigger when saving ourselves
                m_host.MainWindow.FileOpened -= OnFileOpened;               // disable to not trigger when opening ourselves
                ShowMessage(status, true);
                m_host.MainWindow.Enabled = false;

                // abort when user cancelled or didn't provide config
                if (!GetConfiguration())
                {
                    throw new PlgxException(Defs.ProductName() + " 中止!");
                }

                // Get Access Token / Authorization
                // Invoke async method GetAuthorization from thread pool to have no context to marshal back to
                // and thus making this call synchroneous without running into potential deadlocks.
                // Needed so that KeePass can't close the db or lock the workspace before we are done syncing
                UserCredential myCredential = Task.Run(() => GetAuthorization()).Result;

                // Create a new Google Drive API Service
                DriveService service = new DriveService(new BaseClientService.Initializer()
                {
                    HttpClientInitializer = myCredential,
                    ApplicationName       = "Google Sync Plugin"
                });

                string filePath    = m_host.Database.IOConnectionInfo.Path;
                string contentType = "application/x-keepass2";

                File file = getFile(service, filePath);
                if (file == null)
                {
                    if (syncCommand == SyncCommand.DOWNLOAD)
                    {
                        status = "再 Google Drive 上找不到文件,请先上传或与 Google Drive 同步。";
                    }
                    else                     // upload
                    {
                        if (!autoSync)
                        {
                            m_host.Database.Save(new NullStatusLogger());
                        }
                        status = uploadFile(service, "KeePass 密码安全数据库", string.Empty, contentType, filePath);
                    }
                }
                else
                {
                    if (syncCommand == SyncCommand.UPLOAD)
                    {
                        if (!autoSync)
                        {
                            m_host.Database.Save(new NullStatusLogger());
                        }
                        status = updateFile(service, file, filePath, contentType);
                    }
                    else
                    {
                        string downloadFilePath = downloadFile(service, file, filePath);
                        if (!String.IsNullOrEmpty(downloadFilePath))
                        {
                            if (syncCommand == SyncCommand.DOWNLOAD)
                            {
                                status = replaceDatabase(filePath, downloadFilePath);
                            }
                            else                             // sync
                            {
                                status = String.Format("{0} {1}",
                                                       syncFile(downloadFilePath),
                                                       updateFile(service, file, filePath, contentType));
                            }
                        }
                        else
                        {
                            status = "无法下载文件。";
                        }
                    }
                }
            }
            catch (TokenResponseException ex)
            {
                string msg = string.Empty;
                switch (ex.Error.Error)
                {
                case "access_denied":
                    msg = "访问授权被拒绝";
                    break;

                case "invalid_request":
                    msg = "客户端ID或密匙丢失";
                    break;

                case "invalid_client":
                    msg = "客户端ID或密匙无效";
                    break;

                case "invalid_grant":
                    msg = "提供的密匙无效或过期";
                    break;

                case "unauthorized_client":
                    msg = "未经授权的客户端";
                    break;

                case "unsupported_grant_type":
                    msg = "授权服务器不支持该授权类型";
                    break;

                case "invalid_scope":
                    msg = "请求的范围无效";
                    break;

                default:
                    msg = ex.Message;
                    break;
                }

                status = "ERROR";
                ShowMessage(msg);
            }
            catch (Exception ex)
            {
                status = "ERROR";
                ShowMessage(ex.Message);
            }

            m_host.MainWindow.UpdateUI(false, null, true, null, true, null, false);
            ShowMessage(status, true);
            m_host.MainWindow.Enabled     = true;
            m_host.MainWindow.FileSaved  += OnFileSaved;
            m_host.MainWindow.FileOpened += OnFileOpened;
        }
Пример #6
0
        /// <summary>
        /// The <c>Initialize</c> function is called by KeePass when
        /// you should initialize your plugin (create menu items, etc.).
        /// </summary>
        /// <param name="host">Plugin host interface. By using this
        /// interface, you can access the KeePass main window and the
        /// currently opened database.</param>
        /// <returns>You must return <c>true</c> in order to signal
        /// successful initialization. If you return <c>false</c>,
        /// KeePass unloads your plugin (without calling the
        /// <c>Terminate</c> function of your plugin).</returns>
        public override bool Initialize(IPluginHost host)
        {
            if (host == null)
            {
                return(false);
            }
            m_host = host;

            try
            {
                m_autoSync = (AutoSyncMode)Enum.Parse(typeof(AutoSyncMode), m_host.CustomConfig.GetString(Defs.ConfigAutoSync, AutoSyncMode.DISABLED.ToString()), true);
            }
            catch (Exception)
            {
                // support old boolean value (Sync on Save) (may be removed in later versions)
                if (m_host.CustomConfig.GetBool(Defs.ConfigAutoSync, false))
                {
                    m_autoSync = AutoSyncMode.SAVE;
                }
            }

            // Get a reference to the 'Tools' menu item container
            ToolStripItemCollection tsMenu = m_host.MainWindow.ToolsMenu.DropDownItems;

            // Add a separator at the bottom
            m_tsSeparator = new ToolStripSeparator();
            tsMenu.Add(m_tsSeparator);

            // Add the popup menu item
            m_tsmiPopup      = new ToolStripMenuItem();
            m_tsmiPopup.Text = Defs.ProductName();
            tsMenu.Add(m_tsmiPopup);

            m_tsmiSync        = new ToolStripMenuItem();
            m_tsmiSync.Name   = SyncCommand.SYNC.ToString();
            m_tsmiSync.Text   = "同步";
            m_tsmiSync.Click += OnSyncWithGoogle;
            m_tsmiPopup.DropDownItems.Add(m_tsmiSync);

            m_tsmiUpload        = new ToolStripMenuItem();
            m_tsmiUpload.Name   = SyncCommand.UPLOAD.ToString();
            m_tsmiUpload.Text   = "上传";
            m_tsmiUpload.Click += OnSyncWithGoogle;
            m_tsmiPopup.DropDownItems.Add(m_tsmiUpload);

            m_tsmiDownload        = new ToolStripMenuItem();
            m_tsmiDownload.Name   = SyncCommand.DOWNLOAD.ToString();
            m_tsmiDownload.Text   = "下载";
            m_tsmiDownload.Click += OnSyncWithGoogle;
            m_tsmiPopup.DropDownItems.Add(m_tsmiDownload);

            m_tsmiConfigure        = new ToolStripMenuItem();
            m_tsmiConfigure.Name   = "CONFIG";
            m_tsmiConfigure.Text   = "配置...";
            m_tsmiConfigure.Click += OnConfigure;
            m_tsmiPopup.DropDownItems.Add(m_tsmiConfigure);

            // We want a notification when the user tried to save the
            // current database or opened a new one.
            m_host.MainWindow.FileSaved  += OnFileSaved;
            m_host.MainWindow.FileOpened += OnFileOpened;

            return(true);            // Initialization successful
        }
        /// <summary>
        /// Sync the current database with Google Drive. Create a new file if it does not already exists
        /// </summary>
        private void syncWithGoogle(SyncCommand syncCommand, bool autoSync)
        {
            if (!m_host.Database.IsOpen)
            {
                ShowMessage("You first need to open a database.");
                return;
            }
            else if (!m_host.Database.IOConnectionInfo.IsLocalFile())
            {
                ShowMessage("Only databases stored locally or on a network share are supported.\n" +
                            "Save your database locally or on a network share and try again.");
                return;
            }

            string status = "Please wait ...";

            try
            {
                m_host.MainWindow.FileSaved  -= OnFileSaved;                // disable to not trigger when saving ourselves
                m_host.MainWindow.FileOpened -= OnFileOpened;               // disable to not trigger when opening ourselves
                ShowMessage(status, true);
                m_host.MainWindow.Enabled = false;

                // abort when user cancelled or didn't provide config
                if (!GetConfiguration())
                {
                    throw new PlgxException(Defs.ProductName() + " aborted!");
                }

                // Get Access Token / Authorization
                // Invoke async method GetAuthorization from thread pool to have no context to marshal back to
                // and thus making this call synchroneous without running into potential deadlocks.
                // Needed so that KeePass can't close the db or lock the workspace before we are done syncing
                UserCredential myCredential = Task.Run(() => GetAuthorization()).Result;

                // Create a new Google Drive API Service
                DriveService service = new DriveService(new BaseClientService.Initializer()
                {
                    HttpClientInitializer = myCredential,
                    ApplicationName       = Defs.ProductName()
                });

                string filePath    = m_host.Database.IOConnectionInfo.Path;
                string contentType = "application/x-keepass2";

                File file = getFile(service, filePath);
                if (file == null)
                {
                    if (syncCommand == SyncCommand.DOWNLOAD)
                    {
                        status = "File name not found on Google Drive. Please upload or sync with Google Drive first.";
                    }
                    else                     // upload
                    {
                        if (!autoSync)
                        {
                            m_host.Database.Save(new NullStatusLogger());
                        }
                        status = uploadFile(service, "KeePass Password Safe Database", string.Empty, contentType, filePath);
                    }
                }
                else
                {
                    if (syncCommand == SyncCommand.UPLOAD)
                    {
                        if (!autoSync)
                        {
                            m_host.Database.Save(new NullStatusLogger());
                        }
                        status = updateFile(service, file, filePath, contentType);
                    }
                    else
                    {
                        string downloadFilePath = downloadFile(service, file, filePath);
                        if (!String.IsNullOrEmpty(downloadFilePath))
                        {
                            if (syncCommand == SyncCommand.DOWNLOAD)
                            {
                                status = replaceDatabase(filePath, downloadFilePath);
                            }
                            else                             // sync
                            {
                                status = String.Format("{0} {1}",
                                                       syncFile(downloadFilePath),
                                                       updateFile(service, file, filePath, contentType));
                            }
                        }
                        else
                        {
                            status = "File could not be downloaded.";
                        }
                    }
                }
            }
            catch (TokenResponseException ex)
            {
                string msg = string.Empty;
                switch (ex.Error.Error)
                {
                case "access_denied":
                    msg = "Access authorization request denied.";
                    break;

                case "invalid_request":
                    msg = "Either Client ID or Client Secret is missing.";
                    break;

                case "invalid_client":
                    msg = "Either Client ID or Client Secret is invalid.";
                    break;

                case "invalid_grant":
                    msg = "The provided authorization grant (e.g., authorization code, resource owner credentials) or refresh token is invalid, expired, revoked, does not match the redirection URI used in the authorization request, or was issued to another client.";
                    break;

                case "unauthorized_client":
                    msg = "The authenticated client is not authorized to use this authorization grant type.";
                    break;

                case "unsupported_grant_type":
                    msg = "The authorization grant type is not supported by the authorization server.";
                    break;

                case "invalid_scope":
                    msg = "The requested scope is invalid, unknown, malformed, or exceeds the scope granted by the resource owner.";
                    break;

                default:
                    msg = ex.Message;
                    break;
                }

                status = "ERROR";
                ShowMessage(msg);
            }
            catch (Exception ex)
            {
                status = "ERROR";
                ShowMessage(ex.Message);
            }

            m_host.MainWindow.UpdateUI(false, null, true, null, true, null, false);
            ShowMessage(status, true);
            m_host.MainWindow.Enabled     = true;
            m_host.MainWindow.FileSaved  += OnFileSaved;
            m_host.MainWindow.FileOpened += OnFileOpened;
        }