Don't send duplicate replies on error
[accounts-sso:jlaako-signon.git] / src / signond / signonidentityadaptor.cpp
1 /*
2  * This file is part of signon
3  *
4  * Copyright (C) 2009-2010 Nokia Corporation.
5  *
6  * Contact: Aurel Popirtac <ext-aurel.popirtac@nokia.com>
7  * Contact: Alberto Mardegan <alberto.mardegan@nokia.com>
8  *
9  * This library is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public License
11  * version 2.1 as published by the Free Software Foundation.
12  *
13  * This library is distributed in the hope that it will be useful, but
14  * WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with this library; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
21  * 02110-1301 USA
22  */
23
24 #include "signonidentityadaptor.h"
25
26 #include "signonidentity.h"
27 #include "accesscontrolmanager.h"
28
29 namespace SignonDaemonNS {
30
31     SignonIdentityAdaptor::SignonIdentityAdaptor(SignonIdentity *parent)
32         : QDBusAbstractAdaptor(parent),
33           m_parent(parent)
34     {
35         setAutoRelaySignals(true);
36     }
37
38     SignonIdentityAdaptor::~SignonIdentityAdaptor()
39     {}
40
41     void SignonIdentityAdaptor::securityErrorReply(const char *failedMethodName)
42     {
43         QString errMsg;
44         QTextStream(&errMsg) << SIGNOND_PERMISSION_DENIED_ERR_STR
45                              << "Method:"
46                              << failedMethodName;
47
48         errorReply(SIGNOND_PERMISSION_DENIED_ERR_NAME, errMsg);
49         TRACE() << "\nMethod FAILED Access Control check:\n" << failedMethodName;
50     }
51
52     void SignonIdentityAdaptor::errorReply(const QString &name,
53                                            const QString &message)
54     {
55         QDBusMessage msg = parentDBusContext().message();
56         msg.setDelayedReply(true);
57         QDBusMessage errReply = msg.createErrorReply(name, message);
58         SIGNOND_BUS.send(errReply);
59     }
60
61     quint32 SignonIdentityAdaptor::requestCredentialsUpdate(const QString &msg)
62     {
63         /* Access Control */
64         if (!AccessControlManager::isPeerAllowedToUseIdentity(
65                                         parentDBusContext(), m_parent->id())) {
66             securityErrorReply(__func__);
67             return 0;
68         }
69
70         return m_parent->requestCredentialsUpdate(msg);
71     }
72
73     QList<QVariant> SignonIdentityAdaptor::queryInfo()
74     {
75         /* Access Control */
76         if (!AccessControlManager::isPeerAllowedToUseIdentity(
77                                         parentDBusContext(), m_parent->id())) {
78             securityErrorReply(__func__);
79             return QList<QVariant>();
80         }
81
82         return m_parent->queryInfo();
83     }
84
85     void SignonIdentityAdaptor::addReference(const QString &reference)
86     {
87         /* Access Control */
88         if (!AccessControlManager::isPeerAllowedToUseIdentity(
89                                         parentDBusContext(), m_parent->id())) {
90             securityErrorReply(__func__);
91             return;
92         }
93
94         if (!m_parent->addReference(reference)) {
95             /* TODO: add a lastError() method to SignonIdentity */
96             errorReply(SIGNOND_OPERATION_FAILED_ERR_NAME,
97                        SIGNOND_OPERATION_FAILED_ERR_STR);
98         }
99     }
100
101     void SignonIdentityAdaptor::removeReference(const QString &reference)
102     {
103         /* Access Control */
104         if (!AccessControlManager::isPeerAllowedToUseIdentity(
105                                         parentDBusContext(), m_parent->id())) {
106             securityErrorReply(__func__);
107             return;
108         }
109
110         if (!m_parent->removeReference(reference)) {
111             /* TODO: add a lastError() method to SignonIdentity */
112             errorReply(SIGNOND_OPERATION_FAILED_ERR_NAME,
113                        SIGNOND_OPERATION_FAILED_ERR_STR);
114         }
115     }
116
117
118     bool SignonIdentityAdaptor::verifyUser(const QVariantMap &params)
119     {
120         /* Access Control */
121         if (!AccessControlManager::isPeerAllowedToUseIdentity(
122                                         parentDBusContext(), m_parent->id())) {
123             securityErrorReply(__func__);
124             return false;
125         }
126
127         return m_parent->verifyUser(params);
128     }
129
130     bool SignonIdentityAdaptor::verifySecret(const QString &secret)
131     {
132         /* Access Control */
133         if (!AccessControlManager::isPeerAllowedToUseIdentity(
134                                         parentDBusContext(), m_parent->id())) {
135             securityErrorReply(__func__);
136             return false;
137         }
138
139         return m_parent->verifySecret(secret);
140     }
141
142     void SignonIdentityAdaptor::remove()
143     {
144         /* Access Control */
145         AccessControlManager::IdentityOwnership ownership =
146                 AccessControlManager::isPeerOwnerOfIdentity(
147                             parentDBusContext(), m_parent->id());
148
149         if (ownership != AccessControlManager::IdentityDoesNotHaveOwner) {
150             //Identity has an owner
151             if (ownership == AccessControlManager::ApplicationIsNotOwner
152                 && !AccessControlManager::isPeerKeychainWidget(parentDBusContext())) {
153
154                 securityErrorReply(__func__);
155                 return;
156             }
157         }
158
159         m_parent->remove();
160     }
161
162     bool SignonIdentityAdaptor::signOut()
163     {
164         /* Access Control */
165         if (!AccessControlManager::isPeerAllowedToUseIdentity(
166                                         parentDBusContext(), m_parent->id())) {
167             securityErrorReply(__func__);
168             return false;
169         }
170
171         return m_parent->signOut();
172     }
173
174     quint32 SignonIdentityAdaptor::storeCredentials(const quint32 id,
175                                                     const QString &userName,
176                                                     const QString &secret,
177                                                     const bool storeSecret,
178                                                     const QMap<QString, QVariant> &methods,
179                                                     const QString &caption,
180                                                     const QStringList &realms,
181                                                     const QStringList &accessControlList,
182                                                     const int type)
183     {
184         /* Access Control */
185         if (id != SIGNOND_NEW_IDENTITY) {
186             AccessControlManager::IdentityOwnership ownership =
187                     AccessControlManager::isPeerOwnerOfIdentity(
188                                                 parentDBusContext(), m_parent->id());
189
190             if (ownership != AccessControlManager::IdentityDoesNotHaveOwner) {
191                 //Identity has an owner
192                 if (ownership == AccessControlManager::ApplicationIsNotOwner
193                     && !AccessControlManager::isPeerKeychainWidget(parentDBusContext())) {
194
195                     securityErrorReply(__func__);
196                     return 0;
197                 }
198             }
199         }
200
201         return m_parent->storeCredentials(id,
202                                           userName,
203                                           secret,
204                                           storeSecret,
205                                           methods,
206                                           caption,
207                                           realms,
208                                           accessControlList,
209                                           type);
210     }
211
212 } //namespace SignonDaemonNS