Postgresql kérdések

Tags: #<Tag:0x00007f8a1a6fc0d8> #<Tag:0x00007f8a1a703f40> #<Tag:0x00007f8a1a703e00> #<Tag:0x00007f8a1a703cc0>

Megőrülök… már egy jó ideje nem tudok rájönni, hogy mi a baj.

Php-ban szeretnék csinálni adatbázist. Teljesen nulláról felépíteni.
A gond az, hogy szeretnék két user-t létrehozni. Egy aki az adatbázist írni is tudja (puser), egy másikat pedig ami csak olvasni tudja (pread).
A két usert közös funkcióból hozom létre, tehát ugyanaz a kód fut mindkét esetében. Ami különbség az a nevük (, jelszavuk) és a jogosultság. A pread user pesrze csak SELECT jogosultságot kap.

Az első puser tökéletesen működik, míg a második pread userrel nem tudok sem SELECT sem semmi mást futtatni az adatbázisban.

Aztán kirpóbáltam, hogy a SELECT helyett egy az egyben ugyan azokat a jogokat kapja a pread user, mint a sima puser.

Szóval az alábbi sorok futnak le a userek létrehozásánál:

CREATE USER puser WITH PASSWORD 'u' NOSUPERUSER INHERIT NOCREATEDB NOCREATEROLE;
SET SEARCH_PATH TO public;
GRANT USAGE ON SCHEMA public TO puser;
GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO puser;
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL PRIVILEGES ON TABLES TO puser;

CREATE USER pread WITH PASSWORD 'r' NOSUPERUSER INHERIT NOCREATEDB NOCREATEROLE;
SET SEARCH_PATH TO public;
GRANT USAGE ON SCHEMA public TO pread;
GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO pread;
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL PRIVILEGES ON TABLES TO pread;

És a táblát ezután hozom létre. És lehet, hogy fontos, hogy létrehozok egy funkciót és egy triggert is.

CREATE TABLE IF NOT EXISTS public.users (id SERIAL,title varchar(20),name varchar(20),created TIMESTAMP DEFAULT NOW(),modified TIMESTAMP DEFAULT NOW());
CREATE FUNCTION users_update_modified_column() RETURNS trigger LANGUAGE plpgsql AS $$ BEGIN NEW.modified = NOW(); RETURN NEW; END; $$;
CREATE TRIGGER users_modified_time BEFORE UPDATE ON public.users FOR EACH ROW EXECUTE PROCEDURE users_update_modified_column();

Ha ugyanezeket a sorokat parancssorból futtatom, akkor tudom a pread userrel olvasni a dolgokat, de ha a php-ból futtatom, akkor nem.
A php-ból futtatás során nem dob hibát. És természetesen a php_connect-nél az adatbázishoz csatlakozom.

Próbáltam úgy is, hogy ALTER DEFAULT… SEQUENCES-hez is jogot adni, de semmi.
Szóval azt nem értem, hogy az első miért sikerül és a második miért nem, ha ugyanaz a funkció hozza létre??? Ráadásul a két funkció egymás után van, nincs semmi sem köztük.

Ja igen, ha megnézem a \ddp paranncsal, akkor (ha jól értem) helyesen létrejön az default érték:

teszt=> \ddp

             Default access privileges
  Owner   | Schema | Type  |   Access privileges    
----------+--------+-------+------------------------
 postgres | public | table | puser=arwdDxt/postgres+
          |        |       | pread=arwdDxt/postgres

bemásolom ide a php kódot, hogy az is hátha segít:

public function createUserIfNeeded($user, $password, $privileges = NULL, $grants = NULL) {
	$dbName = $this->dbName;
	$schema = $this->schema;

	error_log("database name: $dbName");

	if ($this->userIsExistInDatabase($user)) {
		return true;
	}

	$dbHandle = $this->getCreateHandle($dbName);

	$query = "CREATE USER ".$user." WITH PASSWORD '".$password."'";
	if (!empty($privileges)) {
		$query .= " $privileges";
	}
	$query .= ";";
	$this->query($query, array('transaction' => $this->writeTransactionKey()), $dbHandle);

	$query = "SET SEARCH_PATH TO $schema;";
	$this->query($query, array('transaction' => $this->writeTransactionKey()), $dbHandle);

	$query = "GRANT USAGE ON SCHEMA $schema TO $user;";
	$this->query($query, array('transaction' => $this->writeTransactionKey()), $dbHandle);

	if (!empty($grants)) {
		$query = "GRANT $grants ON ALL TABLES IN SCHEMA $schema TO $user;";
		$this->query($query, array('transaction' => $this->writeTransactionKey()), $dbHandle);
		$query = "ALTER DEFAULT PRIVILEGES IN SCHEMA $schema GRANT $grants ON TABLES TO $user;";
		$this->query($query, array('transaction' => $this->writeTransactionKey()), $dbHandle);
//			$query = "ALTER DEFAULT PRIVILEGES IN SCHEMA $schema GRANT $grants ON SEQUENCES TO $user;";
//			$this->query($query, array('transaction' => $this->writeTransactionKey()), $dbHandle);
//			$query = "ALTER DEFAULT PRIVILEGES IN SCHEMA $schema GRANT USAGE, SELECT ON SEQUENCES TO $user;";
//			$this->query($query, array('transaction' => $this->writeTransactionKey()), $dbHandle);
//			$query = "ALTER DEFAULT PRIVILEGES IN SCHEMA $schema GRANT EXECUTE ON FUNCTIONS TO $user;";
//			$this->query($query, array('transaction' => $this->writeTransactionKey()), $dbHandle);
	}

	$this->closeDBHandle($dbHandle);

	return true;
}

Csak egy tipp: probald meg elobb letrehozni a tablat, es utana jogot adni hozza pread-nek.

Az működik. És bár ez lesz a végső megoldás, de az ALTER DEFAULT PRIVILEGES pont ezt hivatott kikerülni, hogy ne kelljen minden egyes tábla létrehozása után megadni a jogokat is.
Bár mondjuk a végső megoldás valószínű az lesz, hogy csoportot is létre kell majd hozni, a csoport lesz a tulajdonosa a táblának és ahhoz fognak tartozni a userek.
És az a rohadt idegesítő, hogy ha egyesével beütöm ugyanezeket a parancsokat, akkor meg szépen működik.
Az egyetlen ami még eszembe jut, hogy nem jön létre a tábla összes tulajdonsága addigra, mire meghívom az ALTER DEFAULT PRIVILEGES parancsot és emiatt nem kerül be helyesen a jogosultság.

Szerintem itt a tranzakcio hatarokkal lesz a gond. Ha kezzel irod be kliensbe, ott altalaban minden sor sajat tranzakcioban megy.
Amikor PHP-ben kuldod be, ott lehet, hogy csoportositja. Mivel ALTER DEFAULT PRIVILEGES csak a kiadasat kovetoen letrehozott objektumokra vonatkozik, igy a vele egy menetben letrejottek szurke zonaba esnek. Ha akarom neki van igaza, ha akarom nem…