use env variables for admin+restricted user, jdbc-url and admin-password

This commit is contained in:
Michael Hoennig 2024-01-12 18:41:16 +01:00
parent db7c101691
commit 2f5acd4171
14 changed files with 109 additions and 32 deletions

View File

@ -1,3 +1,6 @@
export HSADMINNG_POSTGRES_ADMIN_USERNAME=admin
export HSADMINNG_POSTGRES_RESTRICTED_USERNAME=restricted
gradleWrapper () {
if [ ! -f gradlew ]; then
echo "No 'gradlew' found. Maybe you are not in the root dir of a gradle project?"

View File

@ -39,10 +39,10 @@ public class HsOfficeContactEntity implements Stringifyable, HasUuid {
private String postalAddress;
@Column(name = "emailaddresses", columnDefinition = "json")
private String emailAddresses;
private String emailAddresses; // TODO: check if we can really add multiple. format: ["eins@...", "zwei@..."]
@Column(name = "phonenumbers", columnDefinition = "json")
private String phoneNumbers;
private String phoneNumbers; // TODO: check if we can really add multiple. format: { "office": "+49 40 12345-10", "fax": "+49 40 12345-05" }
@Override
public String toString() {

View File

@ -20,3 +20,7 @@ spring:
liquibase:
contexts: dev
hsadminng:
postgres:
leakproof:

View File

@ -0,0 +1,12 @@
--liquibase formatted sql
-- ============================================================================
-- NUMERIC-HASH-FUNCTIONS
--changeset hash:1 endDelimiter:--//
-- ----------------------------------------------------------------------------
create function postgresAdminUserName() returns text as $$
if
$$ language sql;
--//

View File

@ -763,13 +763,15 @@ $$;
do $$
begin
if '${ADMIN_USER}'='admin' then
if '${HSADMINNG_POSTGRES_ADMIN_USERNAME}'='admin' then
create role admin;
grant all privileges on all tables in schema public to admin;
create role restricted;
grant all privileges on all tables in schema public to restricted;
end if;
if '${HSADMINNG_POSTGRES_RESTRICTED_USERNAME}'='restricted' then
create role restricted;
end if;
-- grant all privileges on all tables in schema public to ${HSADMINNG_POSTGRES_RESTRICTED_USERNAME};
end $$
--//

View File

@ -41,7 +41,7 @@ select *
) as unordered
-- @formatter:on
order by objectTable || '#' || objectIdName || '.' || roleType;
grant all privileges on rbacrole_rv to ${RESTRICTED_USER};
grant all privileges on rbacrole_rv to ${HSADMINNG_POSTGRES_RESTRICTED_USERNAME};
--//
@ -126,7 +126,7 @@ select o.objectTable || '#' || findIdNameByObjectUuid(o.objectTable, o.uuid) ||
join RbacObject as o on o.uuid = r.objectUuid
order by grantedRoleIdName;
-- @formatter:on
grant all privileges on rbacrole_rv to ${RESTRICTED_USER};
grant all privileges on rbacrole_rv to ${HSADMINNG_POSTGRES_RESTRICTED_USERNAME};
--//
@ -240,7 +240,7 @@ create or replace view RbacUser_rv as
) as unordered
-- @formatter:on
order by unordered.name;
grant all privileges on RbacUser_rv to ${RESTRICTED_USER};
grant all privileges on RbacUser_rv to ${HSADMINNG_POSTGRES_RESTRICTED_USERNAME};
--//
-- ============================================================================
@ -326,7 +326,7 @@ select r.uuid as roleuuid, p.uuid as permissionUuid,
join rbacgrants g on g.ascendantuuid = r.uuid
join rbacpermission p on p.uuid = g.descendantuuid
join rbacobject o on o.uuid = p.objectuuid;
grant all privileges on RbacOwnGrantedPermissions_rv to ${RESTRICTED_USER};
grant all privileges on RbacOwnGrantedPermissions_rv to ${HSADMINNG_POSTGRES_RESTRICTED_USERNAME};
-- @formatter:om
-- ============================================================================

View File

@ -104,7 +104,7 @@ begin
create or replace view %1$s_iv as
select target.uuid, cleanIdentifier(%2$s) as idName
from %1$s as target;
grant all privileges on %1$s_iv to ${RESTRICTED_USER};
grant all privileges on %1$s_iv to ${HSADMINNG_POSTGRES_RESTRICTED_USERNAME};
$sql$, targetTable, idNameExpression);
execute sql;
@ -157,7 +157,7 @@ begin
from %1$s as target
where target.uuid in (select * from accessibleObjects)
order by %2$s;
grant all privileges on %1$s_rv to ${RESTRICTED_USER};
grant all privileges on %1$s_rv to ${HSADMINNG_POSTGRES_RESTRICTED_USERNAME};
$sql$, targetTable, orderBy);
execute sql;

View File

@ -18,7 +18,7 @@ create table Global
);
create unique index Global_Singleton on Global ((0));
grant select on global to ${RESTRICTED_USER};
grant select on global to ${HSADMINNG_POSTGRES_RESTRICTED_USERNAME};
--//
@ -48,7 +48,7 @@ drop view if exists global_iv;
create or replace view global_iv as
select target.uuid, target.name as idName
from global as target;
grant all privileges on global_iv to ${RESTRICTED_USER};
grant all privileges on global_iv to ${HSADMINNG_POSTGRES_RESTRICTED_USERNAME};
/*
Returns the objectUuid for a given identifying name (in this case the idName).

View File

@ -93,7 +93,7 @@ call generateRbacIdentityView('test_package', 'target.name');
-- from test_package as target
-- where target.uuid in (select queryAccessibleObjectUuidsOfSubjectIds('view', 'test_package', currentSubjectsUuids()))
-- order by target.name;
-- grant all privileges on test_package_rv to ${RESTRICTED_USER};
-- grant all privileges on test_package_rv to ${HSADMINNG_POSTGRES_RESTRICTED_USERNAME};
call generateRbacRestrictedView('test_package', 'target.name',
$updates$

View File

@ -110,5 +110,5 @@ create or replace view test_domain_rv as
select target.*
from test_domain as target
where target.uuid in (select queryAccessibleObjectUuidsOfSubjectIds('view', 'domain', currentSubjectsUuids()));
grant all privileges on test_domain_rv to ${RESTRICTED_USER};
grant all privileges on test_domain_rv to ${HSADMINNG_POSTGRES_RESTRICTED_USERNAME};
--//

View File

@ -22,6 +22,7 @@ import net.hostsharing.hsadminng.hs.office.sepamandate.HsOfficeSepaMandateEntity
import net.hostsharing.test.JpaAttempt;
import org.junit.jupiter.api.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.context.annotation.Import;
@ -55,30 +56,45 @@ import static org.assertj.core.api.Assertions.assertThat;
* For a real import a main method will be added later
* which reads CSV files from the file system.
*
* When run on a Hostsharing database, it needs the following settings (hsh99_... just examples):
* When run on a Hostsharing database, it needs the following settings (hsh99_... just examples).
*
* In a real hostsharing environment, these are created via (the old) hsadmin:
*
* CREATE USER hsh99_admin WITH PASSWORD 'password';
* GRANT ALL ON SCHEMA public TO hsh99_admin;
* CREATE DATABASE hsh99_hsadminng ENCODING 'UTF8' TEMPLATE template0;
* REVOKE ALL ON DATABASE hsh99_hsadminng FROM public; -- why does hsadmin do that?
* ALTER DATABASE hsh99_hsadminng OWNER TO hsh99_admin;
*
* CREATE USER hsh99_restricted WITH PASSWORD 'password';
* GRANT ALL PRIVILEGES ON ALL TALBES IN SCHEMA hsh99_hsadminng to hsh99_restricted
* GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public to hsh99_restricted;
* Additionally we need these settings (because the Hostsharing DB-Admin has no CREATE right):
*
* CREATE EXTENSION "uuid-ossp";
* CREATE EXTENSION IF EXISTS "uuid-ossp";
*
* And the environment variables ADMIN_USER and RESTRICTED_USER have to be set to the actual users.
* TODO: password
* Then these environment variables need to be set for Liquibase:
* export HSADMIN_POSTGRES_JDBC=jdbc:postgresql://localhost:6432/hsh99_hsadminng
* export HSADMIN_POSTGRES_ADMIN_USERNAME=hsh99_admin
* export HSADMIN_POSTGRES_ADMIN_PASSWORD=password
* export HSADMIN_POSTGRES_RESTRICTED_USERNAME=hsh99_restricted
*
* Then, to run the import, uncomment the @Diabled and then run:
*
* gw test -tests ImportOfficeTables -x check
*/
// @Disabled
//@Disabled
@DataJpaTest(properties = {
"spring.profiles.active=migration",
"spring.datasource.url=jdbc:postgresql://localhost:5432/postgres",
"spring.datasource.username=hsh99_admin",
"spring.datasource.password=password"
"spring.datasource.url=${HSADMIN_POSTGRES_JDBC:jdbc:tc:postgresql:15.5-bookworm:///spring_boot_testcontainers}",
"spring.datasource.username=${HSADMIN_POSTGRES_ADMIN_USERNAME:admin}",
"spring.datasource.password=${HSADMIN_POSTGRES_ADMIN_PASSWORD:password}"
})
@Import({ Context.class, JpaAttempt.class })
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class ImportOfficeTables extends ContextBasedTest {
@Value("${spring.datasource.url}")
private String jdbcUrl;
// TODO: use real rbacSuperuser for actual import
private static final String rbacSuperuser = "superuser-alex@hostsharing.net";
@ -115,6 +131,10 @@ public class ImportOfficeTables extends ContextBasedTest {
throw new RuntimeException(e);
}
if ( !"admin".equals(System.getenv("ADMIN_USER") )) {
return;
}
// no contacts yet => mostly null values
assertThat(partners.toString()).isEqualToIgnoringWhitespace("""
{
@ -150,6 +170,10 @@ public class ImportOfficeTables extends ContextBasedTest {
throw new RuntimeException(e);
}
if ( !"admin".equals(System.getenv("ADMIN_USER") )) {
return;
}
assertThat(partners.toString()).isEqualToIgnoringWhitespace("""
{
7=partner(Mellies, Michael: Herr Michael Mellies ),
@ -199,6 +223,10 @@ public class ImportOfficeTables extends ContextBasedTest {
throw new RuntimeException(e);
}
if ( !"admin".equals(System.getenv("ADMIN_USER") )) {
return;
}
assertThat(bankAccounts.toString()).isEqualToIgnoringWhitespace("""
{
234234=bankAccount(holder='Michael Mellies', iban='DE37500105177419788228', bic='INGDDEFFXXX'),
@ -224,6 +252,10 @@ public class ImportOfficeTables extends ContextBasedTest {
throw new RuntimeException(e);
}
if ( !"admin".equals(System.getenv("ADMIN_USER") )) {
return;
}
assertThat(coopShares.toString()).isEqualToIgnoringWhitespace("""
{
33443=CoopShareTransaction(10007, 2000-12-06, SUBSCRIPTION, 20, initial share subscription),
@ -245,6 +277,10 @@ public class ImportOfficeTables extends ContextBasedTest {
throw new RuntimeException(e);
}
if ( !"admin".equals(System.getenv("ADMIN_USER") )) {
return;
}
assertThat(coopAssets.toString()).isEqualToIgnoringWhitespace("""
{
30000=CoopAssetsTransaction(10007, 2000-12-06, DEPOSIT, 1280.00, for subscription A),
@ -442,7 +478,7 @@ public class ImportOfficeTables extends ContextBasedTest {
.debitorNumberSuffix((byte) 0)
.defaultPrefix(rec.getString("member_code").replace("hsh00-", ""))
.partner(partner)
.billingContact(partner.getContact())
.billingContact(partner.getContact()) // TODO falsch
.billable(rec.isEmpty("free"))
.vatReverseCharge(rec.getBoolean("exempt_vat"))
.vatBusiness("GROSS".equals(rec.getString("indicator_vat"))) // TODO: remove

View File

@ -7,12 +7,14 @@ import net.hostsharing.hsadminng.rbac.rbacuser.RbacUserRepository;
import net.hostsharing.test.Accepts;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.web.server.LocalServerPort;
import jakarta.persistence.EntityManager;
import jakarta.persistence.PersistenceContext;
import static org.assertj.core.api.Assertions.assertThat;
import static org.hamcrest.Matchers.*;
@SpringBootTest(
@ -37,6 +39,14 @@ class RbacRoleControllerAcceptanceTest {
@Autowired
RbacRoleRepository rbacRoleRepository;
@Value("${HSADMINNG_POSTGRES_RESTRICTED_USERNAME}")
String restrictedUser;
@Test
void testEnv() {
assertThat(restrictedUser).isEqualTo("restricted");
}
@Test
@Accepts({ "ROL:L(List)" })
void globalAdmin_withoutAssumedRole_canViewAllRoles() {

View File

@ -9,6 +9,7 @@ import net.hostsharing.test.JpaAttempt;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.web.server.LocalServerPort;
import org.springframework.transaction.annotation.Transactional;
@ -42,6 +43,14 @@ class RbacUserControllerAcceptanceTest {
@Autowired
RbacUserRepository rbacUserRepository;
@Value("${HSADMINNG_POSTGRES_RESTRICTED_USERNAME}")
String restrictedUser;
@Test
void testEnv() {
assertThat(restrictedUser).isEqualTo("restricted");
}
@Nested
class CreateRbacUser {

View File

@ -1,5 +1,6 @@
contact_id; bp_id; salut; first_name; last_name; title; firma; co; street; zipcode;city; country; phone_private; phone_office; phone_mobile; fax; email; roles
71; 7; Herr; Michael; Mellies; ; ; ; Kleine Freiheit 50; 26524; Hage; DE; ; +49 4931 123456; +49 1522 123456;; mih@example.org; billing,operation
101; 10; Frau; Jenny; Meyer; Dr.; JM e.K.;; Waldweg 5; 11001; Berlin; DE; +49 30 7777777; +49 30 8888888; ; +49 30 9999999; jm@example.org; billing
102; 10; Herr; Andrew; Meyer; ; JM e.K.;; Waldweg 5; 11001; Berlin; DE; +49 30 6666666; +49 30 5555555; ; +49 30 9999999; am@example.org; operation
121; 12; ; Petra; Schmidt; ; Test PS;; ; ; ; ; ; ; ; ; ps@example.com; billing,operation
71; 7; Herr; Michael; Mellies; ; ; ; Kleine Freiheit 50; 26524; Hage; DE; ; +49 4931 123456; +49 1522 123456;; mih@example.org; contractual,billing,operation
101; 10; Frau; Jenny; Meyer; Dr.; JM e.K.;; Waldweg 5; 11001; Berlin; DE; +49 30 7777777; +49 30 1111111; ; +49 30 2222222; jm@example.org; billing
102; 10; Herr; Andrew; Meyer; ; JM e.K.;; Waldweg 5; 11001; Berlin; DE; +49 30 6666666; +49 30 3333333; ; +49 30 4444444; am@example.org; operation
102; 10; Herr; Philip; Meyer; ; JM e.K.;; Waldweg 5; 11001; Berlin; DE; +49 30 6666666; +49 30 5555555; ; +49 30 6666666; pm@example.org; contractual
121; 12; ; Petra; Schmidt; ; Test PS;; ; ; ; ; ; ; ; ; ps@example.com; billing,contractual,operation

1 contact_id bp_id salut first_name last_name title firma co street zipcode city country phone_private phone_office phone_mobile fax email roles
2 71 7 Herr Michael Mellies Kleine Freiheit 50 26524 Hage DE +49 4931 123456 +49 1522 123456 mih@example.org billing,operation contractual,billing,operation
3 101 10 Frau Jenny Meyer Dr. JM e.K. Waldweg 5 11001 Berlin DE +49 30 7777777 +49 30 8888888 +49 30 1111111 +49 30 9999999 +49 30 2222222 jm@example.org billing
4 102 10 Herr Andrew Meyer JM e.K. Waldweg 5 11001 Berlin DE +49 30 6666666 +49 30 5555555 +49 30 3333333 +49 30 9999999 +49 30 4444444 am@example.org operation
5 121 102 12 10 Herr Petra Philip Schmidt Meyer Test PS JM e.K. Waldweg 5 11001 Berlin DE +49 30 6666666 +49 30 5555555 +49 30 6666666 ps@example.com pm@example.org billing,operation contractual
6 121 12 Petra Schmidt Test PS ps@example.com billing,contractual,operation