Commit 471f6371 authored by Fabio Bas's avatar Fabio Bas
Browse files

More work

 * Refactored code out of common/ into servatrice/
 * added smtp client library
 * disable registration when connected
 * validate email address
 * send activation token via email
parent 8cf44616
......@@ -104,11 +104,13 @@ void MainWindow::statusChanged(ClientStatus _status)
tabSupervisor->stop();
aSinglePlayer->setEnabled(true);
aConnect->setEnabled(true);
aRegister->setEnabled(true);
aDisconnect->setEnabled(false);
break;
case StatusLoggingIn:
aSinglePlayer->setEnabled(false);
aConnect->setEnabled(false);
aRegister->setEnabled(false);
aDisconnect->setEnabled(true);
break;
case StatusConnecting:
......@@ -179,6 +181,7 @@ void MainWindow::actSinglePlayer()
return;
aConnect->setEnabled(false);
aRegister->setEnabled(false);
aSinglePlayer->setEnabled(false);
localServer = new LocalServer(this);
......@@ -226,6 +229,7 @@ void MainWindow::localGameEnded()
localServer = 0;
aConnect->setEnabled(true);
aRegister->setEnabled(true);
aSinglePlayer->setEnabled(true);
}
......@@ -336,7 +340,7 @@ void MainWindow::registerError(Response::ResponseCode r, QString reasonStr, quin
QMessageBox::critical(this, tr("Registration denied"), tr("There is already an existing account with the same user name."));
break;
case Response::RespEmailRequiredToRegister:
QMessageBox::critical(this, tr("Registration denied"), tr("It's mandatory to specify an email when registering."));
QMessageBox::critical(this, tr("Registration denied"), tr("It's mandatory to specify a valid email address when registering."));
break;
case Response::RespTooManyRequests:
QMessageBox::critical(this, tr("Registration denied"), tr("Too many registration attempts from your IP address."));
......
......@@ -175,64 +175,6 @@ AuthenticationResult Server::loginUser(Server_ProtocolHandler *session, QString
return authState;
}
RegistrationResult Server::registerUserAccount(const QString &ipAddress, const Command_Register &cmd, QString &banReason, int &banSecondsRemaining)
{
if (!registrationEnabled)
return RegistrationDisabled;
QString emailAddress = QString::fromStdString(cmd.email());
if (requireEmailForRegistration && emailAddress.isEmpty())
return EmailRequired;
Server_DatabaseInterface *databaseInterface = getDatabaseInterface();
// TODO: Move this method outside of the db interface
QString userName = QString::fromStdString(cmd.user_name());
if (!databaseInterface->usernameIsValid(userName))
return InvalidUsername;
if(databaseInterface->userExists(userName))
return UserAlreadyExists;
if (databaseInterface->checkUserIsBanned(ipAddress, userName, banReason, banSecondsRemaining))
return ClientIsBanned;
if (tooManyRegistrationAttempts(ipAddress))
return TooManyRequests;
QString realName = QString::fromStdString(cmd.real_name());
ServerInfo_User_Gender gender = cmd.gender();
QString country = QString::fromStdString(cmd.country());
QString password = QString::fromStdString(cmd.password());
if(password.length() < 6)
return PasswordTooShort;
bool regSucceeded = databaseInterface->registerUser(userName, realName, gender, password, emailAddress, country, !requireEmailForRegistration);
if(regSucceeded)
return requireEmailForRegistration ? AcceptedNeedsActivation : Accepted;
else
return Failed;
}
bool Server::activateUserAccount(const Command_Activate &cmd)
{
QString userName = QString::fromStdString(cmd.user_name());
QString token = QString::fromStdString(cmd.token());
Server_DatabaseInterface *databaseInterface = getDatabaseInterface();
return databaseInterface->activateUser(userName, token);
}
bool Server::tooManyRegistrationAttempts(const QString &ipAddress)
{
// TODO: implement
Q_UNUSED(ipAddress);
return false;
}
void Server::addPersistentPlayer(const QString &userName, int roomId, int gameId, int playerId)
{
QWriteLocker locker(&persistentPlayersLock);
......
......@@ -29,7 +29,6 @@ class CommandContainer;
class Command_JoinGame;
enum AuthenticationResult { NotLoggedIn, PasswordRight, UnknownUser, WouldOverwriteOldSession, UserIsBanned, UsernameInvalid, RegistrationRequired, UserIsInactive };
enum RegistrationResult { Accepted, UserAlreadyExists, EmailRequired, TooManyRequests, InvalidUsername, ClientIsBanned, RegistrationDisabled, Failed, PasswordTooShort, AcceptedNeedsActivation };
class Server : public QObject
{
......@@ -47,19 +46,6 @@ public:
void setThreaded(bool _threaded) { threaded = _threaded; }
AuthenticationResult loginUser(Server_ProtocolHandler *session, QString &name, const QString &password, QString &reason, int &secondsLeft);
/**
* Registers a user account.
* @param ipAddress The address of the connection from the user
* @param userName The username to attempt to register
* @param emailAddress The email address to associate with the new account (and to use for activation)
* @param banReason If the client is banned, the reason for the ban will be included in this string.
* @param banSecondsRemaining If the client is banned, the time left will be included in this. 0 if the ban is permanent.
* @return RegistrationResult member indicating whether it succeeded or failed.
*/
RegistrationResult registerUserAccount(const QString &ipAddress, const Command_Register &cmd, QString &banReason, int &banSecondsRemaining);
bool activateUserAccount(const Command_Activate &cmd);
bool tooManyRegistrationAttempts(const QString &ipAddress);
const QMap<int, Server_Room *> &getRooms() { return rooms; }
Server_AbstractUserInterface *findUser(const QString &userName) const;
......@@ -131,9 +117,6 @@ protected:
int getUsersCount() const;
int getGamesCount() const;
void addRoom(Server_Room *newRoom);
bool registrationEnabled;
bool requireEmailForRegistration;
};
#endif
......@@ -9,7 +9,6 @@
#include "pb/commands.pb.h"
#include "pb/response.pb.h"
#include "pb/response_login.pb.h"
#include "pb/response_register.pb.h"
#include "pb/response_list_users.pb.h"
#include "pb/response_get_games_of_user.pb.h"
#include "pb/response_get_user_info.pb.h"
......@@ -145,8 +144,6 @@ Response::ResponseCode Server_ProtocolHandler::processSessionCommandContainer(co
switch ((SessionCommand::SessionCommandType) num) {
case SessionCommand::PING: resp = cmdPing(sc.GetExtension(Command_Ping::ext), rc); break;
case SessionCommand::LOGIN: resp = cmdLogin(sc.GetExtension(Command_Login::ext), rc); break;
case SessionCommand::REGISTER: resp = cmdRegisterAccount(sc.GetExtension(Command_Register::ext), rc); break;
case SessionCommand::ACTIVATE: resp = cmdActivateAccount(sc.GetExtension(Command_Activate::ext), rc); break;
case SessionCommand::MESSAGE: resp = cmdMessage(sc.GetExtension(Command_Message::ext), rc); break;
case SessionCommand::GET_GAMES_OF_USER: resp = cmdGetGamesOfUser(sc.GetExtension(Command_GetGamesOfUser::ext), rc); break;
case SessionCommand::GET_USER_INFO: resp = cmdGetUserInfo(sc.GetExtension(Command_GetUserInfo::ext), rc); break;
......@@ -421,64 +418,6 @@ Response::ResponseCode Server_ProtocolHandler::cmdLogin(const Command_Login &cmd
return Response::RespOk;
}
Response::ResponseCode Server_ProtocolHandler::cmdRegisterAccount(const Command_Register &cmd, ResponseContainer &rc)
{
qDebug() << "Got register command: " << QString::fromStdString(cmd.user_name());
QString banReason;
int banSecondsRemaining;
RegistrationResult result =
server->registerUserAccount(
this->getAddress(),
cmd,
banReason,
banSecondsRemaining);
qDebug() << "Register command result:" << result;
switch (result) {
case RegistrationDisabled:
return Response::RespRegistrationDisabled;
case Accepted:
return Response::RespRegistrationAccepted;
case AcceptedNeedsActivation:
// TODO SEND EMAIL WITH TOKEN TO THE USER
return Response::RespRegistrationAcceptedNeedsActivation;
case UserAlreadyExists:
return Response::RespUserAlreadyExists;
case EmailRequired:
return Response::RespEmailRequiredToRegister;
case TooManyRequests:
return Response::RespTooManyRequests;
case PasswordTooShort:
return Response::RespPasswordTooShort;
case InvalidUsername:
return Response::RespUsernameInvalid;
case Failed:
return Response::RespRegistrationFailed;
case ClientIsBanned:
Response_Register *re = new Response_Register;
re->set_denied_reason_str(banReason.toStdString());
if (banSecondsRemaining != 0)
re->set_denied_end_time(QDateTime::currentDateTime().addSecs(banSecondsRemaining).toTime_t());
rc.setResponseExtension(re);
return Response::RespUserIsBanned;
}
return Response::RespInvalidCommand;
}
Response::ResponseCode Server_ProtocolHandler::cmdActivateAccount(const Command_Activate &cmd, ResponseContainer & /*rc*/)
{
if(server->activateUserAccount(cmd))
{
qDebug() << "Accepted activation for user" << QString::fromStdString(cmd.user_name());
return Response::RespActivationAccepted;
} else {
qDebug() << "Failed activation for user" << QString::fromStdString(cmd.user_name());
return Response::RespActivationFailed;
}
}
Response::ResponseCode Server_ProtocolHandler::cmdMessage(const Command_Message &cmd, ResponseContainer &rc)
{
if (authState == NotLoggedIn)
......
......@@ -60,8 +60,6 @@ private:
Response::ResponseCode cmdPing(const Command_Ping &cmd, ResponseContainer &rc);
Response::ResponseCode cmdLogin(const Command_Login &cmd, ResponseContainer &rc);
Response::ResponseCode cmdRegisterAccount(const Command_Register &cmd, ResponseContainer &rc);
Response::ResponseCode cmdActivateAccount(const Command_Activate &cmd, ResponseContainer & /* rc */);
Response::ResponseCode cmdMessage(const Command_Message &cmd, ResponseContainer &rc);
Response::ResponseCode cmdGetGamesOfUser(const Command_GetGamesOfUser &cmd, ResponseContainer &rc);
Response::ResponseCode cmdGetUserInfo(const Command_GetUserInfo &cmd, ResponseContainer &rc);
......@@ -101,6 +99,7 @@ public:
void sendProtocolItem(const SessionEvent &item);
void sendProtocolItem(const GameEventContainer &item);
void sendProtocolItem(const RoomEvent &item);
};
#endif
......@@ -15,6 +15,18 @@ SET(servatrice_SOURCES
src/settingscache.cpp
src/isl_interface.cpp
${VERSION_STRING_CPP}
src/smtp/emailaddress.cpp
src/smtp/mimeattachment.cpp
src/smtp/mimecontentformatter.cpp
src/smtp/mimefile.cpp
src/smtp/mimehtml.cpp
src/smtp/mimeinlinefile.cpp
src/smtp/mimemessage.cpp
src/smtp/mimemultipart.cpp
src/smtp/mimepart.cpp
src/smtp/mimetext.cpp
src/smtp/quotedprintable.cpp
src/smtp/smtpclient.cpp
)
set(servatrice_RESOURCES servatrice.qrc)
......
......@@ -65,6 +65,39 @@ regonly=0
; to get their account activated. Default true.
;requireemail=true
[smtp]
; Connectin type: currently supported method are "tcp", "ssl" and "tls"
connection=tcp
; Auth type: currently supported method are "plain" and "login"
auth=plain
; Hostname or IP addres of the smtp server
host=localhost
; Smtp port number of the smtp server. Usual values are 25 or 587 for tcp, 465 for ssl
port=25
; Username: this typically matches the "from" email address
username=root@localhost
; Password for the username
password=foobar
; Sender email address: the "from" email address
email=root@localhost
; Sender email name
name="Cockatrice server"
; Email subject
subject="Cockatrice server account activation token"
; Email body. You can use these tags here: %username %token
; They will be substituted with the actual values in the email
;
body="Hi %username, thank our for registering on our Cockatrice server\r\nHere's the activation token you need to supply for activatin your account:\r\n\r\n%token\r\n\r\nHappy gaming!"
[database]
......
......@@ -160,8 +160,8 @@ bool Servatrice::initServer()
authenticationMethod = AuthenticationNone;
}
registrationEnabled = settingsCache->value("registration/enabled", false).toBool();
requireEmailForRegistration = settingsCache->value("registration/requireemail", true).toBool();
bool registrationEnabled = settingsCache->value("registration/enabled", false).toBool();
bool requireEmailForRegistration = settingsCache->value("registration/requireemail", true).toBool();
qDebug() << "Registration enabled: " << registrationEnabled;
if (registrationEnabled)
......
......@@ -111,13 +111,13 @@ bool Servatrice_DatabaseInterface::getRequireRegistration()
return settingsCache->value("authentication/regonly", 0).toBool();
}
bool Servatrice_DatabaseInterface::registerUser(const QString &userName, const QString &realName, ServerInfo_User_Gender const &gender, const QString &password, const QString &emailAddress, const QString &country, bool active)
bool Servatrice_DatabaseInterface::registerUser(const QString &userName, const QString &realName, ServerInfo_User_Gender const &gender, const QString &password, const QString &emailAddress, const QString &country, QString &token, bool active)
{
if (!checkSql())
return false;
QString passwordSha512 = PasswordHasher::computeHash(password, PasswordHasher::generateRandomSalt());
QString token = PasswordHasher::generateActivationToken();
token = active ? QString() : PasswordHasher::generateActivationToken();
QSqlQuery *query = prepareQuery("insert into {prefix}_users "
"(name, realname, gender, password_sha512, email, country, registrationDate, active, token) "
......
......@@ -25,9 +25,7 @@ private:
bool checkUserIsNameBanned(QString const &userName, QString &banReason, int &banSecondsRemaining);
QChar getGenderChar(ServerInfo_User_Gender const &gender);
protected:
bool usernameIsValid(const QString &user);
AuthenticationResult checkUserPassword(Server_ProtocolHandler *handler, const QString &user, const QString &password, QString &reasonStr, int &secondsLeft);
bool checkUserIsBanned(const QString &ipAddress, const QString &userName, QString &banReason, int &banSecondsRemaining);
public slots:
void initDatabase(const QSqlDatabase &_sqlDatabase);
public:
......@@ -62,9 +60,11 @@ public:
void lockSessionTables();
void unlockSessionTables();
bool userSessionExists(const QString &userName);
bool usernameIsValid(const QString &user);
bool checkUserIsBanned(const QString &ipAddress, const QString &userName, QString &banReason, int &banSecondsRemaining);
bool getRequireRegistration();
bool registerUser(const QString &userName, const QString &realName, ServerInfo_User_Gender const &gender, const QString &password, const QString &emailAddress, const QString &country, bool active = false);
bool registerUser(const QString &userName, const QString &realName, ServerInfo_User_Gender const &gender, const QString &password, const QString &emailAddress, const QString &country, QString &token, bool active = false);
bool activateUser(const QString &userName, const QString &token);
void logMessage(const int senderId, const QString &senderName, const QString &senderIp, const QString &logMessage, LogMessage_TargetType targetType, const int targetId, const QString &targetName);
......
......@@ -51,12 +51,15 @@
#include "pb/response_deck_list.pb.h"
#include "pb/response_deck_download.pb.h"
#include "pb/response_deck_upload.pb.h"
#include "pb/response_register.pb.h"
#include "pb/response_replay_list.pb.h"
#include "pb/response_replay_download.pb.h"
#include "pb/serverinfo_replay.pb.h"
#include "pb/serverinfo_user.pb.h"
#include "pb/serverinfo_deckstorage.pb.h"
#include "smtp/SmtpMime"
#include "version_string.h"
#include <string>
#include <iostream>
......@@ -267,6 +270,8 @@ Response::ResponseCode ServerSocketInterface::processExtendedSessionCommand(int
case SessionCommand::REPLAY_DOWNLOAD: return cmdReplayDownload(cmd.GetExtension(Command_ReplayDownload::ext), rc);
case SessionCommand::REPLAY_MODIFY_MATCH: return cmdReplayModifyMatch(cmd.GetExtension(Command_ReplayModifyMatch::ext), rc);
case SessionCommand::REPLAY_DELETE_MATCH: return cmdReplayDeleteMatch(cmd.GetExtension(Command_ReplayDeleteMatch::ext), rc);
case SessionCommand::REGISTER: return cmdRegisterAccount(cmd.GetExtension(Command_Register::ext), rc); break;
case SessionCommand::ACTIVATE: return cmdActivateAccount(cmd.GetExtension(Command_Activate::ext), rc); break;
default: return Response::RespFunctionNotAllowed;
}
}
......@@ -764,6 +769,179 @@ Response::ResponseCode ServerSocketInterface::cmdBanFromServer(const Command_Ban
return Response::RespOk;
}
Response::ResponseCode ServerSocketInterface::cmdRegisterAccount(const Command_Register &cmd, ResponseContainer &rc)
{
QString userName = QString::fromStdString(cmd.user_name());
qDebug() << "Got register command: " << userName;
bool registrationEnabled = settingsCache->value("registration/enabled", false).toBool();
if (!registrationEnabled)
return Response::RespRegistrationDisabled;
QString emailAddress = QString::fromStdString(cmd.email());
bool requireEmailForRegistration = settingsCache->value("registration/requireemail", true).toBool();
if (requireEmailForRegistration)
{
QRegExp rx("\\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,4}\\b");
if(emailAddress.isEmpty() || !rx.exactMatch(emailAddress))
return Response::RespEmailRequiredToRegister;
}
// TODO: Move this method outside of the db interface
if (!sqlInterface->usernameIsValid(userName))
return Response::RespUsernameInvalid;
if(sqlInterface->userExists(userName))
return Response::RespUserAlreadyExists;
QString banReason;
int banSecondsRemaining;
if (sqlInterface->checkUserIsBanned(this->getAddress(), userName, banReason, banSecondsRemaining))
{
Response_Register *re = new Response_Register;
re->set_denied_reason_str(banReason.toStdString());
if (banSecondsRemaining != 0)
re->set_denied_end_time(QDateTime::currentDateTime().addSecs(banSecondsRemaining).toTime_t());
rc.setResponseExtension(re);
return Response::RespUserIsBanned;
}
if (tooManyRegistrationAttempts(this->getAddress()))
return Response::RespTooManyRequests;
QString realName = QString::fromStdString(cmd.real_name());
ServerInfo_User_Gender gender = cmd.gender();
QString country = QString::fromStdString(cmd.country());
QString password = QString::fromStdString(cmd.password());
// TODO make this configurable?
if(password.length() < 6)
return Response::RespPasswordTooShort;
QString token;
bool regSucceeded = sqlInterface->registerUser(userName, realName, gender, password, emailAddress, country, token, !requireEmailForRegistration);
if(regSucceeded)
{
qDebug() << "Accepted register command for user: " << userName;
if(requireEmailForRegistration)
{
// TODO call a slot on another thread to send email
sendActivationTokenMail(userName, emailAddress, token);
return Response::RespRegistrationAcceptedNeedsActivation;
} else {
return Response::RespRegistrationAccepted;
}
} else {
return Response::RespRegistrationFailed;
}
}
bool ServerSocketInterface::sendActivationTokenMail(const QString &nickname, const QString &recipient, const QString &token)
{
QString tmp = settingsCache->value("smtp/connection", "tcp").toString();
SmtpClient::ConnectionType connection = SmtpClient::TcpConnection;
if(tmp == "ssl")
connection = SmtpClient::SslConnection;
else if(tmp == "tls")
connection = SmtpClient::TlsConnection;
tmp = settingsCache->value("smtp/auth", "plain").toString();
SmtpClient::AuthMethod auth = SmtpClient::AuthPlain;
if(tmp == "login")
auth = SmtpClient::AuthLogin;
QString host = settingsCache->value("smtp/host", "localhost").toString();
int port = settingsCache->value("smtp/port", 25).toInt();
QString username = settingsCache->value("smtp/username", "").toString();
QString password = settingsCache->value("smtp/password", "").toString();
QString email = settingsCache->value("smtp/email", "").toString();
QString name = settingsCache->value("smtp/name", "").toString();
QString subject = settingsCache->value("smtp/subject", "").toString();
QString body = settingsCache->value("smtp/body", "").toString();
if(email.isEmpty())
{
qDebug() << "[MAIL] Missing email field" << endl;
return false;
}
if(body.isEmpty())
{
qDebug() << "[MAIL] Missing body field" << endl;
return false;
}
if(recipient.isEmpty())
{
qDebug() << "[MAIL] Missing recipient field" << endl;
return false;
}
if(token.isEmpty())
{
qDebug() << "[MAIL] Missing token field" << endl;
return false;
}
SmtpClient smtp(host, port, connection);
smtp.setUser(username);
smtp.setPassword(password);
smtp.setAuthMethod(auth);
MimeMessage message;
EmailAddress sender(email, name);
message.setSender(&sender);
EmailAddress to(recipient, nickname);
message.addRecipient(&to);
message.setSubject(subject);
MimeText text;
text.setText(body.replace("%username", nickname).replace("%token", token));
message.addPart(&text);
// Now we can send the mail
if (!smtp.connectToHost()) {
qDebug() << "[MAIL] Failed to connect to host" << host << "on port" << port;
return false;
}
if (!smtp.login()) {
qDebug() << "[MAIL] Failed to login as " << username;
return false;
}
if (!smtp.sendMail(message)) {
qDebug() << "[MAIL] Failed to send mail to " << recipient;
return false;
}
smtp.quit();
qDebug() << "[MAIL] Sent activation email to " << recipient << " for nickname " << nickname;
return true;
}
bool ServerSocketInterface::tooManyRegistrationAttempts(const QString &ipAddress)
{
// TODO: implement
Q_UNUSED(ipAddress);
return false;
}
Response::ResponseCode ServerSocketInterface::cmdActivateAccount(const Command_Activate &cmd, ResponseContainer & /*rc*/)
{
QString userName = QString::fromStdString(cmd.user_name());
QString token = QString::fromStdString(cmd.token());
if(sqlInterface->activateUser(userName, token))
{
qDebug() << "Accepted activation for user" << QString::fromStdString(cmd.user_name());
return Response::RespActivationAccepted;
} else {
qDebug() << "Failed activation for user" << QString::fromStdString(cmd.user_name());
return Response::RespActivationFailed;
}
}
// ADMIN FUNCTIONS.
// Permission is checked by the calling function.
......
......@@ -59,6 +59,7 @@ signals:
void outputQueueChanged();
protected:
void logDebugMessage(const QString &message);
bool tooManyRegistrationAttempts(const QString &ipAddress);
private:
QMutex outputQueueMutex;
Servatrice *servatrice;
......@@ -91,10 +92,14 @@ private:
Response::ResponseCode cmdBanFromServer(const Command_BanFromServer &cmd, ResponseContainer &rc);
Response::ResponseCode cmdShutdownServer(const Command_ShutdownServer &cmd, ResponseContainer &rc);
Response::ResponseCode cmdUpdateServerMessage(const Command_UpdateServerMessage &cmd, ResponseContainer &rc);
Response::ResponseCode cmdRegisterAccount(const Command_Register &cmd, ResponseContainer &rc);
Response::ResponseCode cmdActivateAccount(const Command_Activate &cmd, ResponseContainer & /* rc */);
Response::ResponseCode processExtendedSessionCommand(int cmdType, const SessionCommand &cmd, ResponseContainer &rc);
Response::ResponseCode processExtendedModeratorCommand(int cmdType, const ModeratorCommand &cmd, ResponseContainer &rc);
Response::ResponseCode processExtendedAdminCommand(int cmdType, const AdminCommand &cmd, ResponseContainer &rc);
bool sendActivationTokenMail(const QString &nickname, const QString &recipient, const QString &token);
public:
ServerSocketInterface(Servatrice *_server, Servatrice_DatabaseInterface *_databaseInterface, QObject *parent = 0);
~ServerSocketInterface();
......
/*
Copyright (c) 2011-2012 - Tőkés Attila
This file is part of SmtpClient for Qt.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
See the LICENSE file for more details.
*/
#ifndef SMTPMIME_H
#define SMTPMIME_H
#include "smtpclient.h"
#include "mimepart.h"
#include "mimehtml.h"
#include "mimeattachment.h"
#include "mimemessage.h"
#include "mimetext.h"
#include "mimeinlinefile.h"
#include "mimefile.h"
#endif // SMTPMIME_H
/*
Copyright (c) 2011-2012 - Tőkés Attila
This file is part of SmtpClient for Qt.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
See the LICENSE file for more details.
*/
#include "emailaddress.h"
/* [1] Constructors and Destructors */
EmailAddress::EmailAddress(const QString & address, const QString & name)
{
this->address = address;
this->name = name;
}
EmailAddress::~EmailAddress()
{
}
/* [1] --- */
/* [2] Getters and Setters */
void EmailAddress::setName(const QString & name)
{
this->name = name;
}
void EmailAddress::setAddress(const QString & address)
{
this->address = address;
}
const QString & EmailAddress::getName() const
{
return name;
}
const QString & EmailAddress::getAddress() const
{
return address;
}
/* [2] --- */
/*
Copyright (c) 2011-2012 - Tőkés Attila
This file is part of SmtpClient for Qt.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
See the LICENSE file for more details.
*/
#ifndef EMAILADDRESS_H
#define EMAILADDRESS_H
#include <QObject>
#include "smtpexports.h"
class SMTP_EXPORT EmailAddress : public QObject
{
Q_OBJECT
public:
/* [1] Constructors and Destructors */
EmailAddress();
EmailAddress(const QString & address, const QString & name="");
~EmailAddress();
/* [1] --- */
/* [2] Getters and Setters */
void setName(const QString & name);
void setAddress(const QString & address);
const QString & getName() const;
const QString & getAddress() const;
/* [2] --- */
private:
/* [3] Private members */
QString name;
QString address;
/* [3] --- */
};
#endif // EMAILADDRESS_H
/*
Copyright (c) 2011-2012 - Tőkés Attila
This file is part of SmtpClient for Qt.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
See the LICENSE file for more details.
*/
#include "mimeattachment.h"
#include <QFileInfo>
/* [1] Constructors and Destructors */
MimeAttachment::MimeAttachment(QFile *file)
: MimeFile(file)
{
}
MimeAttachment::MimeAttachment(const QByteArray& stream, const QString& fileName): MimeFile(stream, fileName)
{
}
MimeAttachment::~MimeAttachment()
{
}
/* [1] --- */
/* [2] Protected methods */
void MimeAttachment::prepare()
{
this->header += "Content-disposition: attachment\r\n";
/* !!! IMPORTANT !!! */
MimeFile::prepare();
}
/* [2] --- */
/*
Copyright (c) 2011-2012 - Tőkés Attila
This file is part of SmtpClient for Qt.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
See the LICENSE file for more details.
*/
#ifndef MIMEATTACHMENT_H
#define MIMEATTACHMENT_H
#include <QFile>
#include "mimepart.h"
#include "mimefile.h"
#include "smtpexports.h"
class SMTP_EXPORT MimeAttachment : public MimeFile
{
Q_OBJECT
public:
/* [1] Constructors and Destructors */
MimeAttachment(QFile* file);
MimeAttachment(const QByteArray& stream, const QString& fileName);
~MimeAttachment();
/* [1] --- */
protected:
/* [2] Protected methods */
virtual void prepare();
/* [2] --- */
};
#endif // MIMEATTACHMENT_H
/*
Copyright (c) 2011-2012 - Tőkés Attila
This file is part of SmtpClient for Qt.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
See the LICENSE file for more details.
*/
#include "mimecontentformatter.h"
MimeContentFormatter::MimeContentFormatter(int max_length) :
max_length(max_length)
{}
QString MimeContentFormatter::format(const QString &content, bool quotedPrintable) const {
QString out;
int chars = 0;
for (int i = 0; i < content.length() ; ++i) {
chars++;
if (!quotedPrintable) {
if (chars > max_length) {
out.append("\r\n");
chars = 1;
}
}
else {
if (content[i] == '\n') { // new line
out.append(content[i]);
chars = 0;
continue;
}
if ((chars > max_length - 1)
|| ((content[i] == '=') && (chars > max_length - 3) )) {
out.append('=');
out.append("\r\n");
chars = 1;
}
}
out.append(content[i]);
}
return out;
}
void MimeContentFormatter::setMaxLength(int l) {
max_length = l;
}
int MimeContentFormatter::getMaxLength() const {
return max_length;
}
/*
Copyright (c) 2011-2012 - Tőkés Attila
This file is part of SmtpClient for Qt.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
See the LICENSE file for more details.
*/
#ifndef MIMECONTENTFORMATTER_H
#define MIMECONTENTFORMATTER_H
#include <QObject>
#include <QByteArray>
#include "smtpexports.h"
class SMTP_EXPORT MimeContentFormatter : public QObject
{
Q_OBJECT
public:
MimeContentFormatter (int max_length = 76);
void setMaxLength(int l);
int getMaxLength() const;
QString format(const QString &content, bool quotedPrintable = false) const;
protected:
int max_length;
};
#endif // MIMECONTENTFORMATTER_H
/*
Copyright (c) 2011-2012 - Tőkés Attila
This file is part of SmtpClient for Qt.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
See the LICENSE file for more details.
*/
#include "mimefile.h"
#include <QFileInfo>
/* [1] Constructors and Destructors */
MimeFile::MimeFile(QFile *file)
{
this->file = file;
this->cType = "application/octet-stream";
this->cName = QFileInfo(*file).fileName();
this->cEncoding = Base64;
}
MimeFile::MimeFile(const QByteArray& stream, const QString& fileName)
{
this->cEncoding = Base64;
this->cType = "application/octet-stream";
this->file = 0;
this->cName = fileName;
this->content = stream;
}
MimeFile::~MimeFile()
{
if (file)
delete file;
}
/* [1] --- */
/* [2] Getters and setters */
/* [2] --- */
/* [3] Protected methods */
void MimeFile::prepare()
{
if (this->file)
{
file->open(QIODevice::ReadOnly);
this->content = file->readAll();
file->close();
}
/* !!! IMPORTANT !!!! */
MimePart::prepare();
}
/* [3] --- */
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment