40184fb9a36f95a89e2172bf4e83e87d4d5b7f4f
[qtmeetings] / src / Domain / Configuration / Configuration.cpp
1 #include "Configuration.h"
2 #include "ConnectionSettings.h"
3 #include "StartupSettings.h"
4 #include "DisplaySettings.h"
5 #include "Room.h"
6 #include <QDomDocument>
7 #include <QDomElement>
8 #include <QDomNode>
9 #include <QFile>
10 #include <QCryptographicHash>
11
12 #include <QtDebug>
13
14 Configuration * Configuration::sInstance = 0;
15 QString Configuration::sConfigurationPath = "/etc/QtMeetings.conf";
16
17 Configuration::Configuration() :
18                 iConnectionSettings( 0 ),
19                 iStartupSettings( 0 ),
20                 iDisplaySettings( 0 ),
21                 iDateTimeSettings( 0 )
22 {
23 }
24
25 Configuration::~Configuration()
26 {
27         delete iConnectionSettings;
28         delete iStartupSettings;
29         delete iDisplaySettings;
30         delete iDateTimeSettings;
31         while ( !iRooms.isEmpty() )
32         {
33                 delete iRooms.takeFirst();
34         }
35 }
36
37 Configuration* Configuration::instance()
38 {
39         if ( sInstance == 0 )
40         {
41                 sInstance = readFromXML( sConfigurationPath );
42         if( !sInstance )
43         {
44             qDebug() << "FATAL: Configuration cannot be read from:" << Configuration::sConfigurationPath;
45         }
46     }
47         return sInstance;
48 }
49
50 ConnectionSettings* Configuration::connectionSettings()
51 {
52         return iConnectionSettings;
53 }
54
55 StartupSettings * Configuration::startupSettings()
56 {
57         return iStartupSettings;
58 }
59
60 DisplaySettings * Configuration::displaySettings()
61 {
62         return iDisplaySettings;
63 }
64
65 DateTimeSettings * Configuration::dateTimeSettings()
66 {
67         return iDateTimeSettings;
68 }
69
70 Room* Configuration::defaultRoom()
71 {
72         // default room is stored as the first element of the list
73         return ( iRooms.count() == 0 ) ? 0 : iRooms.at( 0 );
74 }
75
76 QString Configuration::languageCode()
77 {
78         return iLanguageCode;
79 }
80
81 QList<Room*> Configuration::rooms()
82 {
83         return iRooms;
84 }
85
86 QByteArray Configuration::adminPassword()
87 {
88         return iAdminPassword;
89 }
90
91 void Configuration::save()
92 {
93         QDomDocument doc;
94         QFile file( sConfigurationPath );
95
96         if ( !file.open( QIODevice::ReadWrite ) )
97         {
98                 return;
99         }
100
101         if ( !doc.setContent( &file ) )
102         {
103                 file.close();
104                 return;
105         }
106
107         QDomElement root = doc.documentElement();
108         // Save all attributes to document
109
110         saveAdminPassword( root );
111
112         for ( QDomNode node = root.firstChild(); !node.isNull(); node = node.nextSibling() )
113         {
114                 QDomElement e = node.toElement();
115                 QString tagName = e.tagName().toLower();
116
117                 if ( tagName == QString( "connection" ) )
118                 {
119                         saveConnectionSettings( node );
120                 }
121                 else if ( tagName == QString( "rooms" ) )
122                 {
123                         saveRooms( node );
124                 }
125                 else if ( tagName == QString( "language" ) )
126                 {
127                         saveLanguageCode( node );
128                 }
129                 else if ( tagName == QString( "startup" ) )
130                 {
131                         saveStartupSettings( node );
132                 }
133                 else if ( tagName == QString( "display" ) )
134                 {
135                         saveDisplaySettings( node );
136                 }
137                 else if (tagName == QString( "datetime" ) )
138                 {
139                         saveDateTimeSettings( node );
140                 }
141         }
142
143         //! Empty the file from previous content and write again with new one
144         file.resize( 0 );
145         file.write( doc.toByteArray( 4 ) );     //! 4 as intent
146
147         file.close();
148
149 }
150
151 void Configuration::saveConnectionSettings( const QDomNode &aXML )
152 {
153         for ( QDomNode node = aXML.firstChild(); !node.isNull(); node = node.nextSibling() )
154         {
155                 QDomElement e = node.toElement();
156                 QString tagName = e.tagName().toLower();
157
158                 if ( tagName == QString( "serverurl" ) )
159                 {
160                         QDomText t = node.ownerDocument().createTextNode( iConnectionSettings->serverUrl().toString() );
161                         e.replaceChild( t, e.firstChild() );
162                 }
163                 else if ( tagName == QString( "username" ) )
164                 {
165                         QDomText t = node.ownerDocument().createTextNode( iConnectionSettings->username() );
166                         e.replaceChild( t, e.firstChild() );
167                 }
168                 else if ( tagName == QString( "password" ) )
169                 {
170                         QDomText t = node.ownerDocument().createTextNode( iConnectionSettings->password() );
171                         e.replaceChild( t, e.firstChild() );
172                 }
173                 else if ( tagName == QString( "refreshinterval" ) )
174                 {
175                         QString s = QString( "%1" ).arg( iConnectionSettings->refreshInterval() );
176                         QDomText t = node.ownerDocument().createTextNode( s );
177                         e.replaceChild( t, e.firstChild() );
178                 }
179         }
180 }
181
182 void Configuration::saveRooms( const QDomNode &aXML )
183 {
184         //! List of rooms must be cleared and rewritten again
185         QDomDocument doc = aXML.ownerDocument();
186         QDomNode root = aXML; 
187
188         // Remove child nodes...
189         int count = root.childNodes().count();
190         QDomNode node = root.firstChild();
191         QDomNode next;
192         for (int i=0; i<count; i++)
193         {
194                 qDebug() << "remove " << node.toElement().text();
195                 next = node.nextSibling();
196                 node = root.removeChild(node);
197                 node = next;
198         }
199
200         QList<Room*>::iterator i;
201         for ( i = iRooms.begin(); i != iRooms.end(); ++i )
202         {
203                 QDomElement tag = doc.createElement( "room" );
204                 node.appendChild( tag );
205
206                 // First room in the list is a dafault room
207                 if ( i == iRooms.begin() )
208                 {
209                         tag.setAttribute( "default", "true" );
210                 }
211
212                 QDomElement ename = doc.createElement( "name" );
213                 QDomText tname = node.ownerDocument().createTextNode(( *i )->name() );
214                 ename.appendChild( tname );
215                 tag.appendChild( ename );
216
217                 QDomElement eaddress = doc.createElement( "address" );
218                 QDomText taddress = node.ownerDocument().createTextNode(( *i )->address() );
219                 eaddress.appendChild( taddress );
220                 tag.appendChild( eaddress );
221         }
222 }
223
224 void Configuration::saveLanguageCode( const QDomNode &aXML )
225 {
226         QDomElement e = aXML.toElement();
227         e.setAttribute( "code", languageCode() );
228 }
229
230 void Configuration::saveStartupSettings( const QDomNode &aXML )
231 {
232         QDomElement e = aXML.toElement();
233
234         for ( QDomNode node = aXML.firstChild(); !node.isNull(); node = node.nextSibling() )
235         {
236                 e = node.toElement();
237                 QString tagName = e.tagName().toLower();
238
239                 if ( tagName == QString( "powersaving" ) )
240                 {
241                         ( iStartupSettings->isPowersavingEnabled() ?
242                           e.setAttribute( "enabled", "true" ) :
243                           e.setAttribute( "enabled", "false" ) );
244
245                         e.setAttribute( "on", iStartupSettings->turnOnAt().toString( "hh:mm" ) );
246                         e.setAttribute( "off", iStartupSettings->turnOffAt().toString( "hh:mm" ) );
247                 }
248         }
249 }
250
251 void Configuration::saveDisplaySettings( const QDomNode &aXML )
252 {
253         for ( QDomNode node = aXML.firstChild(); !node.isNull(); node = node.nextSibling() )
254         {
255                 QDomElement e = node.toElement();
256                 QString tagName = e.tagName().toLower();
257
258                 if ( tagName == QString( "schedule" ) )
259                 {
260                         for ( QDomNode scheduleNode = node.firstChild(); !scheduleNode.isNull(); scheduleNode = scheduleNode.nextSibling() )
261                         {
262                                 QDomElement scheduleElem = scheduleNode.toElement();
263                                 tagName = scheduleElem.tagName().toLower();
264
265                                 if ( tagName == QString( "week" ) )
266                                 {
267                                         scheduleElem.setAttribute( "days", iDisplaySettings->daysInSchedule() );
268                                 }
269                                 else if ( tagName == QString( "day" ) )
270                                 {
271                                         scheduleElem.setAttribute( "startsat", iDisplaySettings->dayStartsAt().toString( "hh:mm" ) );
272                                         scheduleElem.setAttribute( "endsat", iDisplaySettings->dayEndsAt().toString( "hh:mm" ) );
273                                 }
274                         }       // end of for
275                 }       // end of schedule
276                 else if ( tagName == QString( "dateformat" ) )
277                 {
278                         QDomText t = node.ownerDocument().createTextNode( iDisplaySettings->dateFormat() );
279                         e.replaceChild( t, e.firstChild() );
280                 }
281                 else if ( tagName == QString( "timeformat" ) )
282                 {
283                         QDomText t = node.ownerDocument().createTextNode( iDisplaySettings->timeFormat() );
284                         e.replaceChild( t, e.firstChild() );
285                 }
286                 else if ( tagName == QString( "screensaver" ) )
287                 {
288                         QString s = QString( "%1" ).arg( iDisplaySettings->screensaver() );
289                         QDomText t = node.ownerDocument().createTextNode( s );
290                         e.replaceChild( t, e.firstChild() );
291                 }
292         }
293 }
294
295 void Configuration::saveDateTimeSettings( const QDomNode &aXML )
296 {
297         for ( QDomNode node = aXML.firstChild(); !node.isNull(); node = node.nextSibling() )
298         {
299                 QDomElement e = node.toElement();
300                 QString tagName = e.tagName().toLower();
301
302                 if ( tagName == QString( "dayofweek" ) )
303                 {
304                         QDomText t = node.ownerDocument().createTextNode( iDateTimeSettings->iDayOfWeek);
305                         e.replaceChild( t, e.firstChild() );
306                 }
307                 else if( tagName == QString( "StandardTimeChangeMoment" ) )
308                 {
309                         QDomText t = node.ownerDocument().createTextNode( iDateTimeSettings->iStandardTimeChangeMoment.toString("dd.MM.yyyy hh:mm:ss"));
310                         e.replaceChild( t, e.firstChild() );
311                 }
312                 else if( tagName == QString( "DaylightSaveTimeChangeMoment" ) )
313                 {
314                         QDomText t = node.ownerDocument().createTextNode( iDateTimeSettings->iDaylightSaveTimeChangeMoment.toString("dd.MM.yyyy hh:mm:ss"));
315                         e.replaceChild( t, e.firstChild() );
316                 }
317         }
318 }
319
320 void Configuration::saveAdminPassword( const QDomNode &aXML )
321 {
322         QDomElement e = aXML.toElement();
323         e.setAttribute( "password", QString( adminPassword() ) );
324 }
325
326
327 Configuration* Configuration::readFromXML( const QString &aPath )
328 {
329         QDomDocument doc;
330         QFile file( aPath );
331
332         if ( !file.open( QIODevice::ReadOnly ) )
333         {
334                 return 0;
335         }
336         if ( !doc.setContent( &file ) )
337         {
338                 file.close();
339                 return 0;
340         }
341         file.close();
342
343         QDomElement root = doc.documentElement();
344         // check if the file is the one we need
345         if ( root.tagName().toLower() != QString( "configuration" ) )
346         {
347                 return 0;
348         }
349
350         Configuration* conf = new Configuration();
351
352         conf->iAdminPassword = Configuration::readAdminPassword( root );
353
354         for ( QDomNode node = root.firstChild(); !node.isNull(); node = node.nextSibling() )
355         {
356                 QDomElement e = node.toElement();
357                 QString tagName = e.tagName().toLower();
358
359                 if ( tagName == QString( "connection" ) )
360                 {
361                         conf->iConnectionSettings = Configuration::readConnectionSettings( node );
362                 }
363                 else if ( tagName == QString( "rooms" ) )
364                 {
365                         conf->iRooms = Configuration::readRooms( node );
366                 }
367                 else if ( tagName == QString( "language" ) )
368                 {
369                         conf->iLanguageCode = Configuration::readLanguageCode( node );
370                 }
371                 else if ( tagName == QString( "startup" ) )
372                 {
373                         conf->iStartupSettings = Configuration::readStartupSettings( node );
374                 }
375                 else if ( tagName == QString( "display" ) )
376                 {
377                         conf->iDisplaySettings = Configuration::readDisplaySettings( node );
378                 }
379                 else if ( tagName == QString( "datetime" ) )
380                 {
381                         conf->iDateTimeSettings = Configuration::readDateTimeSettings(node);
382                 }
383         }
384
385         return conf;
386 }
387
388 ConnectionSettings* Configuration::readConnectionSettings( const QDomNode &aXML )
389 {
390         QString server, username, password;
391         unsigned int interval = Configuration::sDefaultInterval;
392
393         for ( QDomNode node = aXML.firstChild(); !node.isNull(); node = node.nextSibling() )
394         {
395                 QDomElement e = node.toElement();
396                 QString tagName = e.tagName().toLower();
397
398                 if ( tagName == QString( "serverurl" ) )
399                 {
400                         server = e.text();
401                 }
402                 else if ( tagName == QString( "username" ) )
403                 {
404                         username = e.text();
405                 }
406                 else if ( tagName == QString( "password" ) )
407                 {
408                         password = e.text();
409                 }
410                 else if ( tagName == QString( "refreshinterval" ) )
411                 {
412                         bool success = false;
413                         unsigned int intervalTMP = e.text().toUInt( &success );
414                         if ( success )
415                         {
416                                 interval = intervalTMP;
417                         }
418                 }
419         }
420
421         return new ConnectionSettings( server, username, password, interval );
422 }
423
424 QList<Room*> Configuration::readRooms( const QDomNode &aXML )
425 {
426         QList<Room*> rooms;
427
428         for ( QDomNode node = aXML.firstChild(); !node.isNull(); node = node.nextSibling() )
429         {
430                 QDomElement e = node.toElement();
431                 QString tagName = e.tagName().toLower();
432
433                 if ( tagName == QString( "room" ) )
434                 {
435                         QString name, address;
436
437                         for ( QDomNode roomNode = node.firstChild(); !roomNode.isNull(); roomNode = roomNode.nextSibling() )
438                         {
439                                 QDomElement roomElem = roomNode.toElement();
440                                 tagName = roomElem.tagName().toLower();
441                                 if ( tagName == QString( "name" ) )
442                                 {
443                                         name = roomElem.text();
444                                 }
445                                 else if ( tagName == QString( "address" ) )
446                                 {
447                                         address = roomElem.text();
448                                 }
449                         }
450                         Room* room = new Room( name, address );
451                         QString defaultAttr = e.attribute( "default" ).toLower();
452                         if ( defaultAttr == QString( "true" ) )
453                         {
454                                 rooms.insert( 0, room );
455                         }
456                         else
457                         {
458                                 rooms.append( room );
459                         }
460                 }
461         }
462
463         return rooms;
464 }
465
466 QString Configuration::readLanguageCode( const QDomNode &aXML )
467 {
468         QDomElement e = aXML.toElement();
469         QString tagName = e.tagName().toLower();
470
471         if ( e.hasAttribute( "code" ) )
472         {
473                 return e.attribute( "code" );
474         }
475         else
476         {
477                 // default language is English
478                 return "EN";
479         }
480 }
481
482 StartupSettings * Configuration::readStartupSettings( const QDomNode &aXML )
483 {
484         QDomElement e = aXML.toElement();
485
486         bool isPowersavingEnabled = false;
487         QTime turnOnAt, turnOffAt;
488
489         for ( QDomNode node = aXML.firstChild(); !node.isNull(); node = node.nextSibling() )
490         {
491                 e = node.toElement();
492                 QString tagName = e.tagName().toLower();
493
494                 if ( tagName == QString( "powersaving" ) )
495                 {
496                         if ( e.hasAttribute( "enabled" ) &&
497                                   e.attribute( "enabled" ) == QString( "true" ) )
498                         {
499                                 isPowersavingEnabled = true;
500                         }
501
502                         if ( e.hasAttribute( "on" ) )
503                         {
504                                 QString on = e.attribute( "on" );
505                                 turnOnAt = QTime::fromString( on, "hh:mm" );
506
507                         }
508
509                         if ( e.hasAttribute( "off" ) )
510                         {
511                                 QString off = e.attribute( "off" );
512                                 turnOffAt = QTime::fromString( off, "hh:mm" );
513                         }
514                 }
515         }
516
517         return new StartupSettings( isPowersavingEnabled, turnOnAt, turnOffAt );
518 }
519
520 DisplaySettings * Configuration::readDisplaySettings( const QDomNode &aXML )
521 {
522         DisplaySettings::DaysInSchedule daysInSchedule = DisplaySettings::WeekdaysInSchedule;
523         QTime dayStartsAt, dayEndsAt;
524         DisplaySettings::DateFormat dateformat = DisplaySettings::ShortDateFormat;
525         DisplaySettings::TimeFormat timeformat = DisplaySettings::TwentyFourHoursTimeFormat;
526         int screensaver = 1;    //! Default value for screensaver wait time
527
528         for ( QDomNode node = aXML.firstChild(); !node.isNull(); node = node.nextSibling() )
529         {
530                 QDomElement e = node.toElement();
531                 QString tagName = e.tagName().toLower();
532
533                 if ( tagName == QString( "schedule" ) )
534                 {
535                         for ( QDomNode scheduleNode = node.firstChild(); !scheduleNode.isNull(); scheduleNode = scheduleNode.nextSibling() )
536                         {
537                                 QDomElement scheduleElem = scheduleNode.toElement();
538                                 tagName = scheduleElem.tagName().toLower();
539
540                                 if ( tagName == QString( "week" ) )
541                                 {
542                                         if ( scheduleElem.hasAttribute( "days" ) )
543                                         {
544                                                 // default value is 5, only other supported possibility is 7
545                                                 bool success = false;
546                                                 unsigned int days = scheduleElem.attribute( "days" ).toUInt( &success );
547                                                 daysInSchedule = ( success && days == 7 ) ? DisplaySettings::WholeWeekInSchedule : DisplaySettings::WeekdaysInSchedule;
548                                         }
549
550                                 }
551                                 else if ( tagName == QString( "day" ) )
552                                 {
553                                         if ( scheduleElem.hasAttribute( "startsat" ) )
554                                         {
555                                                 QString time = scheduleElem.attribute( "startsat" );
556                                                 dayStartsAt = QTime::fromString( time, "hh:mm" );
557                                         }
558                                         if ( scheduleElem.hasAttribute( "endsat" ) )
559                                         {
560                                                 QString time = scheduleElem.attribute( "endsat" );
561                                                 dayEndsAt = QTime::fromString( time, "hh:mm" );
562                                         }
563
564                                 }
565                         }       // end of for
566                 }       // end of schedule
567                 else if ( tagName == QString( "dateformat" ) )
568                 {
569                         //! Not able to display long format anyway at the moment
570                         /*
571                         if ( e.text() == QObject::tr( "dddd d MMMM yyyy" ) )
572                                 dateformat = DisplaySettings::LongDateFormat;
573                         else
574                                 dateformat = DisplaySettings::ShortDateFormat;
575                         */
576                         dateformat = DisplaySettings::ShortDateFormat;
577                 }
578                 else if ( tagName == QString( "timeformat" ) )
579                 {
580                         //! Not able to display "TwelveHoursTimeFormat" anyway at the moment
581                         /*
582                         if ( e.text() == QObject::tr( "hh:mm ap" ) )
583                                 timeformat = DisplaySettings::TwelveHoursTimeFormat;
584                         else
585                                 timeformat = DisplaySettings::TwentyFourHoursTimeFormat;
586                         */
587                         timeformat = DisplaySettings::TwentyFourHoursTimeFormat;
588                 }
589                 else if ( tagName == QString( "screensaver" ) )
590                 {
591                         bool success = false;
592                         unsigned int screensaverTMP = e.text().toUInt( &success );
593                         if ( success )
594                         {
595                                 screensaver = screensaverTMP;
596                         }
597                 }
598         }
599
600         return new DisplaySettings( dateformat, timeformat, daysInSchedule, dayStartsAt, dayEndsAt, screensaver );
601 }
602
603 DateTimeSettings * Configuration::readDateTimeSettings( const QDomNode &aXML )
604 {
605         QDateTime standardTimeChangeMoment;
606         QDateTime daylightSaveTimeChangeMoment;
607         QString dayOfWeek;
608         
609         for ( QDomNode node = aXML.firstChild(); !node.isNull(); node = node.nextSibling() )
610         {
611                 QDomElement e = node.toElement();
612                 QString tagName = e.tagName().toLower();
613
614                 if ( tagName == QString( "dayofweek" ) )
615                 {
616                         dayOfWeek = e.text();
617                 }
618                 else if( tagName == QString( "StandardTimeChangeMoment" ) )
619                 {
620                         standardTimeChangeMoment.fromString(e.text(), "dd.MM.yyyy hh:mm:ss");
621                 }
622                 else if( tagName == QString( "DaylightSaveTimeChangeMoment" ) )
623                 {
624                         daylightSaveTimeChangeMoment.fromString(e.text(), "dd.MM.yyyy hh:mm:ss");
625                 }
626         }
627         
628         return new DateTimeSettings(standardTimeChangeMoment, daylightSaveTimeChangeMoment, dayOfWeek);
629 }
630
631 QByteArray Configuration::readAdminPassword( const QDomNode &aXML )
632 {
633         QDomElement e = aXML.toElement();
634         QString tagName = e.tagName().toLower();
635         if ( e.hasAttribute( "password" ) )
636         {
637                 QString pw = e.attribute( "password" );
638                 // Check if the password is default uncrypted "admin"
639                 if ( pw == QString( "admin" ) )
640                 {
641                         // uncrypted password needs to be encoded
642                         QCryptographicHash *hash = new QCryptographicHash( QCryptographicHash::Md5 );
643                         hash->addData( pw.toUtf8() );
644                         pw = QString( hash->result() );
645                         delete hash;
646                 }
647                 return ( pw.toAscii() ).toHex();
648                 
649         }
650         else
651         {
652                 return 0;
653         }
654 }
655
656 void Configuration::setRooms( const QList<Room*> aRooms )
657 {
658         iRooms = aRooms;
659 }
660
661 QString Configuration::hashPassword( const QString aPassword )
662 {
663         QCryptographicHash *hash = new QCryptographicHash( QCryptographicHash::Md5 );
664         hash->addData( aPassword.toUtf8() );
665         QByteArray password = hash->result();
666         delete hash;
667
668         return QString( password );
669 }