コード例 #1
0
/** @short Prepare a network request

This function handles delegating access to the other body parts using various schemes (ie. the special trojita-imap:// one used
by Trojita for internal purposes and the cid: one for referencing to other body parts).  Policy checks for filtering access to
the public Internet are also performed at this level.
*/
QNetworkReply *MsgPartNetAccessManager::createRequest(Operation op, const QNetworkRequest &req, QIODevice *outgoingData)
{
    Q_UNUSED(op);
    Q_UNUSED(outgoingData);

    if (!message.isValid()) {
        // Our message got removed in the meanwhile
        // FIXME: add a better class here
        return new Imap::Network::ForbiddenReply(this);
    }

    Q_ASSERT(message.isValid());
    const Mailbox::Model *constModel = 0;
    Mailbox::Model::realTreeItem(message, &constModel);
    Q_ASSERT(constModel);
    Mailbox::Model *model = const_cast<Mailbox::Model *>(constModel);
    Q_ASSERT(model);
    Imap::Mailbox::TreeItemPart *part = pathToPart(message, req.url().path());
    QModelIndex partIndex = part ? part->toIndex(model) : QModelIndex();

    if (req.url().scheme() == QLatin1String("trojita-imap") && req.url().host() == QLatin1String("msg")) {
        // Internal Trojita reference
        if (part) {
            return new Imap::Network::MsgPartNetworkReply(this, partIndex);
        } else {
            qDebug() << "No such part:" << req.url();
            return new Imap::Network::ForbiddenReply(this);
        }
    } else if (req.url().scheme() == QLatin1String("cid")) {
        // The cid: scheme for cross-part references
        QByteArray cid = req.url().path().toUtf8();
        if (!cid.startsWith("<"))
            cid = QByteArray("<") + cid;
        if (!cid.endsWith(">"))
            cid += ">";
        Imap::Mailbox::TreeItemPart *target = cidToPart(cid, model, model->realTreeItem(message));
        if (target) {
            return new Imap::Network::MsgPartNetworkReply(this, target->toIndex(model));
        } else {
            qDebug() << "Content-ID not found" << cid;
            return new Imap::Network::ForbiddenReply(this);
        }
    } else if (req.url() == QUrl(QLatin1String("about:blank"))) {
        // about:blank is a relatively harmless URL which is used for opening an empty page
        return QNetworkAccessManager::createRequest(op, req, outgoingData);
    } else if (req.url().scheme() == QLatin1String("data")) {
        // data: scheme shall be safe, it's just a method of local access after all
        return QNetworkAccessManager::createRequest(op, req, outgoingData);
    } else {
        // Regular access -- we've got to check policy here
        if (req.url().scheme() == QLatin1String("http") || req.url().scheme() == QLatin1String("https")) {
            if (externalsEnabled) {
                return QNetworkAccessManager::createRequest(op, req, outgoingData);
            } else {
                emit requestingExternal(req.url());
                return new Imap::Network::ForbiddenReply(this);
            }
        } else {
            qDebug() << "Forbidden per policy:" << req.url();
            return new Imap::Network::ForbiddenReply(this);
        }
    }
}
コード例 #2
0
ファイル: MessageView.cpp プロジェクト: G-shadow/trojita
MessageView::MessageView(QWidget *parent, QSettings *settings): QWidget(parent), m_settings(settings)
{
    QPalette pal = palette();
    pal.setColor(backgroundRole(), palette().color(QPalette::Active, QPalette::Base));
    pal.setColor(foregroundRole(), palette().color(QPalette::Active, QPalette::Text));
    setPalette(pal);
    setAutoFillBackground(true);
    setFocusPolicy(Qt::StrongFocus); // not by the wheel
    netAccess = new Imap::Network::MsgPartNetAccessManager(this);
    connect(netAccess, SIGNAL(requestingExternal(QUrl)), this, SLOT(externalsRequested(QUrl)));
    factory = new PartWidgetFactory(netAccess, this);

    emptyView = new EmbeddedWebView(this, new QNetworkAccessManager(this));
    emptyView->setFixedSize(450,300);
    QMetaObject::invokeMethod(emptyView, "handlePageLoadFinished", Qt::QueuedConnection);
    emptyView->setPage(new UserAgentWebPage(emptyView));
    emptyView->installEventFilter(this);
    emptyView->setAutoFillBackground(false);

    viewer = emptyView;

    //BEGIN create header section

    headerSection = new QWidget(this);

    // we create a dummy header, pass it through the style and the use it's color roles so we
    // know what headers in general look like in the system
    QHeaderView helpingHeader(Qt::Horizontal);
    helpingHeader.ensurePolished();
    pal = headerSection->palette();
    pal.setColor(headerSection->backgroundRole(), palette().color(QPalette::Active, helpingHeader.backgroundRole()));
    pal.setColor(headerSection->foregroundRole(), palette().color(QPalette::Active, helpingHeader.foregroundRole()));
    headerSection->setPalette(pal);
    headerSection->setAutoFillBackground(true);

    // the actual mail header
    m_envelope = new EnvelopeView(headerSection, this);

    // the tag bar
    tags = new TagListWidget(headerSection);
    tags->setBackgroundRole(helpingHeader.backgroundRole());
    tags->setForegroundRole(helpingHeader.foregroundRole());
    tags->hide();
    connect(tags, SIGNAL(tagAdded(QString)), this, SLOT(newLabelAction(QString)));
    connect(tags, SIGNAL(tagRemoved(QString)), this, SLOT(deleteLabelAction(QString)));

    // whether we allow to load external elements
    externalElements = new ExternalElementsWidget(this);
    externalElements->hide();
    connect(externalElements, SIGNAL(loadingEnabled()), this, SLOT(externalsEnabled()));

    // layout the header
    layout = new QVBoxLayout(headerSection);
    layout->addWidget(m_envelope, 1);
    layout->addWidget(tags, 3);
    layout->addWidget(externalElements, 1);

    //END create header section

    //BEGIN layout the message

    layout = new QVBoxLayout(this);
    layout->setSpacing(0);
    layout->setContentsMargins(0,0,0,0);

    layout->addWidget(headerSection, 1);

    headerSection->hide();

    // put the actual messages into an extra horizontal view
    // this allows us easy usage of the trailing stretch and also to indent the message a bit
    QHBoxLayout *hLayout = new QHBoxLayout;
    hLayout->setContentsMargins(6,6,6,0);
    hLayout->addWidget(viewer);
    static_cast<QVBoxLayout*>(layout)->addLayout(hLayout, 1);
    // add a strong stretch to squeeze header and message to the top
    // possibly passing a large stretch factor to the message could be enough...
    layout->addStretch(1000);

    //END layout the message

    // make the layout used to add messages our new horizontal layout
    layout = hLayout;

    markAsReadTimer = new QTimer(this);
    markAsReadTimer->setSingleShot(true);
    connect(markAsReadTimer, SIGNAL(timeout()), this, SLOT(markAsRead()));

    m_loadingSpinner = new Spinner(this);
    m_loadingSpinner->setText(tr("Fetching\nMessage"));
    m_loadingSpinner->setType(Spinner::Sun);
}