void SmtpAccountEnableCommand::Failure(const std::exception& e)
{
	if(m_msg.get())
		m_msg->replyError(MojErrInternal, e.what());

	MojLogError(m_log, "error enabling SMTP for account %s: %s", AsJsonString(m_client.GetAccountId()).c_str(), e.what());

	SmtpCommand::Failure(e);
}
void SmtpAccountEnableCommand::Done()
{
	if(m_msg.get())
		m_msg->replySuccess();

	MojLogNotice(m_log, "successfully enabled SMTP on account %s", AsJsonString(m_client.GetAccountId()).c_str());

	Complete();
}
示例#3
0
void PopSession::LoginFailure(MailError::ErrorCode errorCode, const std::string& errorMsg)
{
	// update account status
	MojLogInfo(m_log, "Login failure for account '%s': %s", AsJsonString(m_account->GetAccountId()).c_str(), errorMsg.c_str());
	// updating 'm_accountError' will be done inside the following call.
	PersistFailure(errorCode, errorMsg);

	m_state = State_CancelPendingCommands;
	CheckQueue();
}
void AuthYahooCommand::RunImpl()
{
	MojLogTrace(m_log);
	// HACK: Hard-code partner ID and fetch of NDUID
	m_partnerId.assign("mblclt11");
	
	char id[256];
	memset(id, '\0', 256);
	
	// Read nduid, if available, otherwise make a fake one and try to record it.
	FILE * nduid = fopen("/proc/nduid", "r");
	if (!nduid) {
		nduid = fopen("yahooCachedFakeDeviceId", "r");
		if (!nduid) {
			snprintf(id, 255, "FEED0BEEF479121481533145%016llX", timeMillis());
			nduid = fopen("yahooCachedFakeDeviceId", "w");
			if (nduid) {
				fputs(id, nduid);
				fclose(nduid);
				nduid = NULL;
			}
		}
	}
	
	if (nduid) {
		if (fgets(id, 255, nduid) == NULL)
			id[0] = '\0';
		
		fclose(nduid);
		nduid = NULL;

		if (strlen(id) > 0 && id[strlen(id)-1] == '\n')
			id[strlen(id)-1] = '\0';
	}
	
	m_deviceId.assign(id);

	MojLogInfo(m_log, "Temp: partnerId=%s deviceId=%s", m_partnerId.data(), m_deviceId.data());

	MojObject accountId = m_session.GetAccount()->GetAccountId();

	MojObject params;
	MojErr err = params.put("accountId", accountId);
	ErrorToException(err);

	MojString token;
	token.assign(m_session.GetAccount()->GetYahooToken().c_str());
	err = params.put("securityToken", token);
	ErrorToException(err);

	MojLogInfo(m_log, "Looking up yahoo cookies for account %s", AsJsonString(accountId).c_str());
	// TODO: Should send the request with SmtpClient instead.
	err = m_session.CreateRequest()->send(m_getYahooCookiesSlot, "com.palm.yahoo","fetchcookies", params);
	ErrorToException(err);
}
void SmtpActivityFactory::BuildSmtpConfigWatch(ActivityBuilder& ab, const MojObject& accountId, MojInt64 rev)
{
	MojErr err;

	MojString name;
	err = name.format(ACCOUNT_WATCH_ACTIVITY_FMT, AsJsonString(accountId).c_str());
	ErrorToException(err);

	// description of watch
	MojString desc;
	err = desc.format("Watches SMTP config on account %s", AsJsonString(accountId).c_str());
	ErrorToException(err);

	// activity to setup watch
	ab.SetName(name);
	ab.SetDescription(desc.data());
	ab.SetPersist(true);
	ab.SetExplicit(true);
	ab.SetRequiresInternet(false); // trigger even if we don't have a network connection
	ab.SetImmediate(true, ActivityBuilder::PRIORITY_LOW);

	// setup trigger
	// NOTE: how to trigger only on SMTP config change?
	MojDbQuery trigger;
	err = trigger.from("com.palm.mail.account:1");
	ErrorToException(err);
	err = trigger.where("accountId", MojDbQuery::OpEq, accountId);
	ErrorToException(err);

	if (rev > 0) {
		trigger.where("_revSmtp", MojDbQuery::OpGreaterThan, rev);
	}
	ab.SetDatabaseWatchTrigger(trigger);

	MojObject params;
	err = params.put("accountId", accountId);
	ErrorToException(err);

	ab.SetCallback(ACCOUNT_UPDATED_BUS_METHOD, params);
	ab.SetMetadata(params);
}
// TODO: switch to ActivitySet
void SyncFolderCommand::RunImpl()
{
	try {
		if (!m_client.GetAccount().get()) {
			MojString err;
			err.format("Account is not loaded for '%s'", AsJsonString(
					m_client.GetAccountId()).c_str());
			throw MailException(err.data(), __FILE__, __LINE__);
		}

		MojLogInfo(m_log, "Running sync folder command in PopClient with payload: %s", AsJsonString(m_payload).c_str());
		m_activity = ActivityParser::GetActivityFromPayload(m_payload);

		MojErr err;
		err = m_payload.getRequired("folderId", m_folderId);
		ErrorToException(err);

		bool exist = m_payload.get("force", m_force);
		if (!exist) {
			// just in case this value is not set by MojObject if "force" field doesn't exist
			m_force = false;
		}

		MojObject outboxId = m_client.GetAccount()->GetOutboxFolderId();
		if (outboxId == m_folderId) {
			m_client.SendRequest(m_outboxSyncResponseSlot, "com.palm.smtp",
					"syncOutbox", m_payload);
		} else {
			SyncFolder();
		}
	} catch (const std::exception& ex) {
		Failure(ex);
	} catch (...) {
		Failure(MailException("Unknown exception", __FILE__, __LINE__));
	}
}
void ScheduleRetryCommand::CancelActivities()
{
	// Delete anything that includes the folderId in the name
	MojString folderIdSubstring;
	MojErr err = folderIdSubstring.format("folderId=%s", AsJsonString(m_folderId).c_str());
	ErrorToException(err);

	MojString retryActivityName;
	m_client.GetActivityBuilderFactory()->GetFolderRetrySyncActivityName(retryActivityName, m_folderId);

	m_deleteActivitiesCommand.reset(new DeleteActivitiesCommand(m_client));
	m_deleteActivitiesCommand->SetIncludeNameFilter(folderIdSubstring);
	m_deleteActivitiesCommand->SetExcludeNameFilter(retryActivityName);
	m_deleteActivitiesCommand->Run(m_deleteActivitiesSlot);
}
示例#8
0
void MojoDatabase::MoveDeletedEmailToTrash (Signal::SlotRef slot, const MojObject& emailId, const MojObject& trashFolderId)
{
	MojObject email;
	MojErr err = email.put(PopEmailAdapter::ID, emailId);
	ErrorToException(err);

	err = email.put(EmailSchema::FOLDER_ID, trashFolderId);
	ErrorToException(err);

	err = email.put("_del", false);
	ErrorToException(err);

	MojLogInfo(PopClient::s_log, "Moving email '%s' to trash folder '%s'", AsJsonString(emailId).c_str(), AsJsonString(trashFolderId).c_str());
	err = m_dbClient.merge(slot, email);
	ErrorToException(err);
}
示例#9
0
void SyncSession::SyncSessionComplete()
{
	MojLogInfo(m_log, "Sync session completed");
	if (m_completedSignal.connected()) {
		m_completedSignal.fire();
	}

	PopClient::AccountPtr account = m_client.GetAccount();
	if (account->IsInitialSync() && !PopErrors::IsNetworkError(m_accountError)) {
		MojLogDebug(m_log, "Account '%s' is initially synced.", AsJsonString(account->GetAccountId()).c_str());
		account->SetInitialSync(false);
		m_client.GetDatabaseInterface().UpdateAccountInitialSync(m_updateAccountSlot, account->GetAccountId(), account->IsInitialSync());
	} else {
		BaseSyncSession::SyncSessionComplete();
	}
}
void DownloadPartCommand::RunImpl()
{
	try {
		if (!m_client.GetAccount().get()) {
			MojString err;
			err.format("Account is not loaded for '%s'", AsJsonString(m_client.GetAccountId()).c_str());
			throw MailException(err.data(), __FILE__, __LINE__);
		}

		m_client.GetSession()->FetchEmail(m_emailId, m_partId, m_listener);
		Complete();
	} catch (const std::exception& ex) {
		Failure(ex);
	} catch (...) {
		Failure(MailException("Unknown exception in downloading email", __FILE__, __LINE__));
	}
}
void ScheduleRetryCommand::RunImpl()
{
	try {
		if (!m_client.GetAccount().get()) {
			MojString err;
			err.format("Account is not loaded for '%s'", AsJsonString(
					m_client.GetAccountId()).c_str());
			throw MailException(err.data(), __FILE__, __LINE__);
		}

		ScheduleRetry();
	} catch (const std::exception& ex) {
		Failure(ex);
	} catch (...) {
		Failure(MailException("Unknown exception in scheduling POP account retry", __FILE__, __LINE__));
	}
}
MojErr ScheduleRetryCommand::ScheduleRetryResponse(MojObject& response, MojErr err)
{
	try {
		MojLogInfo(m_log, "Retry activity creation: %s", AsJsonString(response).c_str());
		ErrorToException(err);

		CancelActivities();
	} catch (const std::exception& e) {
		MojLogError(m_log, "Exception in schedule retry response: '%s'", e.what());
		Failure(e);
	} catch (...) {
		MojLogError(m_log, "Unknown exception in schedule retry response");
		Failure(MailException("Unknown exception in schedule retry response", __FILE__, __LINE__));
	}

	return MojErrNone;
}
void ScheduleRetryCommand::CancelActivities()
{
	CommandTraceFunction();

	// Delete anything that includes the folderId in the name
	MojString folderIdSubstring;
	MojErr err = folderIdSubstring.format("folderId=%s", AsJsonString(m_folderId).c_str());
	ErrorToException(err);

	// Don't delete the retry activity
	ImapActivityFactory factory;
	MojString retryActivityName = factory.GetSyncRetryName(m_client.GetAccountId(), m_folderId);

	m_deleteActivitiesCommand.reset(new DeleteActivitiesCommand(m_client));
	m_deleteActivitiesCommand->SetIncludeNameFilter(folderIdSubstring);
	m_deleteActivitiesCommand->SetExcludeNameFilter(retryActivityName);
	m_deleteActivitiesCommand->Run(m_deleteActivitiesSlot);
}
示例#14
0
void MojoDatabase::UpdateEmailParts(Signal::SlotRef slot, const MojObject& emailId, const MojObject& parts, bool autoDownload)
{
	MojObject email;
	MojErr err = email.put(PopEmailAdapter::ID, emailId);
	ErrorToException(err);

	err = email.put(EmailSchema::PARTS, parts);
	ErrorToException(err);

	if ((!parts.undefined() && !parts.null() && parts.size() > 0) || !autoDownload) {
		err = email.put(PopEmailAdapter::DOWNLOADED, true);
		ErrorToException(err);
	}

	MojLogDebug(PopClient::s_log, "Updating email '%s' with parts: '%s'", AsJsonString(emailId).c_str(), AsJsonString(parts).c_str());
	err = m_dbClient.merge(slot, email);
	ErrorToException(err);
}
void PopAccountEnableCommand::RunImpl()
{
	try {
		if (!m_client.GetAccount().get()) {
			MojString err;
			err.format("Account is not loaded for '%s'", AsJsonString(
					m_client.GetAccountId()).c_str());
			throw MailException(err.data(), __FILE__, __LINE__);
		}

		m_account = m_client.GetAccount();
		m_accountId = m_account->GetAccountId();
		FindSpecialFolders();
	} catch (const std::exception& ex) {
		Failure(ex);
	} catch (...) {
		Failure(MailException("Unknown exception in enabling POP account", __FILE__, __LINE__));
	}
}
MojErr DeleteActivitiesCommand::GetActivityListResponse(MojObject& response, MojErr err)
{
	CommandTraceFunction();

	try {
		ResponseToException(response, err);

		MojObject activities;
		err = response.getRequired("activities", activities);
		ErrorToException(err);

		MojString creatorIdSubstring;
		err = creatorIdSubstring.assign("com.palm.imap");
		ErrorToException(err);

		BOOST_FOREACH(const MojObject& activity, DatabaseAdapter::GetArrayIterators(activities)) {
			MojObject activityId;
			err = activity.getRequired("activityId", activityId);
			ErrorToException(err);

			MojString name;
			err = activity.getRequired("name", name);
			ErrorToException(err);

			MojString creator;
			err = activity.getRequired("creator", creator);
			ErrorToException(err);

			// Check that the accountId and creator (com.palm.imap) are in the activity fields
			if(creator.find(creatorIdSubstring.data(), 0) != MojInvalidIndex
			&& ShouldDeleteActivity(activity)) {
				fprintf(stderr, "preparing to delete activity id=%s name=%s, creator=%s\n",
					AsJsonString(activityId).c_str(), name.data(), creator.data());
				m_deleteIds.push(activityId);
			}
		}

		DeleteActivities();
	} CATCH_AS_FAILURE
示例#17
0
MojErr SaveEmailCommand::GetAccountResponse(MojObject &response, MojErr err)
{
	try {
		ResponseToException(response, err);

		MojObject accountObj;
		DatabaseAdapter::GetOneResult(response, accountObj);

		const char* folderPropertyName = m_isDraft ? EmailAccountAdapter::DRAFTS_FOLDERID : EmailAccountAdapter::OUTBOX_FOLDERID;
		err = accountObj.getRequired(folderPropertyName, m_folderId);
		ErrorToException(err);

		MojLogDebug(m_log, "preparing to save email to folderId %s", AsJsonString(m_folderId).c_str());

		PrepareParts();
	} catch(const std::exception& e) {
		Error(e);
	} catch(...) {
		Error( MailException("unknown", __FILE__, __LINE__) );
	}
	
	return MojErrNone;
}
MojErr AccountFinderCommand::GetAccountResponse(MojObject& response, MojErr err)
{
	CommandTraceFunction();

	try {
		// check the result first
		ErrorToException(err);

		err = response.getRequired("result", m_accountObj);
		ErrorToException(err);

		MojLogInfo(m_log, "Found account %s", AsJsonString(m_accountId).c_str());

		// get the password
		GetPassword();
	} catch (const std::exception& ex) {
		Failure(ex);
	} catch (...) {
		Failure(MailException("unknown exception", __FILE__, __LINE__));
	}

	return MojErrNone;
}
void ActivityBuilderFactory::GetDeleteEmailsActivityName(MojString& name)
{
	MojErr err = name.format(DELETE_EMAILS_ACTIVITY_NAME_TEMPLATE, AsJsonString(m_accountId).c_str());
	ErrorToException(err);
}
void SmtpSyncOutboxCommand::AttachAdoptedActivity(MojRefCountedPtr<Activity> activity, const MojString& activityId, const MojString& activityName)
{
	MojLogInfo(m_log, "Attaching adopted activity, incoming activityId=%s, name=%s. WatchActivityName=%s"
		, activityId.data(), activityName.data(), m_outboxWatchActivityName.data());

	if (activityName == m_outboxWatchActivityName) {
		if(m_outboxWatchActivity.get() && activity.get()) {
			MojLogWarning(m_log, "%s: outbox activity already attached; replacing activity %s with %s", __PRETTY_FUNCTION__, AsJsonString(m_outboxWatchActivity->GetActivityId()).c_str(), AsJsonString(activity->GetActivityId()).c_str());
		}

		m_outboxWatchActivity = activity;
	} else if (activityName == m_accountWatchActivityName) {
		if(m_accountWatchActivity.get() && activity.get()) {
			MojLogWarning(m_log, "%s: account watch activity already attached; replacing activity %s with %s", __PRETTY_FUNCTION__, AsJsonString(m_accountWatchActivity->GetActivityId()).c_str(), AsJsonString(activity->GetActivityId()).c_str());
		}

		m_accountWatchActivity = activity;
	} else {
		m_manualActivities.push_back( activity );
	}
	
	m_networkStatus->ParseActivity(activity);
}
void SmtpSyncOutboxCommand::CheckNetworkConnectivity()
{
	try {

		if (m_networkStatus->IsKnown()) {
			if (m_networkStatus->IsConnected()) {
				MojLogInfo(m_log, "CheckNetworkActivity: is connected, moving on");
				GetAccount();
				return;
			} else {
				MojLogInfo(m_log, "CheckNetworkActivity: is not connected, erroring out");
				// Note that this account error explicitly doesn't delay the retry, on the assumption
				// that the next activity will be blocked until the network is available.
				m_error.errorCode = MailError::NO_NETWORK;
				m_error.errorOnAccount = true;
				m_error.errorOnEmail = false;
				m_error.internalError = "No network available for outbox sync";
				m_error.errorText = "";

				CompleteAndUpdateActivities();
				return;
			}
		} else {
			MojLogInfo(m_log, "CheckNetworkActivity: state unknown, starting new activity");
			MojLogInfo(m_log, "OutboxSyncer creating new network activity");
			ActivityBuilder ab;
			MojString name;
			MojErr err = name.format("SMTP Internal Outbox Sync Network Activity for account %s", AsJsonString(m_accountId).c_str());
			ErrorToException(err);
			ab.SetName(name);
			ab.SetDescription("Activity representing SMTP Outbox Sync Network Monitor");
			ab.SetForeground(true);
			ab.SetRequiresInternet(false);
			ab.SetImmediate(true, ActivityBuilder::PRIORITY_LOW);
			m_networkActivity = Activity::PrepareNewActivity(ab);
			m_networkActivity->SetSlots(m_networkActivityUpdatedSlot, m_networkActivityErrorSlot);
			m_networkActivity->Create(m_client);
		}

	} catch (std::exception & e) {
		HandleException(e, __func__);
	} catch (...) {
		HandleException(__func__);
	}
}
void ActivityBuilderFactory::GetFolderRetrySyncActivityDesc(MojString& desc, const MojObject& folderId)
{
	MojErr err = desc.format(FOLDER_RETRY_SYNC_DESC, AsJsonString(folderId).c_str());
	ErrorToException(err);
}
void ActivityBuilderFactory::GetScheduledSyncActivityName(MojString& name)
{
	MojErr err = name.format(SCHEDULED_SYNC_ACTIVITY_NAME_TEMPLATE, AsJsonString(m_accountId).c_str());
	ErrorToException(err);
}
void ActivityBuilderFactory::GetDeleteEmailsActivityDesc(MojString& desc)
{
	MojErr err = desc.format(DELETE_EMAILS_DESC, AsJsonString(m_accountId).c_str());
	ErrorToException(err);
}
void ActivityBuilderFactory::GetAccountPrefsWatchActivityName(MojString& name)
{
	MojErr err = name.format(ACCOUNT_PREFS_WATCH_ACTIVITY_NAME_TEMPLATE, AsJsonString(m_accountId).c_str());
	ErrorToException(err);
}
void ActivityBuilderFactory::GetAccountPrefsWatchActivityDesc(MojString& desc)
{
	MojErr err = desc.format(ACCOUNT_PREFS_WATCH_DESC, AsJsonString(m_accountId).c_str());
	ErrorToException(err);
}
void ActivityBuilderFactory::GetScheduledSyncActivityDesc(MojString& desc)
{
	MojErr err = desc.format(SCHEDULED_SYNC_DESC, AsJsonString(m_accountId).c_str());
	ErrorToException(err);
}
void ActivityBuilderFactory::GetSentEmailsWatchActivityName(MojString& name)
{
	MojErr err = name.format(SENT_EMAILS_WATCH_ACTIVITY_NAME_TEMPLATE, AsJsonString(m_accountId).c_str());
	ErrorToException(err);
}
示例#29
0
void PopSession::AutoDownloadEmails(const MojObject& folderId)
{
	if (m_state == State_SyncingEmails || m_state == State_OkToSync) {
		m_state = State_OkToSync;

		MojLogDebug(m_log, "Creating command to auto download email bodies for folder '%s'", AsJsonString(folderId).c_str());
		MojRefCountedPtr<AutoDownloadCommand> command(new AutoDownloadCommand(*this, folderId));
		m_commandManager->QueueCommand(command);
		CheckQueue();
	}
}
void ActivityBuilderFactory::GetSentEmailsWatchActivityDesc(MojString& desc)
{
	MojErr err = desc.format(SENT_EMAILS_WATCH_DESC, AsJsonString(m_accountId).c_str());
	ErrorToException(err);
}