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.
201 // TODO: Port to OS X.
205 #if defined(__APPLE__)
207 SSLResult = DisplayTrustPanel(&CardDAVConn);
209 if (SSLResult != NSOKButton){
211 lblServerConnResult->SetLabel(_("Failed"));
212 lblServerResponse->SetLabel(_("Not applicable"));
213 lblServerSSLResult->SetLabel(_("Used"));
214 lblServerSSLValid->SetLabel(_("No"));
215 lblConnectionResultText->SetLabel(_("An error occured whilst connnecting: ") + CardDAVConn.GetErrorMessage() + wxString::Format(wxT(" (%i)\n%s"), sslcode, CardDAVConn.GetErrorBuffer().mb_str()));
220 // Evalulate the trust object.
222 SecTrustResultType EvalResult = ProcessResultType(&CardDAVConn);
225 case kSecTrustResultProceed:
226 lblServerSSLValid->SetLabel(_("Verified"));
228 case kSecTrustResultConfirm:
229 lblServerSSLValid->SetLabel(_("Verified (user)"));
232 lblServerSSLValid->SetLabel(_("Unable to verify"));
235 lblServerResponse->SetLabel(_("Not applicable"));
236 lblServerSSLResult->SetLabel(_("Used"));
238 if (EvalResult != kSecTrustResultProceed){
246 frmInvalidSSLCertificate *frmICPtr = new frmInvalidSSLCertificate(this);
248 frmICPtr->LoadDataNew(CardDAVConn.GetSSLVerifyResults(), txtServerAddress->GetValue());
249 frmICPtr->ShowModal();
251 SSLResult = frmICPtr->GetResult();
253 // Clean up before processing response.
258 // Process the response from the user.
262 // Accept the Certificate.
264 CardDAVConn.AllowSelfSignTest(TRUE);
266 } else if (SSLResult == 2){
268 // Reject the certificate, abort the task and mark as failed.
270 lblServerConnResult->SetLabel(_("Failed"));
271 lblConnectionResultText->SetLabel(_("An error occured whilst connnecting: ") + CardDAVConn.GetErrorMessage() + wxString::Format(wxT(" (%i)\n%s"), sslcode, CardDAVConn.GetErrorBuffer().mb_str()));
280 // Something else happened. Stop the process and
281 // display an error message instead.
283 CURLcode sslcode = CardDAVConn.SSLVerifyTest();
285 lblServerConnResult->SetLabel(_("Failed"));
286 lblConnectionResultText->SetLabel(_("An error occured whilst connnecting: ") + CardDAVConn.GetErrorMessage() + wxString::Format(wxT(" (%i)\n%s"), sslcode, CardDAVConn.GetErrorBuffer().mb_str()));
293 std::thread ConnTest(&CardDAV::Connect, &CardDAVConn);
297 if (ServerResult == FALSE){
299 lblServerConnResult->SetLabel(_("Failed"));
300 lblConnectionResultText->SetLabel(_("An error occured whilst connnecting: ") + CardDAVConn.GetErrorMessage());
305 lblServerConnResult->SetLabel(_("Connected"));
309 if (CardDAVConn.CanDoSSL() == TRUE){
311 lblServerSSLResult->SetLabel(_("Used"));
315 lblServerSSLResult->SetLabel(_("Not Used"));
316 lblServerSSLValid->SetLabel(_("Not Applicable"));
320 #if defined(__APPLE__)
322 // Evalulate the trust object.
324 SecTrustResultType EvalResult = ProcessResultType(&CardDAVConn);
327 case kSecTrustResultProceed:
328 lblServerSSLValid->SetLabel(_("Verified"));
330 case kSecTrustResultConfirm:
331 lblServerSSLValid->SetLabel(_("Verified (user)"));
334 lblServerSSLValid->SetLabel(_("Unable to verify"));
339 if (CardDAVConn.SSLVerify() == TRUE && CardDAVConn.CanDoSSL() == TRUE){
341 lblServerSSLValid->SetLabel(_("Verified"));
343 } else if (CardDAVConn.SSLVerify() == FALSE && CardDAVConn.CanDoSSL() == TRUE && CardDAVConn.IsSelfSigned() == TRUE){
345 lblServerSSLValid->SetLabel(_("Verified (user)"));
347 } else if (CardDAVConn.SSLVerify() == FALSE && CardDAVConn.CanDoSSL() == TRUE) {
349 lblServerSSLValid->SetLabel(_("Unable to verify"));
355 if (CardDAVConn.CanDoCardDAV() == TRUE){
357 lblCardDAVSupportResult->SetLabel(_("Supported"));
361 lblCardDAVSupportResult->SetLabel(_("Unsupported"));
362 SetErrorMessageLabel();
367 if (CardDAVConn.AbleToLogin() == TRUE){
369 lblAbleToLoginResult->SetLabel(_("Yes"));
373 lblAbleToLoginResult->SetLabel(_("No"));
374 SetErrorMessageLabel();
379 // Get the address to process CardDAV requests.
381 ServerPrefix = CardDAVConn.GetDefaultAddressBookURL();
383 if (CardDAVConn.HasValidResponse() == TRUE){
385 lblServerResponse->SetLabel(_("Yes"));
389 lblServerResponse->SetLabel(_("No"));
390 SetErrorMessageLabel();
395 if (ServerResult == TRUE && CardDAVConn.HasValidResponse() == TRUE &&
397 CardDAVConn.CanDoCardDAV() == TRUE && CardDAVConn.AbleToLogin() == TRUE){
401 lblConnectionResultText->SetLabel(_("Click on Next to set the account name."));
405 SetErrorMessageLabel();
409 } else if (PageSeek == 2){
416 szrNewAccount->RecalcSizes();
419 btnNext->SetLabel(_("Finish"));
421 if (txtAccountName->IsEmpty() && PageSeek == 2){
431 } else if (PageSeek == 3){
435 wxString XestiaABPrefDirectory;
436 wxString XestiaABDirectory;
437 wxString AccountSettingsFile;
439 wxString RandomNumberSuffix = wxString::Format(wxT("%i"), rand() % 32767);
440 bool DirectoryCreated = FALSE;
442 #if defined(__HAIKU__)
444 //preffilename = wxT("noo");
446 #elif defined(__WIN32__)
448 XestiaABPrefDirectory = GetUserPrefDir();
449 XestiaABDirectory = GetUserDir();
451 AccountSettingsFile = XestiaABPrefDirectory + wxT("accounts");
453 // Open the file for writing.
455 wxFileConfig *cfgfile = new wxFileConfig("", "", AccountSettingsFile);
457 // Check if account name already exists and return an error message
458 // if this is the case.
460 wxString AccountName;
463 ContinueAcc = cfgfile->GetFirstGroup(AccountName, itemindex);
467 if (txtAccountName->GetValue() == AccountName){
469 wxMessageBox(_("The selected account name is already used, please use another account name."), _("Account name already used"), wxICON_ERROR);
474 cfgfile->SetPath(wxT("/"));
475 ContinueAcc = cfgfile->GetNextGroup(AccountName, itemindex);
479 if (cmbServerType->GetCurrentSelection() == 1){
481 // Create the account directory.
483 wxString DirectoryName = txtAccountName->GetValue().Mid(0, 30) + RandomNumberSuffix;
485 if (wxMkdir(XestiaABDirectory + wxT("\\accounts\\") + DirectoryName + wxT(".carddav"), 0740) == TRUE){
487 DirectoryCreated = TRUE;
491 if (DirectoryCreated == TRUE){
493 WriteAccountDetails(cfgfile, wxT("CardDAV"), DirectoryName);
497 wxMessageBox(_("An error occured whilst creating the account directory."), _("Cannot create account directory"));
502 } else if (cmbServerType->GetCurrentSelection() == 0){
504 // Create the account directory.
506 wxString DirectoryName = txtAccountName->GetValue().Mid(0, 30) + RandomNumberSuffix;
508 if (wxMkdir(XestiaABDirectory + wxT("\\accounts\\") + DirectoryName + wxT(".local"), 0740) == TRUE){
510 DirectoryCreated = TRUE;
514 if (DirectoryCreated == TRUE){
516 WriteAccountDetails(cfgfile, wxT("Local"), DirectoryName);
520 wxMessageBox(_("An error occured whilst creating the account directory."), _("Cannot create account directory"));
530 *ReloadAccountConfig = TRUE;
534 XestiaABPrefDirectory = GetUserPrefDir();
535 XestiaABDirectory = GetUserDir();
537 AccountSettingsFile = XestiaABPrefDirectory + wxT("accounts");
539 // Open the file for writing.
541 wxFileConfig *cfgfile = new wxFileConfig("", "", AccountSettingsFile);
543 // Check if account name already exists and return an error message
544 // if this is the case.
546 wxString AccountName;
549 ContinueAcc = cfgfile->GetFirstGroup(AccountName, itemindex);
553 if (txtAccountName->GetValue() == AccountName){
555 wxMessageBox(_("The selected account name is already used, please use another account name."), _("Account name already used"), wxICON_ERROR);
560 cfgfile->SetPath(wxT("/"));
561 ContinueAcc = cfgfile->GetNextGroup(AccountName, itemindex);
565 if (cmbServerType->GetCurrentSelection() == 1){
567 // Create the account directory.
569 wxString DirectoryName = txtAccountName->GetValue().Mid(0, 30) + RandomNumberSuffix;
571 if (wxMkdir(XestiaABDirectory + wxT("/accounts/") + DirectoryName + wxT(".carddav"), 0740) == TRUE){
573 DirectoryCreated = TRUE;
577 if (DirectoryCreated == TRUE){
579 WriteAccountDetails(cfgfile, wxT("CardDAV"), DirectoryName);
583 wxMessageBox(_("An error occured whilst creating the account directory."), _("Cannot create account directory"));
588 } else if (cmbServerType->GetCurrentSelection() == 0){
590 // Create the account directory.
592 wxString DirectoryName = txtAccountName->GetValue().Mid(0, 30) + RandomNumberSuffix;
594 if (wxMkdir(XestiaABDirectory + wxT("/accounts/") + DirectoryName + wxT(".local"), 0740) == TRUE){
596 DirectoryCreated = TRUE;
600 if (DirectoryCreated == TRUE){
602 WriteAccountDetails(cfgfile, wxT("Local"), DirectoryName);
606 wxMessageBox(_("An error occured whilst creating the account directory."), _("Cannot create account directory"));
616 *ReloadAccountConfig = TRUE;
626 void frmNewAccount::WriteAccountDetails(wxFileConfig *cfgfilein, wxString AccountType, wxString DirectoryName){
628 // Write the new account details.
630 cfgfilein->SetPath(txtAccountName->GetValue());
631 cfgfilein->Write(wxT("address"), txtServerAddress->GetValue());
632 cfgfilein->Write(wxT("port"), txtServerPort->GetValue());
633 cfgfilein->Write(wxT("username"), txtUsername->GetValue());
634 cfgfilein->Write(wxT("password"), txtPassword->GetValue());
635 cfgfilein->Write(wxT("prefix"), ServerPrefix);
636 cfgfilein->Write(wxT("accountdir"), DirectoryName);
638 if (chkUseSSL->GetValue() == TRUE){
640 cfgfilein->Write(wxT("ssl"), wxT("true"));
644 cfgfilein->Write(wxT("ssl"), wxT("false"));
648 cfgfilein->Write(wxT("refresh"), wxT("1800"));
649 cfgfilein->Write(wxT("type"), AccountType);
653 void frmNewAccount::CloseWindow( wxCommandEvent& event )
658 *ReloadAccountConfig = FALSE;
663 void frmNewAccount::UpdateRequirements( wxCommandEvent& event )
666 // Update the options.
668 if (cmbServerType->GetCurrentSelection() == 1){
670 txtServerAddress->Enable();
671 txtServerPort->Enable();
672 txtUsername->Enable();
673 txtPassword->Enable();
676 } else if (cmbServerType->GetCurrentSelection() == 0){
678 txtServerAddress->Disable();
679 txtServerPort->Disable();
680 txtUsername->Disable();
681 txtPassword->Disable();
682 chkUseSSL->Disable();
688 void frmNewAccount::SetupPointers(bool *ReloadAccountInc){
690 // Setup the pointers for the new account window.
692 ReloadAccountConfig = ReloadAccountInc;
696 void frmNewAccount::SetErrorMessageLabel(){
698 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)."));