1 // frmNewAccount.cpp - New Account form.
3 // (c) 2012-2015 Xestia Software Development.
5 // This file is part of Xestia Address Book.
7 // Xestia Address Book is free software: you can redistribute it and/or modify
8 // it under the terms of the GNU General Public License as published by the
9 // Free Software Foundation, version 3 of the license.
11 // Xestia Address Book is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
16 // You should have received a copy of the GNU General Public License along
17 // with Xestia Address Book. If not, see <http://www.gnu.org/licenses/>
19 #include "frmNewAccount.h"
22 #include <wx/filefn.h>
23 #include <wx/fileconf.h>
25 #include "carddav/carddav.h"
26 #include "common/dirs.h"
27 #include "common/svrblist.h"
28 #include "frmInvalidSSLCertificate.h"
30 frmNewAccount::frmNewAccount( wxWindow* parent )
32 frmNewAccountADT( parent )
35 // Disable the previous button upon form creation.
37 btnPrevious->Disable();
41 void frmNewAccount::CheckAccountName( wxCommandEvent& event )
44 // Check that the account name is valid.
46 wxString CheckAccName = txtAccountName->GetValue();
48 if ((txtAccountName->IsEmpty() && PageSeek == 2) || CheckAccName.Len() < 4){
60 void frmNewAccount::ProcessPrevious( wxCommandEvent& event )
63 // Go to the previous page.
69 // Currently at the Connection test screen.
74 szrNewAccount->RecalcSizes();
76 btnPrevious->Disable();
79 } else if (PageSeek == 1){
81 if (cmbServerType->GetCurrentSelection() == 0){
87 btnPrevious->Disable();
89 btnNext->SetLabel(_("Next >"));
94 // Currently at the Finish screen.
99 szrNewAccount->RecalcSizes();
101 btnNext->SetLabel(_("Next >"));
108 void frmNewAccount::ProcessNext( wxCommandEvent& event )
111 // Go to the next page or setup the new account.
117 if (cmbServerType->GetCurrentSelection() == 0){
123 btnPrevious->Enable();
124 szrNewAccount->RecalcSizes();
126 btnNext->SetLabel(_("Finish"));
131 // Check if server address matches against the blacklist.
132 // Bring up warning message if it does.
134 if (CheckBlacklist(txtServerAddress->GetValue())){
136 int MessageBoxResult = wxMessageBox(_("The server with the address given does not support the CardDAV protocol properly and shouldn't be used.\n\nData loss is very likely.\n\nDo you still want to continue using this server?"), _("Server warning"), wxYES_NO, this);
138 if (MessageBoxResult == wxNO){
147 bool ServerResult = FALSE;
148 bool ServerAction = FALSE;
150 wxString ServerMessage;
152 // Connection test screen.
157 szrNewAccount->RecalcSizes();
158 btnPrevious->Enable();
162 lblServerConnResult->SetLabel(wxT(""));
163 lblServerResponse->SetLabel(wxT(""));
164 lblServerSSLResult->SetLabel(wxT(""));
165 lblServerSSLValid->SetLabel(wxT(""));
166 lblAbleToLoginResult->SetLabel(wxT(""));
167 lblCardDAVSupportResult->SetLabel(wxT(""));
169 // Spawn a thread and check if server supports CardDAV.
173 lblServerConnResult->SetLabel(_("Testing..."));
175 UseSSL = chkUseSSL->GetValue();
176 CardDAVConn.SetupConnection(txtServerAddress->GetValue(),
177 wxAtoi(txtServerPort->GetValue()),
178 txtUsername->GetValue(),
179 txtPassword->GetValue(),
181 CardDAVConn.SetupResultBools(&ServerResult, &ServerAction);
183 // Verify SSL trust first before doing anything.
187 CURLcode sslcode = CardDAVConn.SSLVerifyTest();
189 if (sslcode == CURLE_OK){
193 } else if (sslcode == CURLE_SSL_CACERT || sslcode == CURLE_SSL_CONNECT_ERROR){
195 // Certificate is more than likely a self-signed or
196 // expired certificate so display the invalid
197 // SSL certificate message.
199 // Setup the data to be sent in the wxPostEvent command.
203 #if defined(__APPLE__)
205 SSLResult = DisplayTrustPanel(&CardDAVConn);
207 if (SSLResult != NSOKButton){
209 lblServerConnResult->SetLabel(_("Failed"));
210 lblServerResponse->SetLabel(_("Not applicable"));
211 lblServerSSLResult->SetLabel(_("Used"));
212 lblServerSSLValid->SetLabel(_("No"));
213 lblConnectionResultText->SetLabel(_("An error occured whilst connnecting: ") + CardDAVConn.GetErrorMessage() + wxString::Format(wxT(" (%i)\n%s"), sslcode, CardDAVConn.GetErrorBuffer().mb_str()));
218 // Evalulate the trust object.
220 SecTrustResultType EvalResult = ProcessResultType(&CardDAVConn);
223 case kSecTrustResultProceed:
224 lblServerSSLValid->SetLabel(_("Verified"));
226 case kSecTrustResultConfirm:
227 lblServerSSLValid->SetLabel(_("Verified (user)"));
230 lblServerSSLValid->SetLabel(_("Unable to verify"));
233 lblServerResponse->SetLabel(_("Not applicable"));
234 lblServerSSLResult->SetLabel(_("Used"));
236 if (EvalResult != kSecTrustResultProceed){
244 frmInvalidSSLCertificate *frmICPtr = new frmInvalidSSLCertificate(this);
246 frmICPtr->LoadDataNew(CardDAVConn.GetSSLVerifyResults(), txtServerAddress->GetValue());
247 frmICPtr->ShowModal();
249 SSLResult = frmICPtr->GetResult();
251 // Clean up before processing response.
256 // Process the response from the user.
260 // Accept the Certificate.
262 CardDAVConn.AllowSelfSignTest(TRUE);
264 } else if (SSLResult == 2){
266 // Reject the certificate, abort the task and mark as failed.
268 lblServerConnResult->SetLabel(_("Failed"));
269 lblConnectionResultText->SetLabel(_("An error occured whilst connnecting: ") + CardDAVConn.GetErrorMessage() + wxString::Format(wxT(" (%i)\n%s"), sslcode, CardDAVConn.GetErrorBuffer().mb_str()));
278 // Something else happened. Stop the process and
279 // display an error message instead.
281 CURLcode sslcode = CardDAVConn.SSLVerifyTest();
283 lblServerConnResult->SetLabel(_("Failed"));
284 lblConnectionResultText->SetLabel(_("An error occured whilst connnecting: ") + CardDAVConn.GetErrorMessage() + wxString::Format(wxT(" (%i)\n%s"), sslcode, CardDAVConn.GetErrorBuffer().mb_str()));
291 std::thread ConnTest(&CardDAV::Connect, &CardDAVConn);
295 if (ServerResult == FALSE){
297 lblServerConnResult->SetLabel(_("Failed"));
298 lblConnectionResultText->SetLabel(_("An error occured whilst connnecting: ") + CardDAVConn.GetErrorMessage());
303 lblServerConnResult->SetLabel(_("Connected"));
307 if (CardDAVConn.CanDoSSL() == TRUE){
309 lblServerSSLResult->SetLabel(_("Used"));
313 lblServerSSLResult->SetLabel(_("Not Used"));
314 lblServerSSLValid->SetLabel(_("Not Applicable"));
318 #if defined(__APPLE__)
320 // Evalulate the trust object.
322 SecTrustResultType EvalResult = ProcessResultType(&CardDAVConn);
325 case kSecTrustResultProceed:
326 lblServerSSLValid->SetLabel(_("Verified"));
328 case kSecTrustResultConfirm:
329 lblServerSSLValid->SetLabel(_("Verified (user)"));
332 lblServerSSLValid->SetLabel(_("Unable to verify"));
337 if (CardDAVConn.SSLVerify() == TRUE && CardDAVConn.CanDoSSL() == TRUE){
339 lblServerSSLValid->SetLabel(_("Verified"));
341 } else if (CardDAVConn.SSLVerify() == FALSE && CardDAVConn.CanDoSSL() == TRUE && CardDAVConn.IsSelfSigned() == TRUE){
343 lblServerSSLValid->SetLabel(_("Verified (user)"));
345 } else if (CardDAVConn.SSLVerify() == FALSE && CardDAVConn.CanDoSSL() == TRUE) {
347 lblServerSSLValid->SetLabel(_("Unable to verify"));
353 if (CardDAVConn.CanDoCardDAV() == TRUE){
355 lblCardDAVSupportResult->SetLabel(_("Supported"));
359 lblCardDAVSupportResult->SetLabel(_("Unsupported"));
360 SetErrorMessageLabel();
365 if (CardDAVConn.AbleToLogin() == TRUE){
367 lblAbleToLoginResult->SetLabel(_("Yes"));
371 lblAbleToLoginResult->SetLabel(_("No"));
372 SetErrorMessageLabel();
377 // Get the address to process CardDAV requests.
379 ServerPrefix = CardDAVConn.GetDefaultAddressBookURL();
381 if (CardDAVConn.HasValidResponse() == TRUE){
383 lblServerResponse->SetLabel(_("Yes"));
387 lblServerResponse->SetLabel(_("No"));
388 SetErrorMessageLabel();
393 if (ServerResult == TRUE && CardDAVConn.HasValidResponse() == TRUE &&
395 CardDAVConn.CanDoCardDAV() == TRUE && CardDAVConn.AbleToLogin() == TRUE){
399 lblConnectionResultText->SetLabel(_("Click on Next to set the account name."));
403 SetErrorMessageLabel();
407 } else if (PageSeek == 2){
414 szrNewAccount->RecalcSizes();
417 btnNext->SetLabel(_("Finish"));
419 if (txtAccountName->IsEmpty() && PageSeek == 2){
429 } else if (PageSeek == 3){
433 wxString XestiaABPrefDirectory;
434 wxString XestiaABDirectory;
435 wxString AccountSettingsFile;
437 wxString RandomNumberSuffix = wxString::Format(wxT("%i"), rand() % 32767);
438 bool DirectoryCreated = FALSE;
440 #if defined(__HAIKU__)
442 //preffilename = wxT("noo");
444 #elif defined(__WIN32__)
446 XestiaABPrefDirectory = GetUserPrefDir();
447 XestiaABDirectory = GetUserDir();
449 AccountSettingsFile = XestiaABPrefDirectory + wxT("accounts");
451 // Open the file for writing.
453 wxFileConfig *cfgfile = new wxFileConfig("", "", AccountSettingsFile);
455 // Check if account name already exists and return an error message
456 // if this is the case.
458 wxString AccountName;
461 ContinueAcc = cfgfile->GetFirstGroup(AccountName, itemindex);
465 if (txtAccountName->GetValue() == AccountName){
467 wxMessageBox(_("The selected account name is already used, please use another account name."), _("Account name already used"), wxICON_ERROR);
472 cfgfile->SetPath(wxT("/"));
473 ContinueAcc = cfgfile->GetNextGroup(AccountName, itemindex);
477 if (cmbServerType->GetCurrentSelection() == 1){
479 // Create the account directory.
481 wxString DirectoryName = txtAccountName->GetValue().Mid(0, 30) + RandomNumberSuffix;
483 if (wxMkdir(XestiaABDirectory + wxT("\\accounts\\") + DirectoryName + wxT(".carddav"), 0740) == TRUE){
485 DirectoryCreated = TRUE;
489 if (DirectoryCreated == TRUE){
491 WriteAccountDetails(cfgfile, wxT("CardDAV"), DirectoryName);
495 wxMessageBox(_("An error occured whilst creating the account directory."), _("Cannot create account directory"));
500 } else if (cmbServerType->GetCurrentSelection() == 0){
502 // Create the account directory.
504 wxString DirectoryName = txtAccountName->GetValue().Mid(0, 30) + RandomNumberSuffix;
506 if (wxMkdir(XestiaABDirectory + wxT("\\accounts\\") + DirectoryName + wxT(".local"), 0740) == TRUE){
508 DirectoryCreated = TRUE;
512 if (DirectoryCreated == TRUE){
514 WriteAccountDetails(cfgfile, wxT("Local"), DirectoryName);
518 wxMessageBox(_("An error occured whilst creating the account directory."), _("Cannot create account directory"));
528 *ReloadAccountConfig = TRUE;
532 XestiaABPrefDirectory = GetUserPrefDir();
533 XestiaABDirectory = GetUserDir();
535 AccountSettingsFile = XestiaABPrefDirectory + wxT("accounts");
537 // Open the file for writing.
539 wxFileConfig *cfgfile = new wxFileConfig("", "", AccountSettingsFile);
541 // Check if account name already exists and return an error message
542 // if this is the case.
544 wxString AccountName;
547 ContinueAcc = cfgfile->GetFirstGroup(AccountName, itemindex);
551 if (txtAccountName->GetValue() == AccountName){
553 wxMessageBox(_("The selected account name is already used, please use another account name."), _("Account name already used"), wxICON_ERROR);
558 cfgfile->SetPath(wxT("/"));
559 ContinueAcc = cfgfile->GetNextGroup(AccountName, itemindex);
563 if (cmbServerType->GetCurrentSelection() == 1){
565 // Create the account directory.
567 wxString DirectoryName = txtAccountName->GetValue().Mid(0, 30) + RandomNumberSuffix;
569 if (wxMkdir(XestiaABDirectory + wxT("/accounts/") + DirectoryName + wxT(".carddav"), 0740) == TRUE){
571 DirectoryCreated = TRUE;
575 if (DirectoryCreated == TRUE){
577 WriteAccountDetails(cfgfile, wxT("CardDAV"), DirectoryName);
581 wxMessageBox(_("An error occured whilst creating the account directory."), _("Cannot create account directory"));
586 } else if (cmbServerType->GetCurrentSelection() == 0){
588 // Create the account directory.
590 wxString DirectoryName = txtAccountName->GetValue().Mid(0, 30) + RandomNumberSuffix;
592 if (wxMkdir(XestiaABDirectory + wxT("/accounts/") + DirectoryName + wxT(".local"), 0740) == TRUE){
594 DirectoryCreated = TRUE;
598 if (DirectoryCreated == TRUE){
600 WriteAccountDetails(cfgfile, wxT("Local"), DirectoryName);
604 wxMessageBox(_("An error occured whilst creating the account directory."), _("Cannot create account directory"));
614 *ReloadAccountConfig = TRUE;
624 void frmNewAccount::WriteAccountDetails(wxFileConfig *cfgfilein, wxString AccountType, wxString DirectoryName){
626 // Write the new account details.
628 cfgfilein->SetPath(txtAccountName->GetValue());
629 cfgfilein->Write(wxT("address"), txtServerAddress->GetValue());
630 cfgfilein->Write(wxT("port"), txtServerPort->GetValue());
631 cfgfilein->Write(wxT("username"), txtUsername->GetValue());
632 cfgfilein->Write(wxT("password"), txtPassword->GetValue());
633 cfgfilein->Write(wxT("prefix"), ServerPrefix);
634 cfgfilein->Write(wxT("accountdir"), DirectoryName);
636 if (chkUseSSL->GetValue() == TRUE){
638 cfgfilein->Write(wxT("ssl"), wxT("true"));
642 cfgfilein->Write(wxT("ssl"), wxT("false"));
646 cfgfilein->Write(wxT("refresh"), wxT("1800"));
647 cfgfilein->Write(wxT("type"), AccountType);
651 void frmNewAccount::CloseWindow( wxCommandEvent& event )
656 *ReloadAccountConfig = FALSE;
661 void frmNewAccount::UpdateRequirements( wxCommandEvent& event )
664 // Update the options.
666 if (cmbServerType->GetCurrentSelection() == 1){
668 txtServerAddress->Enable();
669 txtServerPort->Enable();
670 txtUsername->Enable();
671 txtPassword->Enable();
674 } else if (cmbServerType->GetCurrentSelection() == 0){
676 txtServerAddress->Disable();
677 txtServerPort->Disable();
678 txtUsername->Disable();
679 txtPassword->Disable();
680 chkUseSSL->Disable();
686 void frmNewAccount::SetupPointers(bool *ReloadAccountInc){
688 // Setup the pointers for the new account window.
690 ReloadAccountConfig = ReloadAccountInc;
694 void frmNewAccount::SetErrorMessageLabel(){
696 lblConnectionResultText->SetLabel(_("A problem has occured whilst connecting to the CardDAV server.\nPlease review the above information and change the server details if needed.\nIf there are still problems, please speak to your system administrator(s)."));