Remoto - VFS: VFS_curlauth.cpp Source File
Remoto - VFS
VFS_curlauth.cpp
Go to the documentation of this file.
1 
2 #include "VFS_curlauth.h"
3 #include "VFS.h"
4 
5 #include <QUrlQuery>
6 #include <QNetworkRequest>
7 
27 VFS_curlauth::VFS_curlauth(QString url,QString token)
28 : VFS_auth()
29 , _url(url)
30 , _manager(this)
31 , _token(token)
32 {
33  if (!_url.isValid())
34  VFS::WARN("The provided url is invalid: \""+url+"\". Requests will fail.");
35 
36  connect( &_manager, SIGNAL(finished(QNetworkReply*)),
37  this, SLOT(replyFinished(QNetworkReply*)) );
38 
39  connect( &_manager, SIGNAL(sslErrors(QNetworkReply*,QList<QSslError>)),
40  this, SLOT(sslErrors(QNetworkReply*,QList<QSslError>)) );
41 }
42 
44 {
45 }
46 
78 //http://www.qtcentre.org/threads/42545-HTTP-request-POST-in-QT-application
79 
81 {
82  QJsonObject o = r->_data.object();
83 
84  //FIXME: check if r->_path is empty!
85 
86  QString user = o["username"].toString();
87  QString pass = o["password"].toString();
88 
89  QUrlQuery params;
90  params.addQueryItem("username",user);
91  params.addQueryItem("password",pass);
92 
93  //VFS_request *s = r->getCallback(this);
94  r->_isCallback = true; //defer the response as if there were a callback.
95 
96  QNetworkRequest request(_url);
97  request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");
98 
99  QNetworkReply *p = _manager.post(request,params.query().toUtf8());
100 
101  _requests[p] = r;
102 
103  //r->_success = false;
104  //r->_user = username;
105 }
106 
107 
114 {
115  //printf("curlauth LS\n");
116  QUrlQuery params;
117  params.addQueryItem("mode","list");
118 
119  if (!_token.isEmpty())
120  params.addQueryItem("vfscurltoken",_token);
121 
122  //VFS_request *s = r->getCallback(this);
123  r->_isCallback = true; //defer the response as if there were a callback.
124 
125  QNetworkRequest request(_url);
126  request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");
127 
128  QNetworkReply *p = _manager.post(request,params.query().toUtf8());
129 
130  _requests[p] = r;
131 }
132 
133 
141 void VFS_curlauth::replyFinished(QNetworkReply *reply)
142 {
143  if (_requests.contains(reply))
144  {
145  VFS_request *r = _requests.take(reply);
146 
147  if (reply->error())
148  {
149  r->_reason = QString("Curlauth error: %1").arg(reply->errorString());
150  r->_success = false;
151  }
152  else
153  {
154  QByteArray response = reply->readAll();
155  //printf("received: %s\n",qUtf8Printable(response));
156 
157  QJsonParseError error;
158  QJsonDocument doc = QJsonDocument::fromJson(response,&error);
159  if (error.error == QJsonParseError::NoError)
160  {
161  switch(r->_requestType)
162  {
163  case VFS_request::read: {
164  QJsonObject o = doc.object();
165  QJsonObject d = r->_data.object();
166 
167  if (o["valid"].toBool() && o.contains("username"))
168  {
169  //d["username"] = d["username"];
170  d["uidnumber"] = o["uidnumber"].toInt( 0 );
171  d["realname"] = o.contains("realname") ? o["realname"] : o["username"];
172 
173  d["groups"] = o.contains("groups") ? o["groups"].toArray() : QJsonArray();
174 
175  //d["type"] = d["type"].toString("default");
176 
177  r->_data.setObject(d);
178 
179  r->_success = true;
180  r->_user = o["username"].toString();
181  }
182  else
183  {
184  //printf("CURLAUTH NOT VALID!\n");
185  if (o.contains("error"))
186  r->_reason = "Curlauth error: "+o["error"].toString();
187  else
188  r->_reason = "Unspecified curlauth error";
189 
190  r->_success = false;
191  r->_user = d["username"].toString();
192  }
193  }
194  break;
195 
196  case VFS_request::ls: {
197  QJsonObject o = doc.object();
198 
199  if (o["valid"].toBool() && o.contains("users"))
200  {
201  QJsonObject u = r->_data.object();
202  //u["curlauth"] = o["users"].toObject();
203  u[r->_initialPath] = o["users"].toObject();
204 
205  r->_data.setObject(u);
206  r->_success = true;
207  }
208  else
209  {
210  //printf("CURLAUTH NOT VALID!\n");
211  if (o.contains("error"))
212  r->_reason = o["error"].toString();
213  else
214  r->_reason = "Unspecified curlauth error";
215 
216  r->_success = false;
217  }
218  }
219  break;
220 
221  default: r->_reason = QString("Unknown curlauth type: %2 (%1)").arg(r->_requestType).arg(VFS_request::requestTypeStrings[r->_requestType]);
222  r->_success = false;
223  break;
224  }
225 
226 
227  }
228  else
229  {
230  r->_success = false;
231  r->_reason = QString("JSON parse error in respone to curl request at '%1': %2\n%3").arg(_url.toString()).arg(error.errorString()).arg(QString(response));
232  }
233  }
234 
235  issueResponse(r);
236  }
237  else
238  {
239  VFS::ERROR( QString("Unable to find a VFS_request for network reply on \"%1\". If there was a request, it will not be deleted and will leak memory.").arg(reply->url().toString()), 0, className() );
240  }
241 
242  reply->deleteLater();
243 }
244 
251 void VFS_curlauth::sslErrors(QNetworkReply *reply, QList<QSslError> errors)
252 {
253  for (int i=0;i<errors.size();i++)
254  VFS::ERROR( errors.at(i).errorString(), 0, className() );
255 
256  replyFinished(reply);
257 }
The base class for authenticating users.
Definition: VFS_auth.h:7
virtual ~VFS_curlauth()
QNetworkAccessManager _manager
The curl connection manager.
Definition: VFS_curlauth.h:25
void sslErrors(QNetworkReply *reply, QList< QSslError > errors)
An ssl error has occurred...
QMap< QNetworkReply *, VFS_request * > _requests
A map of outstanding VFS_request objects to their QNetworkReply objects.
Definition: VFS_curlauth.h:26
virtual void ls(VFS_request *r)
List the users available for this auth method.
virtual void read(VFS_request *r)
Perform an authentication request by read()ing from this node, which will curl the _url via http POST...
QUrl _url
The url to curl.
Definition: VFS_curlauth.h:24
Q_INVOKABLE VFS_curlauth(QString url, QString token="")
void replyFinished(QNetworkReply *reply)
A network request has completed.
QString _token
A token sent when requesting a listing from a remote url.
Definition: VFS_curlauth.h:27
virtual void issueResponse(VFS_request *t)
Once a request has been completed, issue a response.
Definition: VFS_node.cpp:1981
QString className()
Return the class name of a node.
Definition: VFS_node.cpp:2039
void finished(bool andDelete=false)
Emitted if a thread fails to create its node, or a node is rm()'d, or any other reason a node has com...
The base class for all requests between nodes.
Definition: VFS_node.h:54
static const char * requestTypeStrings[]
A printable string for each request type.
Definition: VFS_node.h:127
@ read
read full contents (4)
Definition: VFS_node.h:68
@ ls
list children of a node (1)
Definition: VFS_node.h:65
requestType _requestType
the action this request is performing or requesting
Definition: VFS_node.h:87
QString _initialPath
the target path when the request was made (relative to the responder)
Definition: VFS_node.h:93
QString _user
who initiated this request, mostly for logging
Definition: VFS_node.h:106
QString _reason
if something (probably bad) happened, this is the reason
Definition: VFS_node.h:108
bool _isCallback
whether or not to issue a response (IE, another request is chained to this request,...
Definition: VFS_node.h:98
bool _success
if the request was successfully completed
Definition: VFS_node.h:107
QJsonDocument _data
the request payload
Definition: VFS_node.h:102
static void ERROR(QString message, int level=0, QString user="server")
Send a message to the VFS::_errors VFS_stream.
Definition: VFS.cpp:307
static void WARN(QString message, int level=0, QString user="server")
Send a message to the VFS::_warnings VFS_stream.
Definition: VFS.cpp:258
url(value, options)