ATLAS Offline Software
Classes | Signals | Public Member Functions | Private Slots | Private Attributes | List of all members
VP1Authenticator Class Reference

#include <VP1Authenticator.h>

Inheritance diagram for VP1Authenticator:
Collaboration diagram for VP1Authenticator:

Classes

class  Imp
 

Signals

void authenticationSuccessful (QNetworkAccessManager *)
 

Public Member Functions

 VP1Authenticator (QWidget *, QString)
 
virtual ~VP1Authenticator ()
 
bool connectToServer ()
 
QNetworkAccessManager * networkAccessManager ()
 

Private Slots

void finished ()
 
void error (QNetworkReply::NetworkError)
 
void sslErrors (const QList< QSslError > &)
 
void loginClicked ()
 

Private Attributes

Impm_d
 

Detailed Description

Definition at line 28 of file VP1Authenticator.h.

Constructor & Destructor Documentation

◆ VP1Authenticator()

VP1Authenticator::VP1Authenticator ( QWidget *  parent,
QString  fileInfoUrl 
)

Definition at line 136 of file VP1Authenticator.cxx.

137  : QDialog(parent)
138  , m_d(new Imp(this,fileInfoUrl))
139 {
140  setupUi(this);
141  setFixedSize(400,200);
142 
143  // Configure GUI properties
144  teditError->setVisible(false);
145  teditError->setLineWrapMode(QTextEdit::NoWrap);
146  pbtnLogin->setDefault(true);
147 
148  // Connect GUI signals to slots
149  connect(pbtnLogin,SIGNAL(clicked()),this,SLOT(loginClicked()));
150  connect(pbtnCancel,SIGNAL(clicked()),this,SLOT(reject()));
151 
152 #ifndef QT_NO_SSL
153  qRegisterMetaType<QList<QSslError> >("QList<QSslError>");
154 #endif
155 }

◆ ~VP1Authenticator()

VP1Authenticator::~VP1Authenticator ( )
virtual

Definition at line 157 of file VP1Authenticator.cxx.

158 {
159  delete m_d;
160 }

Member Function Documentation

◆ authenticationSuccessful

void VP1Authenticator::authenticationSuccessful ( QNetworkAccessManager *  )
signal

◆ connectToServer()

bool VP1Authenticator::connectToServer ( )

Definition at line 164 of file VP1Authenticator.cxx.

165 {
166  QUrl fileinfoUrl(m_d->m_fileInfoUrl);
167  QNetworkRequest netrequest(fileinfoUrl);
168  m_d->m_netreply = m_d->m_netmanager->get(netrequest);
170 
171  return true;
172 }

◆ error

void VP1Authenticator::error ( QNetworkReply::NetworkError  err)
privateslot

Definition at line 543 of file VP1Authenticator.cxx.

544 {
545  if(m_d->m_log) {
546  QString message("VP1Authenticator error. STAGE " + QString::number(m_d->stage) + ", error code: " + QString::number((int)err) + "\n");
547  QByteArray ba(message.toStdString().c_str());
548  m_d->m_log->write(ba);
549  }
550 }

◆ finished

void VP1Authenticator::finished ( )
privateslot

Definition at line 174 of file VP1Authenticator.cxx.

175 {
176  QString message("\n\nVP1Authenticator done. STAGE " + QString::number(m_d->stage) + "\n");
177 
178  QUrl redirectionUrl;
179  QList<QNetworkCookie> cookielist;
180 
181  // ******** Collect some information for the log ********
182 
183  // ** Headers
184  QVariant val = m_d->m_netreply->header(QNetworkRequest::SetCookieHeader);
185  if(val.type()==QVariant::Invalid) {
186  message += QString(" No set cookies\n");
187  } else if (!val.canConvert<QList<QNetworkCookie> >()){
188  message += QString(" Cannot convert to the list of cookies\n");
189  } else {
190  cookielist = val.value<QList<QNetworkCookie> >();
191  for(int ii=0; ii<cookielist.size(); ++ii) {
192  const QNetworkCookie& cookie = cookielist.at(ii);
193  message += (" Received cookie #" + QString::number(ii) + "\n");
194  message += (" *** Path: " + cookie.path() + "\n");
195  message += (" *** Domain: " + cookie.domain() + "\n");
196  message += (QString(" *** Secure: ") + (cookie.isSecure() ? "YES" : "NO") + "\n");
197  message += (QString(" *** Session: ") + (cookie.isSessionCookie() ? "YES" : "NO") + "\n");
198  message += (" *** Name: " + QString(cookie.name().constData()) + "\n");
199  message += (" *** Value: " + QString(cookie.value().constData()) + "\n");
200  }
201  }
202 
203  val = m_d->m_netreply->header(QNetworkRequest::ContentTypeHeader);
204  if(val.type()==QVariant::Invalid) {
205  message += QString(" No ContentType\n");
206  } else if (!val.canConvert<QString>()) {
207  message += QString(" Cannot convert Content Type to String\n");
208  } else {
209  QString conttype = val.value<QString>();
210  message += QString(" Content type: " + conttype + "\n");
211  }
212 
213  val = m_d->m_netreply->header(QNetworkRequest::ContentLengthHeader);
214  if(val.type()==QVariant::Invalid) {
215  message += QString(" No ContentLength\n");
216  } else if (!val.canConvert<int>()) {
217  message += QString(" Cannot convert Content Length to int\n");
218  } else {
219  int contlength = val.value<int>();
220  message += QString(" Content Length: " + QString::number(contlength) + "\n");
221  }
222 
223  val = m_d->m_netreply->header(QNetworkRequest::LocationHeader);
224  if(val.type()==QVariant::Invalid) {
225  message += QString(" No Location\n");
226  } else if (!val.canConvert<QUrl>()) {
227  message += QString(" Cannot convert Content Length to QUrl\n");
228  } else {
229  QUrl url = val.value<QUrl>();
230  message += QString(" Location URL " + url.toString() + "\n");
231  }
232 
233  // ** Attributes
234  val = m_d->m_netreply->attribute(QNetworkRequest::HttpStatusCodeAttribute);
235  if(val.type()==QVariant::Invalid) {
236  message += QString(" No StatusCode Attribute\n");
237  } else if (!val.canConvert<int>()) {
238  message += QString(" Cannot convert StatusCode to int\n");
239  } else {
240  int sc = val.value<int>();
241  message += QString(" StatusCode : " +QString::number(sc) + "\n");
242  }
243 
244  val = m_d->m_netreply->attribute(QNetworkRequest::RedirectionTargetAttribute);
245  if(val.type()==QVariant::Invalid) {
246  message += QString(" No Redirection Attribute\n");
247  } else if (!val.canConvert<QUrl>()) {
248  message += QString(" Cannot convert Redirection to QUrl\n");
249  } else {
250  redirectionUrl = val.value<QUrl>();
251  message += QString(" Redirection : " + redirectionUrl.toString() + "\n");
252  }
253 
254  message += QString("\n HTML response >>>>>\n");
255 
256  QByteArray logMessage(message.toStdString().c_str());
257 
258  // ** Write reply to log **
259  QByteArray ba = m_d->m_netreply->readAll();
260  logMessage = logMessage.append(ba);
261  logMessage = logMessage.append("\n<<<<< HTML response\n\n\n");
262  if(m_d->m_log)
263  m_d->m_log->write(logMessage);
264 
265 
266  // *** Stage 5:
267  // Final response from the server. It may happen that the
268  // authentication was successfull, however the user is not
269  // authorized to access the requested resource
270  //
271  // Check that...
272  if(m_d->stage==5) {
273  QString replyBody(ba.data());
274  if(replyBody.contains("authorization failed", Qt::CaseInsensitive)) {
275  QString errMessage("Authorization Failed");
276  m_d->displayError(errMessage);
277  m_d->m_netmanager->deleteLater();
278  m_d->m_netmanager = new QNetworkAccessManager();
279  m_d->stage=1;
280  m_d->m_netreply=0;
281  return;
282  }
283 
284  if(m_d->m_netreply->error()==QNetworkReply::NoError)
286  }
287 
288  // ** Check for errors **
289  if(m_d->m_netreply->error()!=QNetworkReply::NoError) {
290  QString errMessage("Network error occured during authentication phase\n");
291  errMessage += QString("Error code " + QString::number((int)m_d->m_netreply->error()) + "\nExplanation on http://doc.trolltech.com/4.4/qnetworkreply.html#NetworkError-enum");
292  m_d->displayError(errMessage);
293  m_d->stage=1;
294  return;
295  }
296 
297  // *** Stage 1:
298  // Received a reply redirecting us to login.cern.ch
299  // Take the redirection URL and issue GET request for it
300  if(m_d->stage==1) {
301  if(redirectionUrl.isEmpty() || redirectionUrl.host() != m_d->m_loginServer) {
302  QString errMessage("Wrong URL: " + m_d->m_fileInfoUrl + "\nPlease fix the URL and restart the job");
303  m_d->displayError(errMessage);
304  m_d->stage=1;
305  return;
306  } else {
307  QNetworkRequest netrequest(redirectionUrl);
308  m_d->m_netreply = m_d->m_netmanager->get(netrequest);
309  if(m_d->m_log) {
310  QByteArray baLog("Get request sent\n_______________________________________________________\n\n");
311  m_d->m_log->write(baLog);
312  }
314  m_d->stage++;
315  return;
316  }
317  }
318 
319  // *** Stage 2:
320  // Received authentication form
321  // Parse contents of the authentication form
322  // look for input tags and collect their attributes
323  if(m_d->stage==2) {
324  QString replyBody(ba.data());
325 
326  QString newRequestBody("__EVENTTARGET=&__EVENTARGUMENT=&__LASTFOCUS=");
327 
328  QStringMatcher inputStartMatcher("<input ",Qt::CaseInsensitive);
329  QStringMatcher inputEndMatcher("/>");
330 
331  int inputStart = inputStartMatcher.indexIn(replyBody,0);
332 
333  while(inputStart!=-1) {
334  int inputEnd = inputEndMatcher.indexIn(replyBody,inputStart+inputStartMatcher.pattern().size());
335  if(inputEnd==-1) // something is wrong with this tag
336  break;
337  else {
338  // Let's parse it
339  QString tag = replyBody.mid(inputStart,inputEnd-inputStart);
340  QString typeVal = m_d->getTagAttributeVal(tag,"type");
341  QString nameVal = m_d->getTagAttributeVal(tag,"name");
342  QString valueVal = m_d->getTagAttributeVal(tag,"value").replace(" ","+");
343 
344  if(QString::compare(typeVal,"text",Qt::CaseInsensitive)==0)
345  valueVal = inpPers->text();
346  else if(QString::compare(typeVal,"password",Qt::CaseInsensitive)==0)
347  valueVal = inpPhr->text();
348 
349  if(QString::compare(typeVal,"checkbox",Qt::CaseInsensitive)!=0) {
350  QByteArray encodedNameVal = QUrl::toPercentEncoding(nameVal);
351  if(QString::compare(typeVal,"submit",Qt::CaseInsensitive)==0
352  || QString::compare(typeVal,"text",Qt::CaseInsensitive)==0
353  || QString::compare(typeVal,"password",Qt::CaseInsensitive)==0 ) {
354  newRequestBody+=("&"+QString(encodedNameVal)+"="+valueVal);
355  } else {
356  QByteArray encodedValueVal = QUrl::toPercentEncoding(valueVal);
357  if(newRequestBody.size()!=0)
358  newRequestBody+="&";
359  newRequestBody+=(QString(encodedNameVal)+"="+QString(encodedValueVal));
360  }
361  }
362 
363  // move to the next input
364  inputStart = inputStartMatcher.indexIn(replyBody,inputEnd+inputEndMatcher.pattern().size());
365  }
366  }
367 
368  QByteArray newBody = newRequestBody.toUtf8();
369 
370  QString logMessage = "New Request Length: " + QString::number(newBody.size()) + "\n";
371  logMessage += ("New Request Body:\n" + newRequestBody.replace(inpPhr->text(),"xxx") + "\n");
372 
373  // Get form action
374  // !!! Hardwire this for now:
375  QString actionUrlString("https://"+m_d->m_loginServer);
376 
377  QStringMatcher actionStartMatcher("action=\"",Qt::CaseInsensitive);
378  QStringMatcher actionEndMatcher("\"");
379  int actionStart = actionStartMatcher.indexIn(replyBody,0);
380  if(actionStart!=-1) {
381  int actionEnd = actionEndMatcher.indexIn(replyBody,actionStart+actionStartMatcher.pattern().size());
382  if(actionEnd!=-1)
383  actionUrlString += replyBody.mid(actionStart+actionStartMatcher.pattern().size(),actionEnd-actionStart-actionStartMatcher.pattern().size());
384  }
385 
386  logMessage += ("New URL: " + actionUrlString + "\n");
387  QByteArray actionUrlBa(actionUrlString.toStdString().c_str());
388  QString actionUrlStringDecoded = QUrl::fromPercentEncoding(actionUrlBa);
389  logMessage += ("Decoded URL: " + actionUrlStringDecoded.replace("&amp;","&")
390  + "\n\nPost request sent\n_______________________________________________________\n\n");
391 
392  // Send Post request:
393  QNetworkRequest netrequest(QUrl(actionUrlStringDecoded.replace("&amp;","&")));
394  netrequest.setHeader(QNetworkRequest::ContentTypeHeader,"application/x-www-form-urlencoded");
395  netrequest.setHeader(QNetworkRequest::ContentLengthHeader,newBody.size());
396  m_d->m_netreply = m_d->m_netmanager->post(netrequest,newBody);
397  if(m_d->m_log) {
398  QByteArray baLog(logMessage.toStdString().c_str());
399  m_d->m_log->write(baLog);
400  }
402  m_d->stage++;
403  return;
404  }
405 
406  // *** Stage 3:
407  // Received response from the autentication attempt
408  //
409  // Check if the authentication was successful. This can be done
410  // either of these two ways:
411  // 1. Check number of set cookies, if it = 0 then authentication failed
412  // 2. Look for 'Logon failure' string in the response body
413  // We implement the option #1
414  //
415  // If the authentication considered successfull then parse contents of the
416  // response, look for input tags and collect their attributes
417  // and compose a new POST request
418  if(m_d->stage==3) {
419 
420  if(cookielist.size()==0) {
421  // Authentication failed
422  QString errMessage("Authentication failed, please try again\n");
423  m_d->displayError(errMessage);
424  m_d->stage=1;
425  return;
426  }
427 
428  QString replyBody(ba.data());
429  QByteArray excludeFromEncoding(" ");
430  QString newRequestBody("");
431 
432  QStringMatcher inputStartMatcher("<input ",Qt::CaseInsensitive);
433  QStringMatcher inputEndMatcher("/>");
434 
435  int inputStart = inputStartMatcher.indexIn(replyBody,0);
436 
437  while(inputStart!=-1) {
438 
439  // It can happen that /> is in the middle of some string, for example it can
440  // be part of value="...". We need to take this into account as well
441  int inputEnd = inputStart;
442  int quoteCount = 1; // just to be able to enter the next loop
443  int quotePos = inputStart;
444  QStringMatcher quoteMatcher("\"");
445 
446  while(quoteCount%2!=0) {
447  inputEnd = inputEndMatcher.indexIn(replyBody,quotePos);
448  if(inputEnd==-1)
449  break;
450  quoteCount = 0;
451  quotePos = inputStart;
452 
453  while(true) {
454  quotePos = quoteMatcher.indexIn(replyBody,quotePos);
455  if(quotePos==-1||quotePos>inputEnd)
456  break;
457  quoteCount++;
458  quotePos++;
459  }
460  }
461 
462  if(inputEnd==-1) // something is wrong with this tag
463  break;
464  else {
465  // Let's parse it
466  QString tag = replyBody.mid(inputStart,inputEnd-inputStart);
467  QString typeVal = m_d->getTagAttributeVal(tag,"type");
468  QString nameVal = m_d->getTagAttributeVal(tag,"name");
469  QString valueVal = m_d->getTagAttributeVal(tag,"value");
470 
471  if(QString::compare(typeVal,"text",Qt::CaseInsensitive)==0)
472  valueVal = inpPers->text();
473  else if(QString::compare(typeVal,"password",Qt::CaseInsensitive)==0)
474  valueVal = inpPhr->text();
475 
476  if(QString::compare(typeVal,"checkbox",Qt::CaseInsensitive)!=0 &&
477  QString::compare(typeVal,"submit",Qt::CaseInsensitive)!=0) {
478  QByteArray encodedNameVal = QUrl::toPercentEncoding(nameVal);
479  QString valueVal1 = valueVal.replace("&lt;","<");
480  QString valueVal2 = valueVal.replace("&quot;","\"");
481  QByteArray encodedValueVal = QUrl::toPercentEncoding(valueVal2,excludeFromEncoding);
482  if(newRequestBody.size()!=0)
483  newRequestBody+="&";
484  newRequestBody+=(QString(encodedNameVal)+"="+QString(encodedValueVal).replace(" ","+"));
485  }
486 
487  // move to the next input
488  inputStart = inputStartMatcher.indexIn(replyBody,inputEnd+inputEndMatcher.pattern().size());
489  }
490  }
491 
492  QByteArray newBody = newRequestBody.toUtf8();
493 
494  QString logMessage = "New Request Length: " + QString::number(newBody.size()) + "\n";
495  logMessage += ("New Request Body:\n" + newRequestBody + "\n");
496 
497  // Get form action
498  QString actionUrlString("");
499 
500  QStringMatcher actionStartMatcher("action=\"",Qt::CaseInsensitive);
501  QStringMatcher actionEndMatcher("\"");
502  int actionStart = actionStartMatcher.indexIn(replyBody,0);
503  if(actionStart!=-1) {
504  int actionEnd = actionEndMatcher.indexIn(replyBody,actionStart+actionStartMatcher.pattern().size());
505  if(actionEnd!=-1)
506  actionUrlString = replyBody.mid(actionStart+actionStartMatcher.pattern().size(),actionEnd-actionStart-actionStartMatcher.pattern().size());
507  }
508 
509  logMessage += ("New URL: " + actionUrlString + "\n");
510 
511  // Send Post request:
512  QNetworkRequest netrequest;
513  netrequest.setUrl(actionUrlString);
514  netrequest.setHeader(QNetworkRequest::ContentTypeHeader,"application/x-www-form-urlencoded");
515  netrequest.setHeader(QNetworkRequest::ContentLengthHeader,newBody.size());
516  m_d->m_netreply = m_d->m_netmanager->post(netrequest,newBody);
517  logMessage += ("\n\nPost request sent\n_______________________________________________________\n\n");
518  if(m_d->m_log) {
519  QByteArray baLog(logMessage.toStdString().c_str());
520  m_d->m_log->write(baLog);
521  }
523  m_d->stage++;
524  return;
525  }
526 
527  // *** Stage 4:
528  // Recieved a final redirection to the requested resource
529  // Just try to get it
530  if(m_d->stage==4) {
531  QNetworkRequest netrequest(redirectionUrl);
532  m_d->m_netreply = m_d->m_netmanager->get(netrequest);
533  if(m_d->m_log) {
534  QByteArray baLog("Get request sent\n_______________________________________________________\n\n");
535  m_d->m_log->write(baLog);
536  }
538  m_d->stage++;
539  return;
540  }
541 }

◆ loginClicked

void VP1Authenticator::loginClicked ( )
privateslot

Definition at line 567 of file VP1Authenticator.cxx.

568 {
569  // Hide error box, if visible
570  if(teditError->isVisible()) {
571  teditError->setVisible(false);
572  setFixedSize(400,200);
573  teditError->clear();
574  }
575 
576  // Set focus on the login box, if empty
577  if(inpPers->text().isEmpty()) {
578  inpPers->setFocus();
579  return;
580  }
581 
582  // Set focus on the pass box, if empty
583  if(inpPhr->text().isEmpty()) {
584  inpPhr->setFocus();
585  return;
586  }
587 
588  inpPers->setEnabled(false);
589  inpPhr->setEnabled(false);
590  connectToServer();
591 }

◆ networkAccessManager()

QNetworkAccessManager * VP1Authenticator::networkAccessManager ( )

Definition at line 593 of file VP1Authenticator.cxx.

594 {
595  return m_d->m_netmanager;
596 }

◆ sslErrors

void VP1Authenticator::sslErrors ( const QList< QSslError > &  errlist)
privateslot

Definition at line 553 of file VP1Authenticator.cxx.

554 {
555  if(m_d->m_log) {
556  QString message("VP1Authenticator SSL errors. STAGE " + QString::number(m_d->stage) + "\n");
557  for(int ii=0; ii<errlist.size(); ++ii)
558  message += (" " + QString::number((int)errlist.at(ii).error()) + ", " + errlist.at(ii).errorString() + "\n");
559  QByteArray ba(message.toStdString().c_str());
560  m_d->m_log->write(ba);
561  }
562  m_d->m_netreply->ignoreSslErrors();
563 }

Member Data Documentation

◆ m_d

Imp* VP1Authenticator::m_d
private

Definition at line 58 of file VP1Authenticator.h.


The documentation for this class was generated from the following files:
VP1Authenticator::connectToServer
bool connectToServer()
Definition: VP1Authenticator.cxx:164
Amg::compare
std::pair< int, int > compare(const AmgSymMatrix(N) &m1, const AmgSymMatrix(N) &m2, double precision=1e-9, bool relative=false)
compare two matrices, returns the indices of the first element that fails the condition,...
Definition: EventPrimitivesHelpers.h:109
VP1Authenticator::Imp::m_fileInfoUrl
QString m_fileInfoUrl
Definition: VP1Authenticator.cxx:45
VP1Authenticator::Imp::m_netmanager
QNetworkAccessManager * m_netmanager
Definition: VP1Authenticator.cxx:40
fillPileUpNoiseLumi.connect
string connect
Definition: fillPileUpNoiseLumi.py:70
VP1Authenticator::Imp::m_netreply
QNetworkReply * m_netreply
Definition: VP1Authenticator.cxx:41
VP1Authenticator::Imp::stage
int stage
Definition: VP1Authenticator.cxx:44
ReweightUtils.message
message
Definition: ReweightUtils.py:15
physics_parameters.url
string url
Definition: physics_parameters.py:27
AthenaPoolTestRead.sc
sc
Definition: AthenaPoolTestRead.py:27
VP1Authenticator::loginClicked
void loginClicked()
Definition: VP1Authenticator.cxx:567
dqt_zlumi_pandas.err
err
Definition: dqt_zlumi_pandas.py:193
VP1Authenticator::Imp::displayError
void displayError(QString)
Definition: VP1Authenticator.cxx:120
test_pyathena.parent
parent
Definition: test_pyathena.py:15
VP1Authenticator::Imp::m_loginServer
QString m_loginServer
Definition: VP1Authenticator.cxx:46
Muon::NoError
@ NoError
Definition: RpcByteStreamErrorContainer.h:31
python.selection.number
number
Definition: selection.py:20
VP1Authenticator::Imp::m_log
QFile * m_log
Definition: VP1Authenticator.cxx:42
VP1Authenticator::authenticationSuccessful
void authenticationSuccessful(QNetworkAccessManager *)
Pythia8_RapidityOrderMPI.val
val
Definition: Pythia8_RapidityOrderMPI.py:14
VP1Authenticator::m_d
Imp * m_d
Definition: VP1Authenticator.h:57
CaloCondBlobAlgs_fillNoiseFromASCII.tag
string tag
Definition: CaloCondBlobAlgs_fillNoiseFromASCII.py:24
VP1Authenticator::Imp::getTagAttributeVal
QString getTagAttributeVal(const QString &tag, const QString &attribute)
Definition: VP1Authenticator.cxx:91
VP1Authenticator::Imp::connectToAuthenticator
void connectToAuthenticator(VP1Authenticator *authenticator)
Definition: VP1Authenticator.cxx:108