DB integration: initial support. user login by DB.
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
CFLAGS := -ggdb -Wall -pedantic
|
CFLAGS := -ggdb -Wall -pedantic -lpq
|
||||||
|
|
||||||
SRC_DIR := src
|
SRC_DIR := src
|
||||||
OBJ_DIR := src/obj
|
OBJ_DIR := src/obj
|
||||||
|
|||||||
@@ -0,0 +1,129 @@
|
|||||||
|
#include "db.h"
|
||||||
|
#include <libpq-fe.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#define UNUSED(x) (void)(x)
|
||||||
|
#define Q_LEN 128
|
||||||
|
|
||||||
|
static PGconn *conn = NULL;
|
||||||
|
static PGresult *res = NULL;
|
||||||
|
|
||||||
|
// #define USR_NOT_FOUND "User with such credentials is not found!"
|
||||||
|
|
||||||
|
static void clearRes() {
|
||||||
|
PQclear(res);
|
||||||
|
res = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int terminate(int code) {
|
||||||
|
if (code != 0)
|
||||||
|
fprintf(stderr, "%s\n", PQerrorMessage(conn));
|
||||||
|
|
||||||
|
if (res != NULL)
|
||||||
|
PQclear(res);
|
||||||
|
|
||||||
|
if (conn != NULL)
|
||||||
|
PQfinish(conn);
|
||||||
|
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int exit_query(int code) {
|
||||||
|
if (code != 0)
|
||||||
|
fprintf(stderr, "%s\n", PQerrorMessage(conn));
|
||||||
|
|
||||||
|
if (res != NULL)
|
||||||
|
PQclear(res);
|
||||||
|
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void processNotice(void *arg, const char *message) {
|
||||||
|
UNUSED(arg);
|
||||||
|
UNUSED(message);
|
||||||
|
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
int init_connection() {
|
||||||
|
// TODO: get from external configs
|
||||||
|
conn = PQconnectdb("user=postgres password=dobro host=127.0.0.1 dbname=bbs");
|
||||||
|
|
||||||
|
if (PQstatus(conn) != CONNECTION_OK)
|
||||||
|
return terminate(1);
|
||||||
|
|
||||||
|
int server_ver = PQserverVersion(conn);
|
||||||
|
char *user = PQuser(conn);
|
||||||
|
char *db_name = PQdb(conn);
|
||||||
|
|
||||||
|
printf("Connection established! server version: %d, user: %s, db: %s\n", server_ver,
|
||||||
|
user, db_name);
|
||||||
|
return exit_query(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int db_user_auth(i_auth_t *credentials, o_auth_t *response) {
|
||||||
|
char query[Q_LEN];
|
||||||
|
response->is_logged = 0;
|
||||||
|
sprintf(query,
|
||||||
|
"SELECT username, password, privileges "
|
||||||
|
"FROM users "
|
||||||
|
"WHERE username= '%s'",
|
||||||
|
credentials->name);
|
||||||
|
res = PQexec(conn, query);
|
||||||
|
|
||||||
|
if (PQresultStatus(res) != PGRES_TUPLES_OK && !PQntuples(res))
|
||||||
|
return exit_query(1);
|
||||||
|
|
||||||
|
const char *pass = PQgetvalue(res, 0, 1);
|
||||||
|
if (!strcmp(pass, credentials->pass)) {
|
||||||
|
response->is_logged = 1;
|
||||||
|
response->privileges = PQgetvalue(res, 0, 2)[0];
|
||||||
|
return exit_query(0);
|
||||||
|
}
|
||||||
|
return exit_query(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*s
|
||||||
|
|
||||||
|
int f_main() {
|
||||||
|
int libpq_ver = PQlibVersion();
|
||||||
|
printf("Version of libpq: %d\n", libpq_ver);
|
||||||
|
|
||||||
|
conn = PQconnectdb("user=postgres password=dobro host=127.0.0.1 dbname=bbs");
|
||||||
|
if (PQstatus(conn) != CONNECTION_OK)
|
||||||
|
terminate(1);
|
||||||
|
|
||||||
|
PQsetNoticeProcessor(conn, processNotice, NULL);
|
||||||
|
|
||||||
|
int server_ver = PQserverVersion(conn);
|
||||||
|
char *user = PQuser(conn);
|
||||||
|
char *db_name = PQdb(conn);
|
||||||
|
|
||||||
|
printf("Server version: %d\n", server_ver);
|
||||||
|
printf("User: %s\n", user);
|
||||||
|
printf("Database name: %s\n", db_name);
|
||||||
|
|
||||||
|
res = PQexec(conn, "SELECT id, username, privileges, email "
|
||||||
|
"FROM users");
|
||||||
|
if (PQresultStatus(res) != PGRES_TUPLES_OK)
|
||||||
|
terminate(1);
|
||||||
|
|
||||||
|
int nrows = PQntuples(res);
|
||||||
|
for (int i = 0; i < nrows; i++) {
|
||||||
|
char *id = PQgetvalue(res, i, 0);
|
||||||
|
char *name = PQgetvalue(res, i, 1);
|
||||||
|
char *privileges = PQgetvalue(res, i, 2);
|
||||||
|
char *email = PQgetvalue(res, i, 3);
|
||||||
|
printf("Id: %s, Name: %s, Privileges: %d, Email: %s, \n", id, name,
|
||||||
|
privileges[0], email);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Total: %d rows\n", nrows);
|
||||||
|
|
||||||
|
clearRes();
|
||||||
|
terminate(0);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
*/
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
typedef struct {
|
||||||
|
char *name;
|
||||||
|
char *pass;
|
||||||
|
} i_auth_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
char privileges;
|
||||||
|
int is_logged;
|
||||||
|
} o_auth_t;
|
||||||
|
|
||||||
|
int init_connection();
|
||||||
|
int db_user_auth(i_auth_t *credentials, o_auth_t *response);
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
client.o: src/client.c src/client.h src/main.h src/file_p.h src/session.h
|
||||||
|
db.o: src/db.c src/db.h
|
||||||
|
file_p.o: src/file_p.c src/file_p.h src/main.h src/session.h
|
||||||
|
main.o: src/main.c src/main.h src/file_p.h src/server.h src/db.h
|
||||||
|
server.o: src/server.c src/main.h src/session.h src/user.h
|
||||||
|
session.o: src/session.c src/session.h src/main.h src/client.h \
|
||||||
|
src/file_p.h src/user.h
|
||||||
|
user.o: src/user.c src/main.h src/session.h src/db.h
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "file_p.h"
|
#include "file_p.h"
|
||||||
#include "server.h"
|
#include "server.h"
|
||||||
|
#include "db.h"
|
||||||
|
|
||||||
/* *** MAIN *** */
|
/* *** MAIN *** */
|
||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
@@ -9,6 +10,7 @@ int main(int argc, char *argv[]) {
|
|||||||
server_data.welcome_message = get_welcome_mes();
|
server_data.welcome_message = get_welcome_mes();
|
||||||
server_data.fl_start = NULL;
|
server_data.fl_start = NULL;
|
||||||
server_data.fl_current = NULL;
|
server_data.fl_current = NULL;
|
||||||
|
init_connection();
|
||||||
get_files_descriptions(&server_data);
|
get_files_descriptions(&server_data);
|
||||||
server_data.ls = start_server();
|
server_data.ls = start_server();
|
||||||
server_main_loop(&server_data);
|
server_main_loop(&server_data);
|
||||||
|
|||||||
@@ -18,13 +18,16 @@ enum sess_states {
|
|||||||
OP_EDIT_USER,
|
OP_EDIT_USER,
|
||||||
OP_LOGIN_USR,
|
OP_LOGIN_USR,
|
||||||
OP_LOGIN_PSS,
|
OP_LOGIN_PSS,
|
||||||
|
OP_LOGIN_ANON,
|
||||||
OP_WAIT,
|
OP_WAIT,
|
||||||
OP_UPLOAD,
|
OP_UPLOAD,
|
||||||
OP_UPLOAD_DESCRIPTION,
|
OP_UPLOAD_DESCRIPTION,
|
||||||
|
OP_REGISTER,
|
||||||
ERR,
|
ERR,
|
||||||
FIN
|
FIN
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
enum user_privileges {
|
enum user_privileges {
|
||||||
ADD_FILE = 01,
|
ADD_FILE = 01,
|
||||||
EDIT_FILES = 02,
|
EDIT_FILES = 02,
|
||||||
|
|||||||
+2
-25
@@ -128,38 +128,15 @@ int query_extract_from_buf(session *sess, char **output_line) {
|
|||||||
|
|
||||||
void perform_session_action(session *sess, char *line, server_data_t *s_d) {
|
void perform_session_action(session *sess, char *line, server_data_t *s_d) {
|
||||||
int state = sess->state;
|
int state = sess->state;
|
||||||
char tmp_buf[256];
|
|
||||||
int priv;
|
int priv;
|
||||||
int tmp_buf_pos;
|
|
||||||
int res;
|
int res;
|
||||||
/* while (sess->buf_used) { */
|
/* while (sess->buf_used) { */
|
||||||
switch (state) {
|
switch (state) {
|
||||||
case OP_LOGIN_USR:
|
case OP_LOGIN_USR:
|
||||||
res = find_user(line);
|
process_user_name(line, sess);
|
||||||
if (res == -2) {
|
|
||||||
sess->state = ERR;
|
|
||||||
sess->reason = EXIT;
|
|
||||||
session_send_string(sess, "Bye!");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
sess->userpos = res;
|
|
||||||
sess->state = OP_LOGIN_PSS;
|
|
||||||
session_send_string(sess, "password> ");
|
|
||||||
break;
|
break;
|
||||||
case OP_LOGIN_PSS:
|
case OP_LOGIN_PSS:
|
||||||
if (sess->userpos == -1) {
|
login(sess, line);
|
||||||
sess->state = ERR;
|
|
||||||
sess->reason = LOGIN;
|
|
||||||
} else {
|
|
||||||
if (login(sess, line)) {
|
|
||||||
sess->state = OP_WAIT;
|
|
||||||
sprintf(tmp_buf, "Welcome, %s\n", sess->uname);
|
|
||||||
session_send_string(sess, tmp_buf);
|
|
||||||
} else {
|
|
||||||
sess->state = ERR;
|
|
||||||
sess->reason = LOGIN;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case OP_WAIT:
|
case OP_WAIT:
|
||||||
process_client_command(line, sess, s_d);
|
process_client_command(line, sess, s_d);
|
||||||
|
|||||||
+38
-51
@@ -3,68 +3,55 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include "db.h"
|
||||||
|
|
||||||
long int find_user(char *uname) {
|
int process_user_name(char *uname, session *sess) {
|
||||||
FILE *fptr = fopen(FILE_USER_LIST_NAME, "r");
|
|
||||||
|
|
||||||
if (fptr == NULL) {
|
|
||||||
perror(FILE_USER_LIST_NAME);
|
|
||||||
exit(9);
|
|
||||||
}
|
|
||||||
|
|
||||||
char *line = NULL;
|
|
||||||
size_t bsize = WSIZE;
|
|
||||||
char b_uname[32];
|
|
||||||
long int cur_pos = 0;
|
|
||||||
int lsize = 0;
|
|
||||||
|
|
||||||
if (!strncmp(uname, "exit", sizeof "exit")) {
|
if (!strncmp(uname, "exit", sizeof "exit")) {
|
||||||
return -2;
|
sess->state = ERR;
|
||||||
|
sess->reason = EXIT;
|
||||||
|
session_send_string(sess, "Bye!");
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (getline(&line, &bsize, fptr)) {
|
if (!strncmp(uname, "register", sizeof "register")) {
|
||||||
if (line[0] == '\b')
|
sess->state = OP_REGISTER;
|
||||||
break;
|
session_send_string(sess, "Your username > ");
|
||||||
sscanf(line, "%s", b_uname);
|
return 2;
|
||||||
if (!strcmp(uname, b_uname)) {
|
|
||||||
line = NULL;
|
|
||||||
fclose(fptr);
|
|
||||||
return cur_pos;
|
|
||||||
} else {
|
|
||||||
cur_pos += lsize;
|
|
||||||
line = NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fclose(fptr);
|
if (!strncmp(uname, "anon", sizeof "anon")) {
|
||||||
return -1;
|
sess->state = OP_LOGIN_ANON;
|
||||||
|
session_send_string(sess, "Welcome, Anonymous!");
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
sess->uname = malloc(strlen(uname) + 1);
|
||||||
|
strcpy(sess->uname, uname);
|
||||||
|
sess->state = OP_LOGIN_PSS;
|
||||||
|
session_send_string(sess, "password> ");
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* returns 1 if success */
|
/* returns 1 if success */
|
||||||
int login(session *sess, char *pass) {
|
int login(session *sess, char *pass) {
|
||||||
FILE *fptr = fopen(FILE_USER_LIST_NAME, "r");
|
char tmp_string[256];
|
||||||
fseek(fptr, sess->userpos, SEEK_SET);
|
i_auth_t cred;
|
||||||
int res = 0;
|
o_auth_t response;
|
||||||
|
cred.name = sess->uname;
|
||||||
char *line = NULL;
|
cred.pass = pass;
|
||||||
size_t lsize = WSIZE;
|
db_user_auth(&cred, &response);
|
||||||
char *pass_tok, *name_tok, *priv_tok;
|
if (response.is_logged) {
|
||||||
|
sess->state = OP_WAIT;
|
||||||
getline(&line, &lsize, fptr);
|
sess->privileges = (char)atoi(&response.privileges);
|
||||||
name_tok = strtok(line, " ");
|
sprintf(tmp_string, "Welcome, %s\n", sess->uname);
|
||||||
pass_tok = strtok(NULL, " ");
|
session_send_string(sess, tmp_string);
|
||||||
|
return 0;
|
||||||
if (!strcmp(pass_tok, pass)) {
|
} else {
|
||||||
int n_len = pass_tok - name_tok - 1; /* exclude space */
|
sess->state = ERR;
|
||||||
sess->uname = malloc(n_len + 1);
|
sess->reason = EXIT;
|
||||||
strncpy(sess->uname, name_tok, n_len);
|
return 1;
|
||||||
sess->uname[n_len] = 0;
|
|
||||||
priv_tok = strtok(NULL, " ");
|
|
||||||
sess->privileges = (char)atoi(priv_tok);
|
|
||||||
res = 1;
|
|
||||||
}
|
}
|
||||||
fclose(fptr);
|
|
||||||
return res;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: синхронизовать c C++
|
// TODO: синхронизовать c C++
|
||||||
|
|||||||
+1
-1
@@ -4,5 +4,5 @@
|
|||||||
#include "main.h"
|
#include "main.h"
|
||||||
int login(session *sess, char *pass);
|
int login(session *sess, char *pass);
|
||||||
int process_error(session *sess);
|
int process_error(session *sess);
|
||||||
long int find_user(char *uname);
|
int process_user_name(char *uname, session *sess);
|
||||||
#endif
|
#endif
|
||||||
Reference in New Issue
Block a user