1 /* Ricochet - https://ricochet.im/ 2 * Copyright (C) 2014, John Brooks <john.brooks@dereferenced.net> 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are 6 * met: 7 * 8 * * Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 11 * * Redistributions in binary form must reproduce the above 12 * copyright notice, this list of conditions and the following disclaimer 13 * in the documentation and/or other materials provided with the 14 * distribution. 15 * 16 * * Neither the names of the copyright owners nor the names of its 17 * contributors may be used to endorse or promote products derived from 18 * this software without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33 #ifndef CONTACTUSER_H 34 #define CONTACTUSER_H 35 36 #include <QObject> 37 #include <QHash> 38 #include <QMetaType> 39 #include <QVariant> 40 #include <QSharedPointer> 41 #include "utils/Settings.h" 42 #include "protocol/Connection.h" 43 44 class UserIdentity; 45 class OutgoingContactRequest; 46 class ConversationModel; 47 48 namespace Protocol 49 { 50 class OutboundConnector; 51 } 52 53 /* Represents a user on the contact list. 54 * All persistent uses of a ContactUser instance must either connect to the 55 * contactDeleted() signal, or use a QWeakPointer to track deletion. A ContactUser 56 * can be removed at essentially any time. */ 57 58 class ContactUser : public QObject 59 { 60 Q_OBJECT 61 Q_DISABLE_COPY(ContactUser) 62 Q_ENUMS(Status) 63 64 Q_PROPERTY(int uniqueID READ getUniqueID CONSTANT) 65 Q_PROPERTY(UserIdentity* identity READ getIdentity CONSTANT) 66 Q_PROPERTY(QString nickname READ nickname WRITE setNickname NOTIFY nicknameChanged) 67 Q_PROPERTY(QString contactID READ contactID CONSTANT) 68 Q_PROPERTY(Status status READ status NOTIFY statusChanged) 69 Q_PROPERTY(OutgoingContactRequest *contactRequest READ contactRequest NOTIFY statusChanged) 70 Q_PROPERTY(SettingsObject *settings READ settings CONSTANT) 71 Q_PROPERTY(ConversationModel *conversation READ conversation CONSTANT) 72 73 friend class ContactsManager; 74 friend class OutgoingContactRequest; 75 76 public: 77 enum Status 78 { 79 Online, 80 Offline, 81 RequestPending, 82 RequestRejected, 83 Outdated 84 }; 85 86 UserIdentity * const identity; 87 const int uniqueID; 88 89 explicit ContactUser(UserIdentity *identity, int uniqueID, QObject *parent = 0); 90 virtual ~ContactUser(); 91 connection()92 const QSharedPointer<Protocol::Connection> &connection() { return m_connection; } isConnected()93 bool isConnected() const { return status() == Online; } 94 contactRequest()95 OutgoingContactRequest *contactRequest() { return m_contactRequest; } conversation()96 ConversationModel *conversation() { return m_conversation; } 97 getIdentity()98 UserIdentity *getIdentity() const { return identity; } getUniqueID()99 int getUniqueID() const { return uniqueID; } 100 101 QString nickname() const; 102 /* Hostname is in the onion hostname format, i.e. it ends with .onion */ 103 QString hostname() const; 104 quint16 port() const; 105 /* Contact ID in the ricochet: format */ 106 QString contactID() const; 107 status()108 Status status() const { return m_status; } 109 110 SettingsObject *settings(); 111 112 Q_INVOKABLE void deleteContact(); 113 114 public slots: 115 /* Assign a connection to this user 116 * 117 * The connection must be connected, and the peer must be authenticated and 118 * must match this user. ContactUser will assume ownership of the connection, 119 * and it will be closed and deleted when it's no longer used. 120 * 121 * It is valid to pass an incoming or outgoing connection. If there is already 122 * a connection, protocol-specific rules are applied and the new connection 123 * may be closed to favor the older one. 124 * 125 * If the existing connection is replaced, that is equivalent to disconnecting 126 * and reconnectng immediately - any ongoing operations will fail and need to 127 * be retried at a higher level. 128 */ 129 void assignConnection(const QSharedPointer<Protocol::Connection> &connection); 130 131 void setNickname(const QString &nickname); 132 void setHostname(const QString &hostname); 133 134 void updateStatus(); 135 136 signals: 137 void statusChanged(); 138 void connected(); 139 void disconnected(); 140 void connectionChanged(const QWeakPointer<Protocol::Connection> &connection); 141 142 void nicknameChanged(); 143 void contactDeleted(ContactUser *user); 144 145 private slots: 146 void onConnected(); 147 void onDisconnected(); 148 void requestRemoved(); 149 void requestAccepted(); 150 void onSettingsModified(const QString &key, const QJsonValue &value); 151 152 private: 153 QSharedPointer<Protocol::Connection> m_connection; 154 Protocol::OutboundConnector *m_outgoingSocket; 155 156 Status m_status; 157 quint16 m_lastReceivedChatID; 158 OutgoingContactRequest *m_contactRequest; 159 SettingsObject *m_settings; 160 ConversationModel *m_conversation; 161 162 /* See ContactsManager::addContact */ 163 static ContactUser *addNewContact(UserIdentity *identity, int id); 164 165 void loadContactRequest(); 166 void updateOutgoingSocket(); 167 168 void clearConnection(); 169 }; 170 171 Q_DECLARE_METATYPE(ContactUser*) 172 173 #endif // CONTACTUSER_H 174