Home | News | Projects | Releases
Bugs | RFE | Repositories | Help
frmNewAccount: Implemented support for adding a CalDAV account
[xestiacalendar/.git] / source / forms / newaccount / frmNewAccount.cpp
1 // frmNewAccount.cpp - frmNewAccount form functions
2 //
3 // (c) 2016-2017 Xestia Software Development.
4 //
5 // This file is part of Xestia Calendar.
6 //
7 // Xestia Calendar 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.
10 //
11 // Xestia Calendar 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.
15 //
16 // You should have received a copy of the GNU General Public License along
17 // with Xestia Calendar. If not, see <http://www.gnu.org/licenses/>
19 #include "frmNewAccount.h"
21 DEFINE_EVENT_TYPE(UPDATERESULTS);
22 DEFINE_EVENT_TYPE(RUNCALDAVTEST);
24 BEGIN_EVENT_TABLE(frmNewAccount, wxDialog)
25 EVT_COMMAND(wxID_ANY, UPDATERESULTS, frmNewAccount::UpdateResults)
26 EVT_COMMAND(wxID_ANY, RUNCALDAVTEST, frmNewAccount::RunCalDAVTest)
27 END_EVENT_TABLE()
29 frmNewAccount::frmNewAccount( wxWindow* parent )
30 :
31 frmNewAccountADT( parent )
32 {
34         // Disable the previous button upon form creation.
36         btnPrevious->Disable();
37         txtServerAddress->Disable();
38         txtServerPort->Disable();
39         txtUsername->Disable();
40         txtPassword->Disable();
41         chkUseSSL->Disable();
42         
43 }
45 void frmNewAccount::UpdateRequirements( wxCommandEvent& event )
46 {
47         // Update the options.
48     
49         if (cmbServerType->GetCurrentSelection() == 1){
50         
51                 txtServerAddress->Enable();
52                 txtServerPort->Enable();
53                 txtUsername->Enable();
54                 txtPassword->Enable();
55                 chkUseSSL->Enable();
56         
57         } else if (cmbServerType->GetCurrentSelection() == 0){
58         
59                 txtServerAddress->Disable();
60                 txtServerPort->Disable();
61                 txtUsername->Disable();
62                 txtPassword->Disable();
63                 chkUseSSL->Disable();
64         
65         }
66 }
68 void frmNewAccount::Navigate( wxCommandEvent& event )
69 {
71         if (event.GetId() == wxID_NEXT)
72                 pageSeek++;
73         else
74                 pageSeek--;
75     
76         if (pageSeek == 1){
77         
78                 // Skip this page.
80                 btnPrevious->Disable();
81                 btnNext->Enable();
83                 tabConn->Hide();
84                 tabFinish->Hide();
85                 tabType->Show();
86                 btnNext->SetLabel(_("Next >"));
87         
88         } else if (pageSeek == 2){
89         
90                 if (cmbServerType->GetCurrentSelection() == 0){
91             
92                         tabType->Hide();
93                         tabConn->Hide();
94                         tabFinish->Show();
95                         szrNewAccount->RecalcSizes();
96                         pageSeek = 2;
97                         
98                         btnNext->Disable();
99                         btnPrevious->Enable();
100                         btnNext->SetLabel(_("Finish"));
101                         return;
102             
103                 }
104                 
105                 // Check if server address matches against the blacklist.
106                 // Bring up warning message if it does.
107                 
108                 if (CheckBlacklist(txtServerAddress->GetValue())){
109                 
110                         int MessageBoxResult = wxMessageBox(_("The server with the address given does not support the CalDAV 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);
111                 
112                         if (MessageBoxResult == wxNO){
113                                 pageSeek--;
114                                 return;
115                         }
116                         
117                 }
118                 
119                 btnNext->Disable();
120                 btnNext->SetLabel(_("Next >"));
121         
122                 bool ServerResult = FALSE;
123                 bool ServerAction = FALSE;
124                 bool UseSSL = TRUE;
125                 wxString ServerMessage;
126         
127                 // Connection test screen.
128         
129                 tabType->Hide();
130                 tabConn->Show();
131                 tabFinish->Hide();
132                 szrNewAccount->RecalcSizes();
133                 btnPrevious->Disable();
134         
135                 // Reset screen.
136         
137                 lblServerConnResult->SetLabel(wxT(""));
138                 lblServerResponse->SetLabel(wxT(""));
139                 lblServerSSLResult->SetLabel(wxT(""));
140                 lblServerSSLValid->SetLabel(wxT(""));
141                 lblAbleToLoginResult->SetLabel(wxT(""));
142                 lblCalDAVSupportResult->SetLabel(wxT(""));
143         
144                 // Depending on account type, run the test.
145         
146                 if (cmbServerType->GetCurrentSelection() == 1){
147                         wxCommandEvent RunTest(RUNCALDAVTEST);
148                         wxPostEvent(this, RunTest);
149                 }
150         
151         } else if (pageSeek == 3){
152         
153                 // Finish screen.
154         
155                 tabType->Hide();
156                 tabConn->Hide();
157                 tabFinish->Show();
158                 szrNewAccount->RecalcSizes();
160                 btnPrevious->Enable();
161                 btnNext->SetLabel(_("Finish"));
162         
163                 if (txtAccountName->IsEmpty() || txtAccountName->GetValue().Len() < 4 && pageSeek == 3){
164         
165                         btnNext->Disable();
166             
167                 } else {
168         
169                         btnNext->Enable();
170             
171                 }
172         
173         } else if (pageSeek == 4){
174         
175                 // Finished.
176         
177                 wxString xestiaCALPrefDirectory;
178                 wxString xestiaCALDirectory;
179                 wxString accountSettingsFile;
180                 //wxFile ASFile;
181                 
182                 srand(time(0));
183                 int randomNumber = rand() % 32767;
184                 wxString randomNumberSuffix = wxString::Format(wxT("%i"), randomNumber);
185                 bool directoryCreated = FALSE;
186         
187 #if defined(__HAIKU__)
188         
189                 //preffilename = wxT("noo");
190         
191 #elif defined(__WIN32__)
192         
193                 xestiaCALPrefDirectory = GetUserPrefDir();
194                 xestiaCALDirectory = GetUserDir();
195         
196                 accountSettingsFile = xestiaCALPrefDirectory + wxT("accounts");
197         
198                 // Open the file for writing.
199         
200                 wxFileConfig *cfgFile = new wxFileConfig("", "", accountSettingsFile);
201         
202                 // Check if account name already exists and return an error message
203                 // if this is the case.
204         
205                 wxString accountName;
206                 long itemIndex = 0;
207                 bool continueAcc;
208                 continueAcc = cfgFile->GetFirstGroup(accountName, itemIndex);
209         
210                 while (continueAcc){
211             
212                         if (txtAccountName->GetValue() == accountName){
213                 
214                                 wxMessageBox(_("The selected account name is already used, please use another account name."), _("Account name already used"), wxICON_ERROR);
215                                 return;
216                 
217                         }
218             
219                         cfgFile->SetPath(wxT("/"));
220                         continueAcc = cfgFile->GetNextGroup(accountName, itemIndex);
221             
222                 }
223         
224                 wxString directoryName = txtAccountName->GetValue().Mid(0, 30) + randomNumberSuffix;
225         
226                 if (cmbServerType->GetCurrentSelection() == 0){
227             
228                         // Create the account directory.
229             
230                         if (wxMkdir(xestiaCALDirectory + wxT("\\accounts\\") + directoryName + wxT(".local"), 0740) == true){
231                 
232                                 WriteAccountDetails(cfgFile, wxT("Local"), directoryName);
233                 
234                         } else {
235                 
236                                 wxMessageBox(_("An error occured whilst creating the account directory."), _("Cannot create account directory"));
237                                 return;
238                 
239                         }
240             
241                 } else if (cmbServerType->GetCurrentSelection() == 1){
242                                                 
243                         // Create the account directory.
244             
245                         if (wxMkdir(xestiaCALDirectory + wxT("\\accounts\\") + directoryName + wxT(".caldav"), 0740) == true){
246                 
247                                 WriteAccountDetails(cfgFile, wxT("CalDAV"), directoryName);
248                 
249                         } else {
250                 
251                                 wxMessageBox(_("An error occured whilst creating the account directory."), _("Cannot create account directory"));
252                                 return;
253                 
254                         }
255                         
256                 }
257         
258                 delete cfgFile;
259                 cfgFile = NULL;
260         
261                 *reloadAccountConfig = TRUE;
262         
263 #else
264         
265                 xestiaCALPrefDirectory = GetUserPrefDir();
266                 xestiaCALDirectory = GetUserDir();
267         
268                 accountSettingsFile = xestiaCALPrefDirectory + wxT("accounts");
269         
270                 // Open the file for writing.
271         
272                 wxFileConfig *cfgFile = new wxFileConfig("", "", accountSettingsFile);
273         
274                 // Check if account name already exists and return an error message
275                 // if this is the case.
276         
277                 wxString accountName;
278                 long itemIndex = 0;
279                 bool continueAcc;
280                 continueAcc = cfgFile->GetFirstGroup(accountName, itemIndex);
281         
282                 while (continueAcc){
283             
284                         if (txtAccountName->GetValue() == accountName){
285                 
286                                 wxMessageBox(_("The selected account name is already used, please use another account name."), _("Account name already used"), wxICON_ERROR);
287                                 return;
288                 
289                         }
290             
291                         cfgFile->SetPath(wxT("/"));
292                         continueAcc = cfgFile->GetNextGroup(accountName, itemIndex);
293             
294                 }
296                 wxString directoryName = txtAccountName->GetValue().Mid(0, 30) + randomNumberSuffix;
297         
298                 if (cmbServerType->GetCurrentSelection() == 0){
299             
300                         // Create the account directory.
301             
302                         if (wxMkdir(xestiaCALDirectory + wxT("/accounts/") + directoryName + wxT(".Local"), 0740) == true){
303                 
304                                 WriteAccountDetails(cfgFile, wxT("Local"), directoryName);
305                         
306                         } else {
307                 
308                                 wxMessageBox(_("An error occured whilst creating the account directory."), _("Cannot create account directory"));
309                                 return;
310                 
311                         }
312             
313                 } else if (cmbServerType->GetCurrentSelection() == 1){
314             
315                         // Create the account directory.
316             
317                         wxString directoryName = txtAccountName->GetValue().Mid(0, 30) + randomNumberSuffix;
318             
319                         if (wxMkdir(xestiaCALDirectory + wxT("/accounts/") + directoryName + wxT(".caldav"), 0740) == true){
320                 
321                                 WriteAccountDetails(cfgFile, wxT("CalDAV"), directoryName);
322                         
323                         } else {
324                 
325                                 wxMessageBox(_("An error occured whilst creating the account directory."), _("Cannot create account directory"));
326                                 return;
327                 
328                         }
329             
330                 }
331         
332                 delete cfgFile;
333                 cfgFile = nullptr;
334         
335                 *reloadAccountConfig = true;
336                 
337 #endif
338         
339                 this->Close();
340         
341         }
342         
345 void frmNewAccount::CloseWindow( wxCommandEvent& event )
347         
348         // Close the window.
350         *reloadAccountConfig = FALSE;
351         this->Close();
352         
355 void frmNewAccount::SetupPointers(bool *ReloadAccountInc, CalendarDataStorage *dataStorage){
357         // Setup the pointers for the new account window.
358    
359         reloadAccountConfig = ReloadAccountInc;
360     
363 void frmNewAccount::CheckAccountName( wxCommandEvent& event )
365     
366         // Check that the account name is valid.
367     
368         wxString checkAccName = txtAccountName->GetValue();
369     
370         if ((txtAccountName->IsEmpty() && pageSeek == 2) || checkAccName.Len() < 4){
371         
372                 btnNext->Disable();
373         
374         } else {
375         
376                 btnNext->Enable();
377         
378         }
379     
382 void frmNewAccount::WriteAccountDetails(wxFileConfig *cfgFileIn, wxString accountType, wxString directoryName){
383     
384         // Write the new account details.
385     
386         cfgFileIn->SetPath(txtAccountName->GetValue());
387         cfgFileIn->Write(wxT("address"), txtServerAddress->GetValue());
388         cfgFileIn->Write(wxT("port"), txtServerPort->GetValue());
389         cfgFileIn->Write(wxT("username"), txtUsername->GetValue());
390         cfgFileIn->Write(wxT("password"), txtPassword->GetValue());
391         cfgFileIn->Write(wxT("prefix"), serverPrefix);
392         cfgFileIn->Write(wxT("accountdir"), directoryName);
393     
394         if (chkUseSSL->GetValue() == TRUE){
395         
396                 cfgFileIn->Write(wxT("ssl"), wxT("true"));
397         
398         } else {
399         
400                 cfgFileIn->Write(wxT("ssl"), wxT("false"));
401         
402         }
403     
404         cfgFileIn->Write(wxT("refresh"), wxT("1800"));
405         cfgFileIn->Write(wxT("type"), accountType);
406     
409 void frmNewAccount::UpdateResults( wxCommandEvent &event )
411         NewAccountResult *resultData = static_cast<NewAccountResult*>(event.GetClientData());
413         lblServerConnResult->SetLabel((resultData->Connected ? _("Successful") : _("Failed")));
414         lblServerResponse->SetLabel((resultData->ValidResponse ? _("Yes") : _("No")));
415         if (chkUseSSL->GetValue())
416         {
417                 lblServerSSLResult->SetLabel((resultData->SSLStatus ? _("Yes") : _("No")));
418                 lblServerSSLValid->SetLabel((resultData->SSLVerified == COSSL_VERIFIED ? _("Yes") : _("No")));
419         } else {
420                 lblServerSSLResult->SetLabel(_("Not Applicable"));
421                 lblServerSSLValid->SetLabel(_("Not Applicable"));
422         }
423         lblAbleToLoginResult->SetLabel((resultData->AuthPassed ? _("Yes") : _("No")));
424         lblCalDAVSupportResult->SetLabel((resultData->CanProcess ? _("Yes") : _("No")));
425         
426         if (resultData->ErrorMessage != "")
427         {
428                 lblConnectionResultText->SetLabel(_("An error occured whilst connecting to the server: ") + resultData->ErrorMessage);
429         }
430         
431         if (VerifyResultData(resultData))
432         {
433                 lblConnectionResultText->SetLabel(_("Successfully connected to the server. Press Next to set the account name."));
434                 btnNext->Enable(true);
435         }
436         else
437         {
438                 btnNext->Enable(false);
439         }
440         
441         tabConn->Layout();
442         btnPrevious->Enable(true);
443         
444         delete resultData;
445         resultData = nullptr;
448 bool frmNewAccount::VerifyResultData(NewAccountResult *resultData)
450         if (!resultData->Connected) return false;
451         if (!resultData->ValidResponse) return false;
452         if (chkUseSSL->GetValue())
453         {
454                 if (!resultData->SSLStatus) return false;
455                 if (resultData->SSLVerified != COSSL_VERIFIED) return false;
456         }
457         if (!resultData->AuthPassed) return false;
458         if (!resultData->CanProcess) return false;
459         
460         return true;
463 void frmNewAccount::RunCalDAVTest( wxCommandEvent &event )
465         NewAccountResult *resultData = new NewAccountResult;
466         
467         lblServerConnResult->SetLabel(_("Testing..."));
468         lblCalDAVSupportResult->SetLabel(wxT(""));
469         lblServerResponse->SetLabel(wxT(""));
470         lblServerSSLResult->SetLabel(wxT(""));
471         lblServerSSLValid->SetLabel(wxT(""));
472         lblAbleToLoginResult->SetLabel(wxT(""));
473         lblConnectionResultText->SetLabel(wxT(""));
474         bool usingSSLBypass = false;
475         
476         // Setup a CalDAV connection object for testing.
478         CalDAVConnectionData connData;
479         connData.hostname = txtServerAddress->GetValue().ToStdString();
480         connData.port = wxAtoi(txtServerPort->GetValue());
481         connData.username = txtUsername->GetValue().ToStdString();
482         connData.password = txtPassword->GetValue().ToStdString();
483         connData.useSSL = chkUseSSL->GetValue() ? true : false;
485         CalDAV testConnection;
486         testConnection.SetupConnectionData(&connData);
488         /*CardDAV2 TestConnection(txtServerAddress->GetValue().ToStdString(),
489                 wxAtoi(txtServerPort->GetValue()),
490                 txtUsername->GetValue().ToStdString(),
491                 txtPassword->GetValue().ToStdString(),
492                 chkUseSSL->GetValue() ? true : false);*/
493         
494         // Test the connection.
495         
496         //testConnection.SetupConnectionObject();
497         CalDAVServerResult testConnectionResult = testConnection.Connect(false);
498         
499         // If server is using SSL, verify that the SSL connection is valid.
500         
501         if (testConnection.SSLVerify() == COSSL_UNABLETOVERIFY){
502 #if defined(__APPLE__)
503                 
504                 testConnection.BypassSSLVerification(true);
505                 
506                 CalDAVServerResult testConnection = testConnection.Connect(false);
507                 
508                 testConnection.BypassSSLVerification(false);
509                 
510                 int SSLResult = DisplayTrustPanel(&TestConnection);
511                 
512                 if (SSLResult != NSOKButton){
513                         
514                         lblServerConnResult->SetLabel(_("Failed"));
515                         lblServerResponse->SetLabel(_("Not applicable"));
516                         lblServerSSLResult->SetLabel(_("Used"));
517                         lblServerSSLValid->SetLabel(_("No"));
518                         lblConnectionResultText->SetLabel(_("An error occured whilst connnecting: ") + TestConnection.GetErrorMessage());
519                         btnPrevious->Enable(true);
520                         return;
521                         
522                 } else {
523                         
524                         // Evalulate the trust object.
525                         
526                         SecTrustResultType evalResult = ProcessResultType(&testConnection);
527                         
528                         switch(evalResult){
529                                 case kSecTrustResultProceed:
530                                         lblServerSSLValid->SetLabel(_("Verified"));
531                                         break;
532                                 case kSecTrustResultConfirm:
533                                         lblServerSSLValid->SetLabel(_("Verified (user)"));
534                                         break;
535                                 default:
536                                         lblServerSSLValid->SetLabel(_("Unable to verify"));
537                         }
538                         
539                         lblServerResponse->SetLabel(_("Not applicable"));
540                         lblServerSSLResult->SetLabel(_("Used"));
541                         
542                         if (evalResult != kSecTrustResultProceed){
543                                 return;
544                         }
545                         
546                 }
547                 
548 #elif defined(__WIN32__)
550                 testConnection.BypassSSLVerification(true);
552                 CalDAVServerResult testConnectionResult = testConnection.Connect(false);
554                 testConnection.BypassSSLVerification(false);
556                 bool modifiedCertificateData = false;
558                 CRYPTUI_VIEWCERTIFICATE_STRUCTW certificateDialogData = BuildCertificateData(&testConnection, (HWND)this->GetHandle());
560                 if (!CryptUIDlgViewCertificate(&certificateDialogData, &modifiedCertificateData)){
561                         wxMessageBox(_("An error occured while trying to open the certificate dialog."), _("Error opening Certificate Information dialog"));
562                 }
564                 if (modifiedCertificateData == false){
566                         lblServerConnResult->SetLabel(_("Failed"));
567                         lblServerResponse->SetLabel(_("Not applicable"));
568                         lblServerSSLResult->SetLabel(_("Used"));
569                         lblServerSSLValid->SetLabel(_("No"));
570                         lblConnectionResultText->SetLabel(_("An error occured whilst connnecting: ") + testConnection.GetErrorMessage());
571                         btnPrevious->Enable(true);
572                         return;
574                 }
576 #else
577         
578                 // Connect again and fetch SSL certificate information.
579                 
580                 testConnection.BypassSSLVerification(true);
581                 
582                 CalDAVServerResult testConnectionResult = testConnection.Connect(false);
583                 
584                 testConnection.BypassSSLVerification(false);
586                 SSLCertCollectionString certData = testConnection.BuildSSLCollection();
587                 frmInvalidSSLCertificate *frmICPtr = new frmInvalidSSLCertificate(this);
588                 
589                 frmICPtr->LoadDataNew(certData, txtServerAddress->GetValue().ToStdString());
590                 frmICPtr->ShowModal();
591                                                                 
592                 int sslResult = frmICPtr->GetResult();
593                                                         
594                 // Clean up before processing response.
595                                 
596                 delete frmICPtr;
597                 frmICPtr = nullptr;
598                                                         
599                 // Process the response from the user.
600                                                         
601                 if (sslResult == 1){
602                                                                 
603                         // Accept the Certificate.
604                         
605                         usingSSLBypass = true;
606                         testConnection.BypassSSLVerification(true);
607                 
608                         CalDAVServerResult testConnectionResult = testConnection.Connect(true);
609                 
610                         testConnection.BypassSSLVerification(false);
611                                                                 
612                 } else if (sslResult == 2){
613                                                                 
614                         // Reject the certificate, abort the task and mark as failed.
616                         // TODO: Integrate into the code.
617                         
618                         //lblConnectionResultText->SetLabel(_("An error occured whilst connnecting: ") + CardDAVConn.GetErrorMessage() + wxString::Format(wxT(" (%i)\n%s"), sslcode, CardDAVConn.GetErrorBuffer().mb_str()));
619                         
620                         resultData->Connected = true;
621                         resultData->SSLStatus = true;
622                         resultData->SSLVerified = COSSL_UNABLETOVERIFY;
623                         resultData->ValidResponse = false;
624                         resultData->AuthPassed = false;
625                         resultData->CanProcess = false;
626                         resultData->ErrorMessage = _("Server is using self-signed certificate and was rejected.");
627                         
628                         wxCommandEvent resultsEvent(UPDATERESULTS);
629                         resultsEvent.SetClientData(resultData);
630                         wxPostEvent(this, resultsEvent);
631                         
632                         return;
633                                                 
634                 }               
635                 
636 #endif
637         }
638         
639         if (usingSSLBypass == true){
640                 testConnection.BypassSSLVerification(true);                     
641         }
642         
643         testConnectionResult = testConnection.Connect(true);
645         // Get the server prefix if the connection was successful.
646         
647         if (testConnectionResult.result == CALDAVQUERYRESULT_OK){
648                 
649                 std::string receivedServerPrefix;
650                 
651                 receivedServerPrefix = testConnection.GetUserPrincipal();
652                 serverPrefix = receivedServerPrefix;
653                 
654         }
655         
656         CalDAVServerSupport testConnectionSupport = testConnection.GetServerSupport();
657         
658         if (usingSSLBypass == true){
659                 testConnection.BypassSSLVerification(false);
660         }
661         
662         (testConnectionResult.result == CALDAVQUERYRESULT_OK || testConnectionResult.result == CALDAVQUERYRESULT_SSLFAILURE) ? 
663                 resultData->Connected = true : resultData->Connected = false;
664         
665         resultData->SSLStatus = testConnection.CanDoSSL();
666         resultData->SSLVerified = testConnection.SSLVerify();
667         resultData->ValidResponse = testConnection.HasValidResponse();
668         resultData->AuthPassed = testConnection.AbleToLogin();
669         resultData->CanProcess = testConnectionSupport.basicSupport;
670         resultData->ErrorMessage = testConnection.GetErrorMessage();
671         
672         // Post event back confirming the tests.
673         
674         wxCommandEvent resultsEvent(UPDATERESULTS);
675         resultsEvent.SetClientData(resultData);
676         wxPostEvent(this, resultsEvent);
Xestia Software Development
Yn Maystri
© 2006 - 2019 Xestia Software Development
Software

Xestia Address Book
Xestia Calendar
Development

Xestia Gelforn
Everything else

About
News
Privacy Policy