From 10f7aab3edcc8833c937dfa6c1c2ef6a05644423 Mon Sep 17 00:00:00 2001 From: Andrew Wang Date: Sat, 21 Aug 2021 02:00:26 -0400 Subject: [PATCH] cleaning up --- README.md | 39 +++++++++++++++++++++++++++++++++++- ceod/api/database.py | 4 +++- ceod/db/MySQLService.py | 1 - ceod/db/PostgreSQLService.py | 16 +-------------- requirements.txt | 3 ++- 5 files changed, 44 insertions(+), 19 deletions(-) diff --git a/README.md b/README.md index b286421..3315dd0 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,10 @@ +### TODO before merge +- testing and tests +- need someone to test isolation of PostgreSQL users +- handling for improper (missing values, unable to connect) config +- make MySQLService and PostgreSQLService look nicer to read +- check database.py + # pyceo [![Build Status](https://ci.csclub.uwaterloo.ca/api/badges/public/pyceo/status.svg?ref=refs/heads/v1)](https://ci.csclub.uwaterloo.ca/public/pyceo) @@ -33,7 +40,37 @@ On phosphoric-acid, you will additionally need to create a principal called `ceod/admin` (remember to addprinc **and** ktadd). #### Database -TODO - Andrew +Edit the `/etc/csc/ceod.ini` with the credentials required to access MySQL and PostgreSQL +``` +[mysql] +host = +username = +password = + +[postgresql] +host = +usrename = +password = +``` +#### PostgreSQL Database +PostgreSQL is not designed for isolation of users and by default will allow any user to connect and edit any database. To disallow users to create public schema we run +``` +su postgres +psql + +REVOKE ALL ON SCHEMA public FROM public; +GRANT ALL ON SCHEMA public TO postgres; +``` +We also want to change `pg_hba.conf` to only allow local connections and force the requested database to have the same name as the user creating the connection ([more info](https://www.postgresql.org/docs/9.1/auth-pg-hba-conf.html)) +``` +# TYPE DATABASE USER ADDRESS METHOD +local all postgres peer +local sameuser all md5 +``` +- peer authentication only requires that your os username matches the postgres username (no password) +- Users will have access to list of databases and users, and this cannot be disabled without possible issues ([more info](https://wiki.postgresql.org/wiki/Shared_Database_Hosting#template1)) +- [Managing rights in PostgreSQL](https://wiki.postgresql.org/images/d/d1/Managing_rights_in_postgresql.pdf) + #### Dependencies Next, install and activate a virtualenv: diff --git a/ceod/api/database.py b/ceod/api/database.py index f0c2444..2ed64e9 100644 --- a/ceod/api/database.py +++ b/ceod/api/database.py @@ -2,7 +2,7 @@ from flask import Blueprint, request from zope import component from ceod.api.utils import authz_restrict_to_staff, authz_restrict_to_syscom, \ user_is_in_group, requires_authentication_no_realm, \ - create_streaming_response, create_sync_response, development_only + create_streaming_response, development_only from ceo_common.errors import UserNotFoundError, DatabaseConnectionError from ceo_common.interfaces import IDatabaseService @@ -10,6 +10,8 @@ from ceo_common.interfaces import IDatabaseService bp = Blueprint('db', __name__) # could combine create_mysql_db and create_postgresql_db into one function +# catch other less expected errors (mysql or psql error) +# handle if user somehow dropped their database @bp.route('/mysql/', methods=['POST']) diff --git a/ceod/db/MySQLService.py b/ceod/db/MySQLService.py index 8baf1b7..2d8aac0 100644 --- a/ceod/db/MySQLService.py +++ b/ceod/db/MySQLService.py @@ -9,7 +9,6 @@ import ceod.utils as utils @implementer(IDatabaseService) class MySQLService: def __init__(self): - # how to set default values for these self.type = 'mysql' config = component.getUtility(IConfig) self.host = config.get('mysql_host') diff --git a/ceod/db/PostgreSQLService.py b/ceod/db/PostgreSQLService.py index 1078c80..4c198ff 100644 --- a/ceod/db/PostgreSQLService.py +++ b/ceod/db/PostgreSQLService.py @@ -15,20 +15,6 @@ class PostgreSQLService: self.auth_username = config.get('postgresql_username') self.auth_password = config.get('postgresql_password') - # https://www.postgresql.org/docs/9.1/auth-pg-hba-conf.html - # pg_hba.conf only listen to localhost and only allow users to login to database with the same name as user - # local sameuser all localhost md5 - # need different line for syscom - - # Allow only postgres to create on the schema public - # REVOKE ALL ON SCHEMA public FROM PUBLIC; - # GRANT ALL ON SCHEMA public TO postgres; - - # by default all database created are open to connection from anyone - # only the owner (and superusers) can ever drop a database - - # note that pg_catalog allows access list of database and user names for everyone and cannot be disabled with breaking some things - def create_db(self, username: str) -> str: component.getUtility(ILDAPService).get_user(username) # make sure user exists password = utils.gen_password() @@ -39,7 +25,7 @@ class PostgreSQLService: user=self.auth_username, password=self.auth_password, ) as con: - # limit access to localhost? + # only the owner (and superusers) can ever drop a database search_for_user = "SELECT FROM pg_roles WHERE rolname='%(username)s'" create_user = "CREATE USER %(username)s WITH NOSUPERUSER NOCREATEDB NOCREATEROLE PASSWORD '%(password)s'" create_database = "CREATE DATABASE %(username)s" diff --git a/requirements.txt b/requirements.txt index 007aa66..f3ed87b 100644 --- a/requirements.txt +++ b/requirements.txt @@ -7,4 +7,5 @@ requests==2.26.0 requests-gssapi==1.2.3 zope.component==5.0.1 zope.interface==5.4.0 -mysql-connector-python==8.0.26 \ No newline at end of file +mysql-connector-python==8.0.26 +psycopg2==2.9.1 \ No newline at end of file