core defaults to safer umask
[quassel.git] / src / common / identity.cpp
1 /***************************************************************************
2  *   Copyright (C) 2005-09 by the Quassel Project                          *
3  *   devel@quassel-irc.org                                                 *
4  *                                                                         *
5  *   This program is free software; you can redistribute it and/or modify  *
6  *   it under the terms of the GNU General Public License as published by  *
7  *   the Free Software Foundation; either version 2 of the License, or     *
8  *   (at your option) version 3.                                           *
9  *                                                                         *
10  *   This program is distributed in the hope that it will be useful,       *
11  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
12  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
13  *   GNU General Public License for more details.                          *
14  *                                                                         *
15  *   You should have received a copy of the GNU General Public License     *
16  *   along with this program; if not, write to the                         *
17  *   Free Software Foundation, Inc.,                                       *
18  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
19  ***************************************************************************/
20
21 #include "identity.h"
22
23 #include <QMetaProperty>
24 #include <QVariantMap>
25 #include <QString>
26
27 #ifdef Q_OS_MAC
28 #  include <CoreServices/CoreServices.h>
29 #  include "mac_utils.h"
30 #endif
31
32 #ifdef Q_OS_UNIX
33 #  include <sys/types.h>
34 #  include <pwd.h>
35 #  include <unistd.h>
36 #endif
37
38 #ifdef Q_OS_WIN32
39 #  include <windows.h>
40 #  include <Winbase.h>
41 #  define SECURITY_WIN32
42 #  include <Security.h>
43 #endif
44
45 INIT_SYNCABLE_OBJECT(Identity)
46 Identity::Identity(IdentityId id, QObject *parent)
47   : SyncableObject(parent),
48     _identityId(id)
49 {
50   init();
51   setToDefaults();
52 }
53
54 Identity::Identity(const Identity &other, QObject *parent)
55   : SyncableObject(parent),
56     _identityId(other.id()),
57     _identityName(other.identityName()),
58     _realName(other.realName()),
59     _nicks(other.nicks()),
60     _awayNick(other.awayNick()),
61     _awayNickEnabled(other.awayNickEnabled()),
62     _awayReason(other.awayReason()),
63     _awayReasonEnabled(other.awayReasonEnabled()),
64     _autoAwayEnabled(other.autoAwayEnabled()),
65     _autoAwayTime(other.autoAwayTime()),
66     _autoAwayReason(other.autoAwayReason()),
67     _autoAwayReasonEnabled(other.autoAwayReasonEnabled()),
68     _detachAwayEnabled(other.detachAwayEnabled()),
69     _detachAwayReason(other.detachAwayReason()),
70     _detachAwayReasonEnabled(other.detachAwayReasonEnabled()),
71     _ident(other.ident()),
72     _kickReason(other.kickReason()),
73     _partReason(other.partReason()),
74     _quitReason(other.quitReason())
75 {
76   init();
77 }
78
79 void Identity::init() {
80   setObjectName(QString::number(id().toInt()));
81   setAllowClientUpdates(true);
82 }
83
84 QString Identity::defaultNick() {
85   QString nick = QString("quassel%1").arg(qrand() & 0xff); // FIXME provide more sensible default nicks
86
87 #ifdef Q_OS_MAC
88   QString shortUserName = CFStringToQString(CSCopyUserName(true));
89   if(!shortUserName.isEmpty())
90     nick = shortUserName;
91
92 #elif defined(Q_OS_UNIX)
93   QString userName;
94   struct passwd *pwd = getpwuid(getuid());
95   if(pwd)
96     userName = pwd->pw_name;
97   if(!userName.isEmpty())
98     nick = userName;
99
100 #elif defined(Q_OS_WIN32)
101   TCHAR  infoBuf[128];
102   DWORD  bufCharCount = 128;
103   //if(GetUserNameEx(/* NameSamCompatible */ 1, infoBuf, &bufCharCount))
104   if(GetUserNameEx(NameSamCompatible, infoBuf, &bufCharCount)) {
105     QString nickName(infoBuf);
106     int lastBs = nickName.lastIndexOf('\\');
107     if(lastBs != -1) {
108       nickName = nickName.mid(lastBs + 1);
109     }
110     if(!nickName.isEmpty())
111       nick = nickName;
112   }
113 #endif
114
115   // cleaning forbidden characters from nick
116   QRegExp rx(QString("(^[\\d-]+|[^A-Za-z0-9\x5b-\x60\x7b-\x7d])"));
117   nick.remove(rx);
118   return nick;
119 }
120
121 QString Identity::defaultRealName() {
122   QString generalDefault = tr("Quassel IRC User");
123
124 #ifdef Q_OS_MAC
125   return CFStringToQString(CSCopyUserName(false));
126
127 #elif defined(Q_OS_UNIX)
128   QString realName;
129   struct passwd *pwd = getpwuid(getuid());
130   if(pwd)
131     realName = QString::fromUtf8(pwd->pw_gecos);
132   if(!realName.isEmpty())
133     return realName;
134   else
135     return generalDefault;
136
137 #elif defined(Q_OS_WIN32)
138   TCHAR  infoBuf[128];
139   DWORD  bufCharCount = 128;
140   if(GetUserName(infoBuf, &bufCharCount))
141     return QString(infoBuf);
142   else
143     return generalDefault;
144 #else
145   return generalDefault;
146 #endif
147 }
148
149 void Identity::setToDefaults() {
150   setIdentityName(tr("<empty>"));
151   setRealName(defaultRealName());
152   QStringList n = QStringList() << defaultNick();
153   setNicks(n);
154   setAwayNick("");
155   setAwayNickEnabled(false);
156   setAwayReason(tr("Gone fishing."));
157   setAwayReasonEnabled(true);
158   setAutoAwayEnabled(false);
159   setAutoAwayTime(10);
160   setAutoAwayReason(tr("Not here. No, really. not here!"));
161   setAutoAwayReasonEnabled(false);
162   setDetachAwayEnabled(false);
163   setDetachAwayReason(tr("All Quassel clients vanished from the face of the earth..."));
164   setDetachAwayReasonEnabled(false);
165   setIdent("quassel");
166   setKickReason(tr("Kindergarten is elsewhere!"));
167   setPartReason(tr("http://quassel-irc.org - Chat comfortably. Anywhere."));
168   setQuitReason(tr("http://quassel-irc.org - Chat comfortably. Anywhere."));
169 }
170
171 /*** setters ***/
172
173 void Identity::setId(IdentityId _id) {
174   _identityId = _id;
175   SYNC(ARG(_id))
176   emit idSet(_id);
177   renameObject(QString::number(id().toInt()));
178 }
179
180 void Identity::setIdentityName(const QString &identityName) {
181   _identityName = identityName;
182   SYNC(ARG(identityName))
183 }
184
185 void Identity::setRealName(const QString &realName) {
186   _realName = realName;
187   SYNC(ARG(realName))
188 }
189
190 void Identity::setNicks(const QStringList &nicks) {
191   _nicks = nicks;
192   SYNC(ARG(nicks))
193   emit nicksSet(nicks);
194 }
195
196 void Identity::setAwayNick(const QString &nick) {
197   _awayNick = nick;
198   SYNC(ARG(nick))
199 }
200
201 void Identity::setAwayReason(const QString &reason) {
202   _awayReason = reason;
203   SYNC(ARG(reason))
204 }
205
206 void Identity::setAwayNickEnabled(bool enabled) {
207   _awayNickEnabled = enabled;
208   SYNC(ARG(enabled))
209 }
210
211 void Identity::setAwayReasonEnabled(bool enabled) {
212   _awayReasonEnabled = enabled;
213   SYNC(ARG(enabled))
214 }
215
216 void Identity::setAutoAwayEnabled(bool enabled) {
217   _autoAwayEnabled = enabled;
218   SYNC(ARG(enabled))
219 }
220
221 void Identity::setAutoAwayTime(int time) {
222   _autoAwayTime = time;
223   SYNC(ARG(time))
224 }
225
226 void Identity::setAutoAwayReason(const QString &reason) {
227   _autoAwayReason = reason;
228   SYNC(ARG(reason))
229 }
230
231 void Identity::setAutoAwayReasonEnabled(bool enabled) {
232   _autoAwayReasonEnabled = enabled;
233   SYNC(ARG(enabled))
234 }
235
236 void Identity::setDetachAwayEnabled(bool enabled) {
237   _detachAwayEnabled = enabled;
238   SYNC(ARG(enabled))
239 }
240
241 void Identity::setDetachAwayReason(const QString &reason) {
242   _detachAwayReason = reason;
243   SYNC(ARG(reason))
244 }
245
246 void Identity::setDetachAwayReasonEnabled(bool enabled) {
247   _detachAwayReasonEnabled = enabled;
248   SYNC(ARG(enabled))
249 }
250
251 void Identity::setIdent(const QString &ident) {
252   _ident = ident;
253   SYNC(ARG(ident))
254 }
255
256 void Identity::setKickReason(const QString &reason) {
257   _kickReason = reason;
258   SYNC(ARG(reason))
259 }
260
261 void Identity::setPartReason(const QString &reason) {
262   _partReason = reason;
263   SYNC(ARG(reason))
264 }
265
266 void Identity::setQuitReason(const QString &reason) {
267   _quitReason = reason;
268   SYNC(ARG(reason))
269 }
270
271 /***  ***/
272
273 void Identity::copyFrom(const Identity &other) {
274   for(int idx = staticMetaObject.propertyOffset(); idx < staticMetaObject.propertyCount(); idx++) {
275     QMetaProperty metaProp = staticMetaObject.property(idx);
276     Q_ASSERT(metaProp.isValid());
277     if(this->property(metaProp.name()) != other.property(metaProp.name())) {
278       setProperty(metaProp.name(), other.property(metaProp.name()));
279     }
280   }
281 }
282
283 bool Identity::operator==(const Identity &other) const {
284   for(int idx = staticMetaObject.propertyOffset(); idx < staticMetaObject.propertyCount(); idx++) {
285     QMetaProperty metaProp = staticMetaObject.property(idx);
286     Q_ASSERT(metaProp.isValid());
287     QVariant v1 = this->property(metaProp.name());
288     QVariant v2 = other.property(metaProp.name()); // qDebug() << v1 << v2;
289     // QVariant cannot compare custom types, so we need to check for this special case
290     if(QString(v1.typeName()) == "IdentityId") {
291       if(v1.value<IdentityId>() != v2.value<IdentityId>()) return false;
292     } else {
293       if(v1 != v2) return false;
294     }
295   }
296   return true;
297 }
298
299 bool Identity::operator!=(const Identity &other) const {
300   return !(*this == other);
301 }
302
303 ///////////////////////////////
304
305 QDataStream &operator<<(QDataStream &out, Identity id) {
306   out << id.toVariantMap();
307   return out;
308 }
309
310
311 QDataStream &operator>>(QDataStream &in, Identity &id) {
312   QVariantMap i;
313   in >> i;
314   id.fromVariantMap(i);
315   return in;
316 }
317
318 #ifdef HAVE_SSL
319 INIT_SYNCABLE_OBJECT(CertManager)
320 #endif // HAVE_SSL