1 /*
    2  * WARNING: automatically generated by kwebapp 0.3.1.
    3  * DO NOT EDIT!
    4  */
    5 #include <sys/queue.h>
    6 
    7 #include <stdarg.h>
    8 #include <stdint.h>
    9 #include <stdio.h>
   10 #include <stdlib.h>
   11 #include <string.h>
   12 #include <unistd.h>
   13 
   14 #include <ksql.h>
   15 #include <kcgi.h>
   16 #include <kcgijson.h>
   17 
   18 #include "rbac-ex2.h"
   19 
   20 /*
   21  * All SQL statements we'll define in "stmts".
   22  */
   23 enum	stmt {
   24 	STMT_USER_BY_SEARCH_0,
   25 	STMT_USER_INSERT,
   26 	STMT_SESSION_BY_SEARCH_0,
   27 	STMT_SESSION_INSERT,
   28 	STMT_SESSION_DELETE_0,
   29 	STMT__MAX
   30 };
   31 
   32 /*
   33  * Definition of our opaque "kwbp", which contains role information.
   34  */
   35 struct	kwbp {
   36 	/* Hidden database connection */
   37 	struct ksql *db;
   38 	/* Current RBAC role. */
   39 	enum kwbp_role role;
   40 };
   41 
   42 /*
   43  * Our full set of SQL statements.
   44  * We define these beforehand because that's how ksql handles statement 
   45  * generation.
   46  * Notice the "AS" part: this allows for multiple inner joins without 
   47  * ambiguity.
   48  */
   49 static	const char *const stmts[STMT__MAX] = {
   50 	/* STMT_USER_BY_SEARCH_0 */
   51 	"SELECT " DB_SCHEMA_USER(user) " FROM user WHERE user.email = ?",
   52 	/* STMT_USER_INSERT */
   53 	"INSERT INTO user (email,hash) VALUES (?,?)",
   54 	/* STMT_SESSION_BY_SEARCH_0 */
   55 	"SELECT " DB_SCHEMA_SESSION(session) "," DB_SCHEMA_USER(_a) " FROM session INNER JOIN user AS _a ON _a.id=session.userid WHERE session.id = ?",
   56 	/* STMT_SESSION_INSERT */
   57 	"INSERT INTO session (userid) VALUES (?)",
   58 	/* STMT_SESSION_DELETE_0 */
   59 	"DELETE FROM session WHERE id = ?",
   60 };
   61 
   62 const struct kvalid valid_keys[VALID__MAX] = {
   63 	{ valid_user_email, "user-email" },
   64 	{ valid_user_hash, "user-hash" },
   65 	{ valid_user_id, "user-id" },
   66 	{ valid_session_userid, "session-userid" },
   67 	{ valid_session_id, "session-id" },
   68 };
   69 
   70 /*
   71  * Finally, all of the functions we'll use.
   72  */
   73 
   74 struct kwbp *
   75 db_open(const char *file)
   76 {
   77 	struct ksqlcfg cfg;
   78 	struct ksql *db;
   79 	struct kwbp *ctx;
   80 
   81 	ctx = malloc(sizeof(struct kwbp));
   82 	if (NULL == ctx)
   83 		return(NULL);
   84 
   85 	memset(&cfg, 0, sizeof(struct ksqlcfg));
   86 	cfg.flags = KSQL_EXIT_ON_ERR |
   87 		KSQL_FOREIGN_KEYS | KSQL_SAFE_EXIT;
   88 	cfg.err = ksqlitemsg;
   89 	cfg.dberr = ksqlitedbmsg;
   90 
   91 	db = ksql_alloc(&cfg);
   92 	if (NULL == db) {
   93 		free(ctx);
   94 		return(NULL);
   95 	}
   96 	ctx->db = db;
   97 	ksql_open(db, file);
   98 	ctx->role = ROLE_default;
   99 	return(ctx);
  100 }
  101 
  102 void
  103 db_close(struct kwbp *p)
  104 {
  105 	if (NULL == p)
  106 		return;
  107 	ksql_close(p->db);
  108 	ksql_free(p->db);
  109 	free(p);
  110 }
  111 
  112 void
  113 db_role(struct kwbp *ctx, enum kwbp_role r)
  114 {
  115 
  116 	if (r == ctx->role)
  117 		return;
  118 	if (ROLE_none == ctx->role)
  119 		abort();
  120 
  121 	switch (r) {
  122 	case ROLE_none:
  123 		ctx->role = r;
  124 		return;
  125 	case ROLE_user:
  126 		switch (ctx->role) {
  127 		case ROLE_default:
  128 			ctx->role = r;
  129 			return;
  130 		default:
  131 			abort();
  132 		}
  133 		break;
  134 	case ROLE_admin:
  135 		switch (ctx->role) {
  136 		case ROLE_default:
  137 			ctx->role = r;
  138 			return;
  139 		default:
  140 			abort();
  141 		}
  142 		break;
  143 	default:
  144 		abort();
  145 	}
  146 }
  147 
  148 static void
  149 db_user_fill_r(struct user *p, struct ksqlstmt *stmt, size_t *pos)
  150 {
  151 	size_t i = 0;
  152 
  153 	if (NULL == pos)
  154 		pos = &i;
  155 	db_user_fill(p, stmt, pos);
  156 }
  157 
  158 void
  159 db_user_fill(struct user *p, struct ksqlstmt *stmt, size_t *pos)
  160 {
  161 	size_t i = 0;
  162 
  163 	if (NULL == pos)
  164 		pos = &i;
  165 	memset(p, 0, sizeof(*p));
  166 	p->email = strdup(ksql_stmt_str(stmt, (*pos)++));
  167 	if (NULL == p->email) {
  168 		perror(NULL);
  169 		exit(EXIT_FAILURE);
  170 	}
  171 	p->hash = strdup(ksql_stmt_str(stmt, (*pos)++));
  172 	if (NULL == p->hash) {
  173 		perror(NULL);
  174 		exit(EXIT_FAILURE);
  175 	}
  176 	p->id = ksql_stmt_int(stmt, (*pos)++);
  177 }
  178 
  179 static void
  180 db_user_unfill_r(struct user *p)
  181 {
  182 	if (NULL == p)
  183 		return;
  184 
  185 	db_user_unfill(p);
  186 }
  187 
  188 void
  189 db_user_unfill(struct user *p)
  190 {
  191 	if (NULL == p)
  192 		return;
  193 	free(p->email);
  194 	free(p->hash);
  195 }
  196 
  197 void
  198 db_user_free(struct user *p)
  199 {
  200 	db_user_unfill_r(p);
  201 	free(p);
  202 }
  203 
  204 void
  205 json_user_data(struct kjsonreq *r, const struct user *p)
  206 {
  207 	kjson_putstringp(r, "email", p->email);
  208 	/* Omitting hash: is a password hash. */
  209 	kjson_putintp(r, "id", p->id);
  210 }
  211 
  212 void
  213 json_user_obj(struct kjsonreq *r, const struct user *p)
  214 {
  215 	kjson_objp_open(r, "user");
  216 	json_user_data(r, p);
  217 	kjson_obj_close(r);
  218 }
  219 
  220 int
  221 valid_user_email(struct kpair *p)
  222 {
  223 	if ( ! kvalid_email(p))
  224 		return(0);
  225 	return(1);
  226 }
  227 
  228 int
  229 valid_user_hash(struct kpair *p)
  230 {
  231 	if ( ! kvalid_string(p))
  232 		return(0);
  233 	return(1);
  234 }
  235 
  236 int
  237 valid_user_id(struct kpair *p)
  238 {
  239 	if ( ! kvalid_int(p))
  240 		return(0);
  241 	return(1);
  242 }
  243 
  244 struct user *
  245 db_user_get_creds(struct kwbp *ctx, const char *v1, const char *v2)
  246 {
  247 	struct ksqlstmt *stmt;
  248 	struct user *p = NULL;
  249 	struct ksql *db = ctx->db;
  250 
  251 	/* Restrict to allowed roles. */
  252 
  253 	switch (ctx->role) {
  254 	case ROLE_user:
  255 		break;
  256 	default:
  257 		abort();
  258 	}
  259 
  260 	ksql_stmt_alloc(db, &stmt,
  261 		stmts[STMT_USER_BY_SEARCH_0],
  262 		STMT_USER_BY_SEARCH_0);
  263 	ksql_bind_str(stmt, 0, v1);
  264 	if (KSQL_ROW == ksql_stmt_step(stmt)) {
  265 		p = malloc(sizeof(struct user));
  266 		if (NULL == p) {
  267 			perror(NULL);
  268 			exit(EXIT_FAILURE);
  269 		}
  270 		db_user_fill_r(p, stmt, NULL);
  271 		if (NULL != p && crypt_checkpass(v2, p->hash) < 0) {
  272 			db_user_free(p);
  273 			p = NULL;
  274 		}
  275 	}
  276 	ksql_stmt_free(stmt);
  277 	return(p);
  278 }
  279 
  280 static void
  281 db_session_fill_r(struct session *p, struct ksqlstmt *stmt, size_t *pos)
  282 {
  283 	size_t i = 0;
  284 
  285 	if (NULL == pos)
  286 		pos = &i;
  287 	db_session_fill(p, stmt, pos);
  288 	db_user_fill_r(&p->user, stmt, pos);
  289 }
  290 
  291 void
  292 db_session_fill(struct session *p, struct ksqlstmt *stmt, size_t *pos)
  293 {
  294 	size_t i = 0;
  295 
  296 	if (NULL == pos)
  297 		pos = &i;
  298 	memset(p, 0, sizeof(*p));
  299 	p->userid = ksql_stmt_int(stmt, (*pos)++);
  300 	p->id = ksql_stmt_int(stmt, (*pos)++);
  301 }
  302 
  303 static void
  304 db_session_unfill_r(struct session *p)
  305 {
  306 	if (NULL == p)
  307 		return;
  308 
  309 	db_session_unfill(p);
  310 	db_user_unfill_r(&p->user);
  311 }
  312 
  313 void
  314 db_session_unfill(struct session *p)
  315 {
  316 	if (NULL == p)
  317 		return;
  318 }
  319 
  320 void
  321 db_session_free(struct session *p)
  322 {
  323 	db_session_unfill_r(p);
  324 	free(p);
  325 }
  326 
  327 int64_t
  328 db_session_insert(struct kwbp *ctx, int64_t v1)
  329 {
  330 	struct ksqlstmt *stmt;
  331 	int64_t id = -1;
  332 	struct ksql *db = ctx->db;
  333 
  334 	/* Restrict to allowed roles. */
  335 
  336 	switch (ctx->role) {
  337 	case ROLE_user:
  338 	case ROLE_admin:
  339 		break;
  340 	default:
  341 		abort();
  342 	}
  343 
  344 	ksql_stmt_alloc(db, &stmt,
  345 		stmts[STMT_SESSION_INSERT],
  346 		STMT_SESSION_INSERT);
  347 	ksql_bind_int(stmt, 0, v1);
  348 	if (KSQL_DONE == ksql_stmt_cstep(stmt))
  349 		ksql_lastid(db, &id);
  350 	ksql_stmt_free(stmt);
  351 	return(id);
  352 }
  353 
  354 void
  355 json_session_data(struct kjsonreq *r, const struct session *p)
  356 {
  357 	kjson_objp_open(r, "user");
  358 	json_user_data(r, &p->user);
  359 	kjson_obj_close(r);
  360 	kjson_putintp(r, "userid", p->userid);
  361 	kjson_putintp(r, "id", p->id);
  362 }
  363 
  364 void
  365 json_session_obj(struct kjsonreq *r, const struct session *p)
  366 {
  367 	kjson_objp_open(r, "session");
  368 	json_session_data(r, p);
  369 	kjson_obj_close(r);
  370 }
  371 
  372 int
  373 valid_session_userid(struct kpair *p)
  374 {
  375 	if ( ! kvalid_int(p))
  376 		return(0);
  377 	return(1);
  378 }
  379 
  380 int
  381 valid_session_id(struct kpair *p)
  382 {
  383 	if ( ! kvalid_int(p))
  384 		return(0);
  385 	return(1);
  386 }
  387 
  388 struct session *
  389 db_session_get_id(struct kwbp *ctx, int64_t v1)
  390 {
  391 	struct ksqlstmt *stmt;
  392 	struct session *p = NULL;
  393 	struct ksql *db = ctx->db;
  394 
  395 	/* Restrict to allowed roles. */
  396 
  397 	switch (ctx->role) {
  398 	case ROLE_default:
  399 	case ROLE_user:
  400 	case ROLE_admin:
  401 		break;
  402 	default:
  403 		abort();
  404 	}
  405 
  406 	ksql_stmt_alloc(db, &stmt,
  407 		stmts[STMT_SESSION_BY_SEARCH_0],
  408 		STMT_SESSION_BY_SEARCH_0);
  409 	ksql_bind_int(stmt, 0, v1);
  410 	if (KSQL_ROW == ksql_stmt_step(stmt)) {
  411 		p = malloc(sizeof(struct session));
  412 		if (NULL == p) {
  413 			perror(NULL);
  414 			exit(EXIT_FAILURE);
  415 		}
  416 		db_session_fill_r(p, stmt, NULL);
  417 	}
  418 	ksql_stmt_free(stmt);
  419 	return(p);
  420 }
  421 
  422 int
  423 db_session_delete_by_id_eq(struct kwbp *ctx, int64_t v1)
  424 {
  425 	struct ksqlstmt *stmt;
  426 	enum ksqlc c;
  427 	struct ksql *db = ctx->db;
  428 
  429 	/* Restrict to allowed roles. */
  430 
  431 	switch (ctx->role) {
  432 	case ROLE_user:
  433 	case ROLE_admin:
  434 		break;
  435 	default:
  436 		abort();
  437 	}
  438 
  439 	ksql_stmt_alloc(db, &stmt,
  440 		stmts[STMT_SESSION_DELETE_0],
  441 		STMT_SESSION_DELETE_0);
  442 	ksql_bind_int(stmt, 0, v1);
  443 	c = ksql_stmt_cstep(stmt);
  444 	ksql_stmt_free(stmt);
  445 	return(KSQL_CONSTRAINT != c);
  446 }
  447