Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 22 additions & 8 deletions src/auth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,14 @@ pub struct Authenticated {

impl Authenticated {
pub fn can_access_schema(&self, schema: &str) -> bool {
if self.schemas.is_empty() {
if self.role == "admin" {
return true;
}

if self.schemas.is_empty() {
return false;
}

self.schemas.iter().any(|s| s == schema)
}
}
Expand Down Expand Up @@ -193,13 +198,22 @@ pub async fn register(

let mut conn = get_connection();

// Determine role: first registered user becomes admin, others are regular users.
let count_row = diesel::sql_query("SELECT COUNT(*)::INT as count FROM \"Auth\".users")
.get_result::<UserCount>(&mut conn)
.unwrap_or(UserCount { count: 0 });

let role = if count_row.count == 0 {
"admin".to_string()
// Determine role. By default the first registered user becomes admin
// (for easy bootstrap), but this behavior can be disabled by setting
// AUTH_BOOTSTRAP_MODE to any value other than "first-user-admin".
let bootstrap_mode = std::env::var("AUTH_BOOTSTRAP_MODE")
.unwrap_or_else(|_| "first-user-admin".to_string());

let role = if bootstrap_mode == "first-user-admin" {
let count_row = diesel::sql_query("SELECT COUNT(*)::INT as count FROM \"Auth\".users")
.get_result::<UserCount>(&mut conn)
.unwrap_or(UserCount { count: 0 });

if count_row.count == 0 {
"admin".to_string()
} else {
"user".to_string()
}
} else {
"user".to_string()
};
Expand Down
5 changes: 5 additions & 0 deletions src/createdatabase.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
use crate::dbconnect;
use diesel::prelude::*;
use diesel::sql_query;
use crate::validation;
//create a logical database (schema) in Postgres and register an API key
pub fn create_database(database_name: &str) {
let mut conn = dbconnect::internalqueryconn();
// database_name is expected to be validated at the HTTP layer; this is
// a final safety net.
assert!(validation::is_valid_identifier(database_name));
let mut query = String::from("CREATE SCHEMA IF NOT EXISTS ");
query.push_str(database_name);
query.push_str(";");
Expand All @@ -16,6 +20,7 @@ pub fn create_database(database_name: &str) {
pub fn create_databaseweb(database: &str) -> String {
let mut conn = dbconnect::internalqueryconn();
let dbname = String::from(database);
assert!(validation::is_valid_identifier(&dbname));
let mut query = String::from("CREATE SCHEMA IF NOT EXISTS ");
query.push_str(&dbname);
query.push_str(";");
Expand Down
5 changes: 0 additions & 5 deletions src/dbconnect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,6 @@ use csv::ReaderBuilder;
use diesel::pg::PgConnection;
use diesel::prelude::*;

// For Postgres/Diesel we maintain a single physical database and use
// the `database` argument only as a logical schema/table prefix inside SQL.
// All connections are created from a DATABASE_URL environment variable.
pub fn database_connection(_database: &str) -> PooledConn {
internalqueryconn()
}
Expand All @@ -22,7 +19,6 @@ pub fn database_connection_no_db() -> PooledConn {
internalqueryconn()
}
fn grabfromfile() -> LinkDataBase {
//igneroe header
let mut reader = ReaderBuilder::new()
.has_headers(false)
.from_path("tmp/dbconnection.txt")
Expand All @@ -34,7 +30,6 @@ fn grabfromfile() -> LinkDataBase {
dbport: String::new(),
};
for result in reader.records() {
//ignore header

let record = result.unwrap();
println!("{:?}", record);
Expand Down
27 changes: 19 additions & 8 deletions src/delete.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,27 +7,38 @@ pub fn deleterecord(
table: &str,
id: Vec<(String, String)>,
) -> std::result::Result<String, String> {
//grab second string from tuple
// Collect and validate numeric IDs make sure positive
let mut numeric_ids: Vec<i64> = Vec::new();
for (_, raw) in id.iter() {
let trimmed = raw.trim().trim_matches('"');
match trimmed.parse::<i64>() {
Ok(v) if v > 0 => numeric_ids.push(v),
_ => return Err("invalid record id".to_string()),
}
}

if numeric_ids.is_empty() {
return Err("no record ids provided".to_string());
}

let mut stmt = String::from("DELETE FROM ");
stmt.push_str(database);
stmt.push_str(".");
stmt.push_str(table);
stmt.push_str(" WHERE ");
stmt.push_str("INTERNAL_PRIMARY_KEY");
stmt.push_str(" in( ");
for i in 0..id.len() {
stmt.push_str(&id[i].1);
if i != id.len() - 1 {
stmt.push_str(" WHERE INTERNAL_PRIMARY_KEY IN (");
for (idx, v) in numeric_ids.iter().enumerate() {
if idx > 0 {
stmt.push_str(", ");
}
stmt.push_str(&v.to_string());
}
stmt.push_str(")");
println!("{}", stmt);
Ok(stmt)
}

pub fn droptable(database: &str, table: &str) -> std::result::Result<String, String> {
//grab second string from tuple
// This is only called from admin-only handlers; the database and table
let mut stmt = String::from("DROP TABLE ");
stmt.push_str(database);
stmt.push_str(".");
Expand Down
5 changes: 0 additions & 5 deletions src/initconnect.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,3 @@
//initialize conenction parameters like username, password, host, port
//use crate::LinkDataBase;
//use std::fs::File;
//use std::io::Write;

pub fn getpagehtml() -> String {
//get page html to type username, password, host, port.
let mut html = String::new();
Expand Down
11 changes: 5 additions & 6 deletions src/insertrecords.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ impl TableDef {
}
}
stmt.push_str(") VALUES (");
for data in date.iter() {
for (record_idx, data) in date.iter().enumerate() {
for i in 0..data.len() {
let mut valuedata = data[i].1.replace("\"", "");
// Escape single quotes for SQL literal
Expand All @@ -87,12 +87,11 @@ impl TableDef {
stmt.push_str(", ");
}
}
stmt.push_str("), (");
if record_idx != date.len() - 1 {
stmt.push_str("), (");
}
}
// remove the trailing `, (`
stmt.pop();
stmt.pop();
stmt.pop();
stmt.push_str(")");
stmt
}
}
Expand Down
Loading
Loading