Exemple #1
0
void MainWindow::on_btnDeleteAccount_clicked()
{
    QString selectedAccountName = getAccountName();
    QString warningMessage = qApp->tr("This will delete account ");
    warningMessage.append(selectedAccountName);
    if (QMessageBox::warning(0,qApp->tr("Delete Account"),
                         warningMessage,
                         QMessageBox::Ok | QMessageBox::Cancel)
            == QMessageBox::Ok)
    {
        int accountId = getAccountId();

        //remove any transactions associated with this account
        QSqlQuery q;
        q.prepare("DELETE FROM trans WHERE id_account = ?");
        q.addBindValue(accountId);
        if(!q.exec())
        {
            transactionFailedError(qApp->tr("Could not delete account"));
        }

        //remove the account
        q.clear();
        q.prepare("DELETE FROM account WHERE pk_uid = ?");
        q.addBindValue(accountId);
        if(!q.exec())
        {
            transactionFailedError(qApp->tr("Could not delete account"));
        }
    }
    refreshAccountTree();
}
	/*
		Summary: returns a string representation of the account object
				that allows the object to be persisted in a text file
		Pre: none
		Post: string representation (std::string) is returned										
	*/
	std::string toString()
	{
		stringstream ss;
		ss << getAccountId() << ", ";
		ss << getCustomerId() << ", ";
		ss << getAccountName() << ", ";
		ss << getInterestRate() << ", ";
		ss << getBalance();

		std::string str;
		getline(ss, str);

		return str;
	}
Exemple #3
0
/*
 *  fills the account combobox with accounts for a transfer transaction
 */
void MainWindow::fillAccountCombo()
{
    //query the accounts
    QSqlQuery q;
    q.prepare("SELECT pk_uid, account_name FROM account WHERE pk_uid <> ? ORDER BY account_name");
    q.addBindValue(QString::number(getAccountId()));
    q.exec();

    //add accounts to the combobox
    while(q.next())
    {
        ui->comboAccounts->addItem(q.value(1).toString(),q.value(0));
    }
}
Exemple #4
0
void MainWindow::on_treeAccounts_itemSelectionChanged()
{
    transactions->refresh();
    accountFilter->setFilterFixedString(QString::number(getAccountId()));

    //if the transfer combobox is showing, update the accounts to reflect the change
    if (ui->transferCheckBox->checkState() == Qt::Checked)
    {
        ui->comboAccounts->clear();
        fillAccountCombo();
    }

    //scroll to the bottom of the transactions
    ui->tableTransactions->scrollToBottom();

    //reset filtered amount label if visible
    if ( ! ui->lblFilterTotal->isHidden() )
    {
        setFilterAmount();
    }
}
/* expected hook, this is where custom stuff happens */
PAM_EXTERN int pam_sm_authenticate(pam_handle_t* pamh, int flags, int argc, const char **argv) {
    int ret = 0;

    const char *pUsername = NULL;
    const char *pAccountId = NULL;
    const char *pOperation = NULL;
    const char *pSecretKey = NULL;
    const char *pAppId = NULL;
    const char *pOperationId = NULL;
    const char *pAccounts = NULL;
    const char *pConfig = NULL;
    const char *pOtp = NULL;
    const char *pHost = NULL;
    const char *pTimeout = NULL;
    char *pDefaultOption = NULL;
    char *buffer;
    int timeout = 2;
    int default_option = PAM_SUCCESS;
    int res =  PAM_SUCCESS;
    char *otp = NULL;


    struct pam_message msg[1],*pmsg[1];
    struct pam_response *resp;

    // setting up conversation call prompting for one-time code
    pmsg[0] = &msg[0] ;
    msg[0].msg_style = PAM_PROMPT_ECHO_ON ;
    msg[0].msg = "One-time code: " ;
    resp = NULL ;


    if (pam_get_user(pamh, &pUsername, NULL) != PAM_SUCCESS) {
        return PAM_AUTH_ERR;
    }

    pAccounts = getArg("accounts", argc, argv);
    if (!pAccounts) {
        pAccounts = DEFAULT_LATCH_ACCOUNTS_FILE;
    }

    pAccountId = getAccountId(pUsername, pAccounts);
    if (pAccountId == NULL) {
        return PAM_SUCCESS;
    }

    pConfig = getArg("config", argc, argv);
    if (!pConfig) {
        pConfig = DEFAULT_LATCH_CONFIG_FILE;
    }

    pOperation = getArg("operation", argc, argv);
    if (!pOperation) {
        pOperationId = NULL;
    } else {
        pOperationId = getConfig(OPERATION_ID_LENGTH, pOperation, pConfig);
        if (pOperationId == NULL) {
            send_syslog_alert("PAM", "Latch-auth-pam error: Failed to find operation");
            perror("Failed to find operation");
            return PAM_SUCCESS;
        }
    }

    pOtp = getArg("otp", argc, argv);
    if (!pOtp) {
        pOtp = "no";
    }

    pDefaultOption = (char *)getConfig(DEFAULT_OPTION_MAX_LENGTH, "action", pConfig);
    if (pDefaultOption == NULL) {
        pDefaultOption = malloc(4 + 1);
        memset(pDefaultOption, 0, 4 + 1);
        strncpy(pDefaultOption, "open", 4);
    } else if (strcmp(pDefaultOption,"open") != 0 && strcmp(pDefaultOption,"close") != 0){
        pDefaultOption = realloc(pDefaultOption, 4 + 1);
        memset(pDefaultOption, 0, 4 + 1);
        strncpy(pDefaultOption, "open", 4);
    }

    if (strcmp(pDefaultOption,"open") == 0) {
        default_option = PAM_SUCCESS;
    } else {
        default_option = PAM_AUTH_ERR;
    }
    free(pDefaultOption);

    pAppId = getConfig(APP_ID_LENGTH, "app_id", pConfig);
    pSecretKey = getConfig(SECRET_KEY_LENGTH, "secret_key", pConfig);

    if(pAppId == NULL || pSecretKey == NULL || strcmp(pAppId, "") == 0 || strcmp(pSecretKey, "") == 0){
        send_syslog_alert("PAM", "Latch-auth-pam error: Failed to read \"latch.conf\"");
        perror("Failed to read \"latch.conf\"");
        free((char*)pAccountId);
        free((char*)pOperationId);
        return PAM_SUCCESS;
    }

    pHost = getConfig(MAX_SIZE, "latch_host", pConfig);
    if(pHost == NULL) {
        pHost = malloc(LATCH_API_HOST_LENGTH + 1);
        memset((char*)pHost, 0, LATCH_API_HOST_LENGTH + 1);
        strncpy((char*)pHost, LATCH_API_HOST, LATCH_API_HOST_LENGTH);
    }

    pTimeout = getConfig(TIMEOUT_MAX_LENGTH, "timeout", pConfig);
    if(pTimeout == NULL || ((timeout = atoi(pTimeout)) < TIMEOUT_MIN) || timeout > TIMEOUT_MAX) {
        timeout = 2;
    }
    free((char*)pTimeout);

    if (drop_privileges(0)) {
        send_syslog_alert("PAM", "Latch-auth-pam error: Couldn't drop privileges");
    }

    init(pAppId, pSecretKey);
    setHost(pHost);
    setTimeout(timeout);

    if (pOperationId != NULL) {
        buffer = operationStatus(pAccountId, pOperationId);
    } else {
        buffer = status(pAccountId);
    }
    free((char*)pAppId);
    free((char*)pSecretKey);
    free((char*)pAccountId);
    free((char*)pOperationId);
    free((char*)pHost);

    if (restore_privileges()) {
        send_syslog_alert("PAM", "Latch-auth-pam error: Couldn't restore privileges");
    }

    if(buffer == NULL || strcmp(buffer,"") == 0){
        free(buffer);
        return default_option;
    }

    if (strstr(buffer, "\"status\":\"off\"") != NULL){
        fprintf (stderr, "AUTH-PAM: latch locked\n");
        send_syslog_alert("PAM", "Latch-auth-pam warning: Someone tried to access. Latch locked");
        res = PAM_AUTH_ERR;

    }else if (strstr(buffer, "\"status\":\"on\"") != NULL) {

        if(strncmp(pOtp, "yes", 3) == 0){

            char *pch;
            if((pch = strstr(buffer, "\"two_factor\"")) != NULL){
                char code[OTP_LENGTH];
                memset(code, 0, OTP_LENGTH);

                strncpy (code, pch + strlen("\"two_factor\":{\"token\":\""), OTP_LENGTH);

                otp = get_response(pamh, "One-time password", 1);

                // comparing user input with known code
                if(strncmp(code, otp, OTP_LENGTH) != 0  || strlen(otp) != OTP_LENGTH){
                    send_syslog_alert("PAM", "Latch-auth-pam warning: Someone tried to access. Bad OTP");
                    res = PAM_AUTH_ERR;
                } else {
                    res = PAM_SUCCESS;
                }
            }

        }else{
            res = PAM_SUCCESS;
        }
    }

    free(buffer);
    return res;
}
Exemple #6
0
/*
 *  right click menu for transactions
 */
void MainWindow::on_tableTransactions_customContextMenuRequested(const QPoint &pos)
{
    //test for a click in empty table space, or for no selection
    if (ui->tableTransactions->selectionModel()->selectedRows().count() < 1 || !ui->tableTransactions->indexAt(pos).isValid())
    {
        return;
    }

    QMenu *transactionsMenu;
    QPoint globalPos = ui->tableTransactions->mapToGlobal(pos);
    QMenu *accountsMenu;
    QSqlQuery q;
    QString moveText;
    QString deleteText;
    QString reconcileText;

    //set the menu item text based on the number of selected transactions
    if (ui->tableTransactions->selectionModel()->selectedRows().count() == 1)
    {
        moveText = "Move transaction";
        deleteText = "Delete this transaction";
    }
    else
    {
        moveText = "Move transactions";
        deleteText = "Delete these transactions";
    }
    reconcileText = "Mark as reconciled";  //not dependent on number of transactions selected

    //create the menus
    transactionsMenu = new QMenu(this);
    accountsMenu = new QMenu(moveText,transactionsMenu);
    transactionsMenu->addMenu(accountsMenu);

    //add the delete transaction action
    QAction *deleteAction;
    deleteAction = new QAction(deleteText,transactionsMenu);
    deleteAction->setData("delete");
    transactionsMenu->addAction(deleteAction);

    //add the reconcile action
    QAction *reconcileAction;
    reconcileAction = new QAction(reconcileText,transactionsMenu);
    reconcileAction->setData("reconcile");
    transactionsMenu->addAction(reconcileAction);

    //query the accounts
    q.prepare("SELECT pk_uid, account_name FROM account WHERE pk_uid <> ? ORDER BY account_name");
    q.addBindValue(QString::number(getAccountId()));
    q.exec();

    //iterate through the accounts selected in the sql query, create an action for each, and populate the submenu
    while (q.next())
    {
        QAction *a;
        a = new QAction(q.value(1).toString(),accountsMenu);
        a->setData(q.value(0).toInt());  //need to store the pk_uid for each account with the menu item
        accountsMenu->addAction(a);
    }

    //show the menu and get the selected menu item
    QAction *selectedMenuItem = transactionsMenu->exec(globalPos);

    if (selectedMenuItem)
    {
        QItemSelectionModel *rowsSelectionModel;
        QModelIndexList rowsList;

        //set up the selection model and get the pk_uid column of the selected rows
        rowsSelectionModel = ui->tableTransactions->selectionModel();
        rowsList = rowsSelectionModel->selectedRows(col_pk_uid);

        //iterate through the selection and perform the selected task on each
        //selected transaction
        QList<QModelIndex>::Iterator i;
        for (i = rowsList.begin(); i != rowsList.end(); ++i)
        {
            int transactionId;
            transactionId = i->data().toInt();

            if(selectedMenuItem->data() == "delete")  //if the user clicked on "delete this transaction"
            {
                if(!transactions->deleteTransaction(transactionId))
                {
                    transactionFailedError(qApp->tr("Could not delete transaction."));
                    return;
                }
            }
            else if(selectedMenuItem->data() == "reconcile")
            {
                if(!transactions->setReconcile(transactionId,true))
                {
                    transactionFailedError(qApp->tr("Could not set as reconciled."));
                    return;
                }
            }
            else    //the user selected an account to move the transaction to
            {
                int accountId = selectedMenuItem->data().toInt();

                if (!transactions->moveTransaction(accountId, transactionId))
                {
                    transactionFailedError(qApp->tr("Could not move transaction."));
                    return;
                }
            }
        }

        transactions->refresh();
        ui->tableTransactions->scrollToBottom();
    }
}
Exemple #7
0
void MainWindow::on_btnAccept_clicked()
{
    double transactionAmount, transferAmount;
    int accountId, transferAccountId, firstTransactionId, secondTransactionId;
    QString transactionComment, transactionDate;

    //get the account id and the information from the fields
    accountId = getAccountId();
    transferAccountId = ui->comboAccounts->itemData(ui->comboAccounts->currentIndex()).toInt();
    transactionAmount = ui->lineEditAmount->text().toDouble();
    transferAmount = transactionAmount*-1;
    transactionComment = ui->lineEditTransactionInfo->text();
    transactionDate = ui->dateEdit->date().toString("yyyy-MM-dd");

    //check to see if this is a transfer
    if (ui->transferCheckBox->isChecked())  //this is a transfer
    {
        QSqlQuery q;

        //perform the first part of the transfer. if it fails, kick out an error message and exit routine
        if(!transactions->addTransaction(accountId,transactionDate,transactionComment,transactionAmount))
        {
            transactionFailedError(qApp->tr("Could not add transaction."));
            return;
        }

        //get the id of the first part of the transfer
        q.exec("SELECT last_insert_rowid()");
        q.first();
        firstTransactionId = q.value(0).toInt();

        //perform the second part of the transfer. if it fails, kick out an error message and exit routine
        if(!transactions->addTransaction(transferAccountId,transactionDate,transactionComment,transferAmount))
        {
            transactionFailedError(qApp->tr("Could not add transaction."));
            return;
        }

        //get the id of the second part of the transfer
        q.clear();
        q.exec("SELECT last_insert_rowid()");
        q.first();
        q.value(0);
        secondTransactionId = q.value(0).toInt();

        if(!transactions->addTransactionRelation(firstTransactionId,secondTransactionId))
        {
            transactionFailedError(qApp->tr("Could not add transaction."));
            return;
        }

        if(!transactions->addTransactionRelation(secondTransactionId,firstTransactionId))
        {
            transactionFailedError(qApp->tr("Could not add transaction."));
            return;
        }
    }
    else  //this is not a transfer
    {
        //perform the transaction. if it fails, kick out an error message
        if(!transactions->addTransaction(accountId,transactionDate,transactionComment,transactionAmount))
        {
            transactionFailedError(qApp->tr("Could not add transaction."));
            return;
        }
    }

    //clear the amount and comment lines
    ui->lineEditAmount->clear();
    ui->lineEditTransactionInfo->clear();

    //clear the transfer checkbox and hide the combobox
    ui->transferCheckBox->setChecked(false);
    ui->comboAccounts->clear();
    ui->comboAccounts->hide();

    //refresh the table
    transactions->refresh();

    //scroll to the bottom
    ui->tableTransactions->scrollToBottom();
}
Exemple #8
0
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    //set the ui
    ui->setupUi(this);
    ui->dateEdit->setDate(QDate::currentDate());  //set the date to today
    ui->lineEditAmount->setValidator(new QDoubleValidator(-INFINITY,INFINITY,2));  //force 2-decimal number in amount field
    ui->comboAccounts->hide();  //hide the transfer to account combobox
    ui->lblFilterTotal->hide();  //hide the filter total

    //set the db and open
    db = QSqlDatabase::addDatabase("QSQLITE");
    db.setDatabaseName(pathDB);
    QFileInfo checkFile(pathDB);
    if(!checkFile.isFile() or !db.open())
    {
        QMessageBox::critical(0, qApp->tr("Cannot open database"),
            qApp->tr("Unable to establish a database connection.\n"
                     "Click Cancel to exit."), QMessageBox::Cancel);
        QApplication::quit();
    }

    //establish accounts and select first account
    refreshAccountTree();
    ui->treeAccounts->expandAll();

    //set up transactions table
    transactions = new TransactionsModel(this);
    transactions->refresh();

    //set up the filters
    accountFilter = new QSortFilterProxyModel(this);
    reconcileFilter = new QSortFilterProxyModel(this);
    commentFilter = new QSortFilterProxyModel(this);
    accountFilter->setFilterKeyColumn(col_id_account);
    reconcileFilter->setFilterKeyColumn(col_reconciled);
    commentFilter->setFilterKeyColumn(col_comment);
    accountFilter->setDynamicSortFilter(true);
    reconcileFilter->setDynamicSortFilter(true);
    commentFilter->setDynamicSortFilter(true);
    accountFilter->setSourceModel(transactions);
    reconcileFilter->setSourceModel(accountFilter);
    commentFilter->setSourceModel(reconcileFilter);

    if (ui->treeAccounts->selectedItems().count() == 1)     //filter the table based on the selection in the accounts tree
    {
        accountFilter->setFilterFixedString(QString::number(getAccountId()));
    }
    ui->tableTransactions->setModel(commentFilter);         //filter the table for tag searches in the box

    //hide the pk_uid, id_account, and related account columns
    //and size the remaining columns appropriately
    ui->tableTransactions->hideColumn(col_pk_uid);
    ui->tableTransactions->hideColumn(col_id_account);
    ui->tableTransactions->hideColumn(col_relate_account);
    ui->tableTransactions->hideColumn(col_reconciled);
    QHeaderView *h = ui->tableTransactions->horizontalHeader();
    h->setStretchLastSection(false);
    h->setSectionResizeMode(col_date,QHeaderView::Fixed);
    h->setSectionResizeMode(col_comment,QHeaderView::Stretch);  //make the comments column stretch to fill leftover space
    h->setSectionResizeMode(col_amount,QHeaderView::Fixed);
    h->setSectionResizeMode(col_total,QHeaderView::Fixed);
    h->resizeSection(col_date,100);
    h->resizeSection(col_amount,100);
    h->resizeSection(col_total,120);

    //select the first account (so that there is a selection active)
    ui->treeAccounts->setCurrentItem(ui->treeAccounts->itemAt(0,0));
}
/* expected hook, this is where custom stuff happens */
PAM_EXTERN int pam_sm_authenticate(pam_handle_t* pamh, int flags, int argc, const char **argv) {
	//int ret = 0;

	const char* pUsername = NULL;				
	const char* pAccountId = NULL;
	const char* pSecretKey = NULL;
	const char* pAppId = NULL;
	const char* pAccounts = NULL;
	const char* pConfig = NULL;
	char *buffer;				
	
	/*
	struct pam_message msg[1],*pmsg[1];
	struct pam_response *resp;

	// setting up conversation call prompting for one-time code 
	pmsg[0] = &msg[0] ;
	msg[0].msg_style = PAM_PROMPT_ECHO_ON ;
	msg[0].msg = "One-time code: " ;
	resp = NULL ;
	*/

	if (pam_get_user(pamh, &pUsername, NULL) != PAM_SUCCESS) {
		return PAM_AUTH_ERR;
	}

	pAccounts = getArg("accounts", argc, argv);
	if (!pAccounts) {
		return PAM_AUTH_ERR;
	}

	pConfig = getArg("config", argc, argv);
	if (!pConfig) {
		return PAM_AUTH_ERR;
	}

	pAccountId = getAccountId(pUsername, pAccounts);
	if (pAccountId == NULL) {
		return PAM_SUCCESS;
	}


	pAppId = getConfig("app_id", pConfig);
	pSecretKey = getConfig("secret_key", pConfig);
	
	if(pAppId == NULL || pSecretKey == NULL){
		perror("Failed to read \"latch.conf\"");
		return PAM_AUTH_ERR;
	}

	if(strcmp(pAppId,"") == 0 || strcmp(pSecretKey,"") == 0){
		perror("Failed to read \"latch.conf\"");
		return PAM_AUTH_ERR;
	}

	init(pAppId, pSecretKey);
	setHost("https://latch.elevenpaths.com");

	buffer = status(pAccountId);
	
	if(buffer == NULL || strcmp(buffer,"") == 0)
		return PAM_SUCCESS;

	if (strstr(buffer, "\"status\":\"off\"") != NULL){
		fprintf (stderr, "AUTH-PAM: latch locked\n");
                send_syslog_alert();
		return PAM_AUTH_ERR;
	}
	
	/*
	if (strstr(buffer, "\"status\":\"on\"") != NULL) {
		
		char *pch;
		if((pch = strstr(buffer, "\"two_factor\"")) != NULL){
			char code[6] ;
			char *input;

			strncpy (code, pch + strlen("\"two_factor\":{\"token\":\""), 6);

			if( (ret = converse(pamh, 1 , pmsg, &resp)) != PAM_SUCCESS ) {
			// if this function fails, make sure that ChallengeResponseAuthentication in sshd_config is set to yes
				return ret ;
			}

			// retrieving user input 
			if( resp ) {
				if( (flags & PAM_DISALLOW_NULL_AUTHTOK) && resp[0].resp == NULL ) {
	    				free( resp );
	    				return PAM_AUTH_ERR;
				}
				input = resp[ 0 ].resp;
				resp[ 0 ].resp = NULL; 		  				  
    			} else {
				return PAM_CONV_ERR;
			}

			// comparing user input with known code 
			if(strncmp(code,input,6) != 0){
				free( input ) ;
				return PAM_AUTH_ERR;
			}
			free( input ) ;
		}
			
	} 
	*/
	//printf("buffer response from  status  call -> %s\n",buffer);

	return PAM_SUCCESS;
}