Repository: frappe/frappe

Issue:
Facing two issues while setting up Postgresql with frappe

1) Frappe Postgres setup expects to have a user in Postgresql that is same as the system user. So user can log in to psql without any password.

So if we don't have Postgres user same as a system user, then  while connecting to Postgres we get an error

`psycopg2.OperationalError: fe_sendauth: no password supplied` since fraape not supplying password
https://github.com/frappe/frappe/blob/develop/frappe/database/postgres/database.py#L66

2) Bootstrapping postgres db is executed as default user since we are not passing
the the fraape db user. (https://github.com/frappe/frappe/blob/develop/frappe/database/postgres/setup_db.py#L14)

So while accessing the tables by fraape db user, we are getting an error

`psycopg2.ProgrammingError: permission denied for relation tabDefaultValue`

How to reproduce:
Try to install frappe with Postgres in a system where there is not Postgres user same system user.


Discussion:

Resolving patch:
diff --git a/frappe/database/postgres/database.py b/frappe/database/postgres/database.py
--- a/frappe/database/postgres/database.py
+++ b/frappe/database/postgres/database.py
@@ -64,10 +64,10 @@ def setup_type_map(self):
 
 	def get_connection(self):
 		# warnings.filterwarnings('ignore', category=psycopg2.Warning)
-		conn = psycopg2.connect('host={} dbname={} port={}'.format(self.host, self.user, self.port))
+		conn = psycopg2.connect('host={} dbname={} user={} password={} port={}'.format(
+			self.host, self.user, self.user, self.password, self.port
+		))
 		conn.set_isolation_level(ISOLATION_LEVEL_AUTOCOMMIT) # TODO: Remove this
-		# conn = psycopg2.connect('host={} dbname={} user={} password={}'.format(self.host,
-		# 	self.user, self.user, self.password))
 
 		return conn
 
@@ -310,4 +310,4 @@ def replace_locate_with_strpos(query):
 	# strpos is the locate equivalent in postgres
 	if re.search(r'locate\(', query, flags=re.IGNORECASE):
 		query = re.sub(r'locate\(([^,]+),([^)]+)\)', r'strpos(\2, \1)', query, flags=re.IGNORECASE)
-	return query
\ No newline at end of file
+	return query
diff --git a/frappe/database/postgres/setup_db.py b/frappe/database/postgres/setup_db.py
--- a/frappe/database/postgres/setup_db.py
+++ b/frappe/database/postgres/setup_db.py
@@ -1,4 +1,5 @@
 import frappe, subprocess, os
+from six.moves import input
 
 def setup_database(force, source_sql, verbose):
 	root_conn = get_root_connection()
@@ -10,9 +11,16 @@ def setup_database(force, source_sql, verbose):
 		frappe.conf.db_password))
 	root_conn.sql("GRANT ALL PRIVILEGES ON DATABASE `{0}` TO {0}".format(frappe.conf.db_name))
 
+	# we can't pass psql password in arguments in postgresql as mysql. So
+	# set password connection parameter in environment variable
+	subprocess_env = os.environ.copy()
+	subprocess_env['PGPASSWORD'] = str(frappe.conf.db_password)
 	# bootstrap db
-	subprocess.check_output(['psql', frappe.conf.db_name, '-qf',
-		os.path.join(os.path.dirname(__file__), 'framework_postgres.sql')])
+	subprocess.check_output([
+		'psql', frappe.conf.db_name, '-h', 'localhost', '-U',
+		frappe.conf.db_name, '-f',
+		os.path.join(os.path.dirname(__file__), 'framework_postgres.sql')
+	], env=subprocess_env)
 
 	frappe.connect()
 
@@ -24,17 +32,20 @@ def setup_help_database(help_db_name):
 	root_conn.sql("CREATE user {0} password '{1}'".format(help_db_name, help_db_name))
 	root_conn.sql("GRANT ALL PRIVILEGES ON DATABASE `{0}` TO {0}".format(help_db_name))
 
-def get_root_connection(root_login='postgres', root_password=None):
+def get_root_connection(root_login=None, root_password=None):
 	import getpass
 	if not frappe.local.flags.root_connection:
 		if not root_login:
-			root_login = 'root'
+			root_login = frappe.conf.get("root_login") or None
+
+		if not root_login:
+			root_login = input("Enter postgres super user: ")
 
 		if not root_password:
 			root_password = frappe.conf.get("root_password") or None
 
 		if not root_password:
-			root_password = getpass.getpass("Postgres root password: ")
+			root_password = getpass.getpass("Postgres super user password: ")
 
 		frappe.local.flags.root_connection = frappe.database.get_db(user=root_login, password=root_password)
 


Test patch:
diff --git a/test_sites/test_site_postgres/site_config.json b/test_sites/test_site_postgres/site_config.json
--- a/test_sites/test_site_postgres/site_config.json
+++ b/test_sites/test_site_postgres/site_config.json
@@ -7,6 +7,7 @@
  "mail_login": "test@example.com",
  "mail_password": "test",
  "admin_password": "admin",
+ "root_login": "postgres",
  "root_password": "travis",
  "run_selenium_tests": 1,
  "host_name": "http://test_site_postgres:8000"