fix: merged
This commit is contained in:
commit
7a9955b781
19
.gitea/workflows/back.yaml
Normal file
19
.gitea/workflows/back.yaml
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
name: Format
|
||||||
|
|
||||||
|
on: [ push, pull_request ]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
|
||||||
|
formatting:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4 # v2 minimum required
|
||||||
|
- uses: actions/setup-java@v4
|
||||||
|
with:
|
||||||
|
distribution: 'temurin' # See 'Supported distributions' for available options
|
||||||
|
java-version: '21'
|
||||||
|
- uses: axel-op/googlejavaformat-action@v3
|
||||||
|
with:
|
||||||
|
args: "--replace --skip-sorting-imports --aosp"
|
||||||
|
- name: Print diffs
|
||||||
|
run: git --no-pager diff --exit-code
|
1
.gitignore
vendored
1
.gitignore
vendored
@ -2,3 +2,4 @@
|
|||||||
.idea
|
.idea
|
||||||
keycloak/CAS/target
|
keycloak/CAS/target
|
||||||
docker-compose.yaml
|
docker-compose.yaml
|
||||||
|
postgres/data
|
2
Makefile
2
Makefile
@ -27,7 +27,7 @@ dev-front: clean vite
|
|||||||
prod: clean
|
prod: clean
|
||||||
@cp config/prod.front.env front/MyINPulse-front/.env
|
@cp config/prod.front.env front/MyINPulse-front/.env
|
||||||
@cp config/prod.main.env .env
|
@cp config/prod.main.env .env
|
||||||
@cp config/frontdev.docker-compose.yaml docker-compose.yaml
|
@cp config/prod.docker-compose.yaml docker-compose.yaml
|
||||||
@docker compose up -d --build
|
@docker compose up -d --build
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,29 +1,15 @@
|
|||||||
package enseirb.myinpulse;
|
package enseirb.myinpulse;
|
||||||
|
|
||||||
import enseirb.myinpulse.security.KeycloakJwtRolesConverter;
|
|
||||||
import org.springframework.boot.SpringApplication;
|
import org.springframework.boot.SpringApplication;
|
||||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
import org.springframework.context.annotation.Bean;
|
|
||||||
import org.springframework.core.convert.converter.Converter;
|
|
||||||
import org.springframework.security.authentication.AbstractAuthenticationToken;
|
|
||||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
|
||||||
import org.springframework.security.oauth2.jwt.*;
|
import org.springframework.security.oauth2.jwt.*;
|
||||||
import org.springframework.security.web.SecurityFilterChain;
|
|
||||||
import org.springframework.web.cors.CorsConfiguration;
|
|
||||||
import org.springframework.web.cors.CorsConfigurationSource;
|
|
||||||
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
|
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
import static org.springframework.security.authorization.AuthorityAuthorizationManager.hasRole;
|
|
||||||
|
|
||||||
@SpringBootApplication
|
@SpringBootApplication
|
||||||
public class MyinpulseApplication {
|
public class MyinpulseApplication {
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
SpringApplication.run(MyinpulseApplication.class, args);
|
SpringApplication.run(MyinpulseApplication.class, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -22,21 +22,21 @@ public class GetUserInfo {
|
|||||||
|
|
||||||
@CrossOrigin(methods = {RequestMethod.GET, RequestMethod.OPTIONS})
|
@CrossOrigin(methods = {RequestMethod.GET, RequestMethod.OPTIONS})
|
||||||
@GetMapping("/random")
|
@GetMapping("/random")
|
||||||
public boolean rand(){
|
public boolean rand() {
|
||||||
System.err.println("HELLO");
|
System.err.println("HELLO");
|
||||||
return Math.random() > 0.5;
|
return Math.random() > 0.5;
|
||||||
}
|
}
|
||||||
|
|
||||||
@CrossOrigin(methods = {RequestMethod.GET, RequestMethod.OPTIONS})
|
@CrossOrigin(methods = {RequestMethod.GET, RequestMethod.OPTIONS})
|
||||||
@GetMapping("/random2")
|
@GetMapping("/random2")
|
||||||
public boolean rand2(){
|
public boolean rand2() {
|
||||||
System.err.println("HELLO2");
|
System.err.println("HELLO2");
|
||||||
return Math.random() > 0.5;
|
return Math.random() > 0.5;
|
||||||
}
|
}
|
||||||
|
|
||||||
@CrossOrigin(methods = {RequestMethod.GET, RequestMethod.OPTIONS})
|
@CrossOrigin(methods = {RequestMethod.GET, RequestMethod.OPTIONS})
|
||||||
@GetMapping("/random3")
|
@GetMapping("/random3")
|
||||||
public boolean rand3(){
|
public boolean rand3() {
|
||||||
System.err.println("HELLO");
|
System.err.println("HELLO");
|
||||||
return Math.random() > 0.5;
|
return Math.random() > 0.5;
|
||||||
}
|
}
|
||||||
|
@ -23,10 +23,13 @@ public class WebSecurityCustomConfiguration {
|
|||||||
CorsConfiguration configuration = new CorsConfiguration();
|
CorsConfiguration configuration = new CorsConfiguration();
|
||||||
configuration.setAllowedOrigins(List.of("*"));
|
configuration.setAllowedOrigins(List.of("*"));
|
||||||
configuration.setAllowedMethods(Arrays.asList("GET", "OPTIONS"));
|
configuration.setAllowedMethods(Arrays.asList("GET", "OPTIONS"));
|
||||||
configuration.setAllowedHeaders(Arrays.asList("authorization", "content-type",
|
configuration.setAllowedHeaders(
|
||||||
"x-auth-token")); // Do not remove, this fixes the CORS errors when unauthenticated
|
Arrays.asList(
|
||||||
UrlBasedCorsConfigurationSource source = new
|
"authorization",
|
||||||
UrlBasedCorsConfigurationSource();
|
"content-type",
|
||||||
|
"x-auth-token")); // Do not remove, this fixes the CORS errors when
|
||||||
|
// unauthenticated
|
||||||
|
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
|
||||||
source.registerCorsConfiguration("/**", configuration);
|
source.registerCorsConfiguration("/**", configuration);
|
||||||
|
|
||||||
return source;
|
return source;
|
||||||
@ -34,17 +37,23 @@ public class WebSecurityCustomConfiguration {
|
|||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
|
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
|
||||||
http
|
http.authorizeHttpRequests(
|
||||||
.authorizeHttpRequests(authorize -> authorize
|
authorize ->
|
||||||
.requestMatchers("/random2").access(hasRole("REALM_MyINPulse-entrepreneur"))
|
authorize
|
||||||
.requestMatchers("/random").access(hasRole("REALM_MyINPulse-admin"))
|
.requestMatchers("/random2")
|
||||||
.requestMatchers("/random3").permitAll()
|
.access(hasRole("REALM_MyINPulse-entrepreneur"))
|
||||||
.anyRequest().authenticated()
|
.requestMatchers("/random")
|
||||||
)
|
.access(hasRole("REALM_MyINPulse-admin"))
|
||||||
.oauth2ResourceServer(oauth2 -> oauth2
|
.requestMatchers("/random3")
|
||||||
.jwt(jwt -> jwt.
|
.permitAll()
|
||||||
jwtAuthenticationConverter(new KeycloakJwtRolesConverter())));
|
.anyRequest()
|
||||||
|
.authenticated())
|
||||||
|
.oauth2ResourceServer(
|
||||||
|
oauth2 ->
|
||||||
|
oauth2.jwt(
|
||||||
|
jwt ->
|
||||||
|
jwt.jwtAuthenticationConverter(
|
||||||
|
new KeycloakJwtRolesConverter())));
|
||||||
return http.build();
|
return http.build();
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,40 +16,35 @@ import java.util.stream.Stream;
|
|||||||
|
|
||||||
import static java.util.stream.Collectors.toSet;
|
import static java.util.stream.Collectors.toSet;
|
||||||
|
|
||||||
|
|
||||||
public class KeycloakJwtRolesConverter implements Converter<Jwt, AbstractAuthenticationToken> {
|
public class KeycloakJwtRolesConverter implements Converter<Jwt, AbstractAuthenticationToken> {
|
||||||
/**
|
/** Prefix used for realm level roles. */
|
||||||
* Prefix used for realm level roles.
|
|
||||||
*/
|
|
||||||
public static final String PREFIX_REALM_ROLE = "ROLE_REALM_";
|
public static final String PREFIX_REALM_ROLE = "ROLE_REALM_";
|
||||||
/**
|
|
||||||
* Prefix used in combination with the resource (client) name for resource level roles.
|
/** Prefix used in combination with the resource (client) name for resource level roles. */
|
||||||
*/
|
|
||||||
public static final String PREFIX_RESOURCE_ROLE = "ROLE_";
|
public static final String PREFIX_RESOURCE_ROLE = "ROLE_";
|
||||||
|
|
||||||
/**
|
/** Name of the claim containing the realm level roles */
|
||||||
* Name of the claim containing the realm level roles
|
|
||||||
*/
|
|
||||||
private static final String CLAIM_REALM_ACCESS = "realm_access";
|
private static final String CLAIM_REALM_ACCESS = "realm_access";
|
||||||
/**
|
|
||||||
* Name of the claim containing the resources (clients) the user has access to.
|
/** Name of the claim containing the resources (clients) the user has access to. */
|
||||||
*/
|
|
||||||
private static final String CLAIM_RESOURCE_ACCESS = "resource_access";
|
private static final String CLAIM_RESOURCE_ACCESS = "resource_access";
|
||||||
/**
|
|
||||||
* Name of the claim containing roles. (Applicable to realm and resource level.)
|
/** Name of the claim containing roles. (Applicable to realm and resource level.) */
|
||||||
*/
|
|
||||||
private static final String CLAIM_ROLES = "roles";
|
private static final String CLAIM_ROLES = "roles";
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AbstractAuthenticationToken convert(Jwt source)
|
public AbstractAuthenticationToken convert(Jwt source) {
|
||||||
{
|
return new JwtAuthenticationToken(
|
||||||
return new JwtAuthenticationToken(source, Stream.concat(new JwtGrantedAuthoritiesConverter().convert(source)
|
source,
|
||||||
.stream(), TEMPORARNAME(source).stream())
|
Stream.concat(
|
||||||
.collect(toSet()));
|
new JwtGrantedAuthoritiesConverter().convert(source).stream(),
|
||||||
|
TEMPORARNAME(source).stream())
|
||||||
|
.collect(toSet()));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Extracts the realm and resource level roles from a JWT token distinguishing between them using prefixes.
|
* Extracts the realm and resource level roles from a JWT token distinguishing between them
|
||||||
|
* using prefixes.
|
||||||
*/
|
*/
|
||||||
public Collection<GrantedAuthority> TEMPORARNAME(Jwt jwt) {
|
public Collection<GrantedAuthority> TEMPORARNAME(Jwt jwt) {
|
||||||
// Collection that will hold the extracted roles
|
// Collection that will hold the extracted roles
|
||||||
@ -66,33 +61,43 @@ public class KeycloakJwtRolesConverter implements Converter<Jwt, AbstractAuthent
|
|||||||
// Check if any roles are present
|
// Check if any roles are present
|
||||||
if (roles != null && !roles.isEmpty()) {
|
if (roles != null && !roles.isEmpty()) {
|
||||||
// Iterate of the roles and add them to the granted authorities
|
// Iterate of the roles and add them to the granted authorities
|
||||||
Collection<GrantedAuthority> realmRoles = roles.stream()
|
Collection<GrantedAuthority> realmRoles =
|
||||||
// Prefix all realm roles with "ROLE_realm_"
|
roles.stream()
|
||||||
.map(role -> new SimpleGrantedAuthority(PREFIX_REALM_ROLE + role))
|
// Prefix all realm roles with "ROLE_realm_"
|
||||||
.collect(Collectors.toList());
|
.map(role -> new SimpleGrantedAuthority(PREFIX_REALM_ROLE + role))
|
||||||
|
.collect(Collectors.toList());
|
||||||
grantedAuthorities.addAll(realmRoles);
|
grantedAuthorities.addAll(realmRoles);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Resource (client) roles
|
// Resource (client) roles
|
||||||
// A user might have access to multiple resources all containing their own roles. Therefore, it is a map of
|
// A user might have access to multiple resources all containing their own roles. Therefore,
|
||||||
|
// it is a map of
|
||||||
// resource each possibly containing a "roles" property.
|
// resource each possibly containing a "roles" property.
|
||||||
Map<String, Map<String, Collection<String>>> resourceAccess = jwt.getClaim(CLAIM_RESOURCE_ACCESS);
|
Map<String, Map<String, Collection<String>>> resourceAccess =
|
||||||
|
jwt.getClaim(CLAIM_RESOURCE_ACCESS);
|
||||||
|
|
||||||
// Check if resources are assigned
|
// Check if resources are assigned
|
||||||
if (resourceAccess != null && !resourceAccess.isEmpty()) {
|
if (resourceAccess != null && !resourceAccess.isEmpty()) {
|
||||||
// Iterate of all the resources
|
// Iterate of all the resources
|
||||||
resourceAccess.forEach((resource, resourceClaims) -> {
|
resourceAccess.forEach(
|
||||||
// Iterate of the "roles" claim inside the resource claims
|
(resource, resourceClaims) -> {
|
||||||
resourceClaims.get(CLAIM_ROLES).forEach(
|
// Iterate of the "roles" claim inside the resource claims
|
||||||
// Add the role to the granted authority prefixed with ROLE_ and the name of the resource
|
resourceClaims
|
||||||
role -> grantedAuthorities.add(new SimpleGrantedAuthority(PREFIX_RESOURCE_ROLE + resource + "_" + role))
|
.get(CLAIM_ROLES)
|
||||||
);
|
.forEach(
|
||||||
});
|
// Add the role to the granted authority prefixed with ROLE_
|
||||||
|
// and the name of the resource
|
||||||
|
role ->
|
||||||
|
grantedAuthorities.add(
|
||||||
|
new SimpleGrantedAuthority(
|
||||||
|
PREFIX_RESOURCE_ROLE
|
||||||
|
+ resource
|
||||||
|
+ "_"
|
||||||
|
+ role)));
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return grantedAuthorities;
|
return grantedAuthorities;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -6,8 +6,6 @@ import org.springframework.boot.test.context.SpringBootTest;
|
|||||||
@SpringBootTest
|
@SpringBootTest
|
||||||
class MyinpulseApplicationTests {
|
class MyinpulseApplicationTests {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void contextLoads() {
|
void contextLoads() {}
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,15 +1,14 @@
|
|||||||
services:
|
services:
|
||||||
postgres:
|
postgres:
|
||||||
image: postgres:latest
|
env_file: .env
|
||||||
|
build:
|
||||||
|
context: postgres/
|
||||||
|
dockerfile: Dockerfile
|
||||||
container_name: MyINPulse-DB
|
container_name: MyINPulse-DB
|
||||||
ports:
|
ports:
|
||||||
- 5432:5432
|
- 5433:5432
|
||||||
volumes:
|
volumes:
|
||||||
- ./postgres:/var/lib/postgresql/data
|
- ./postgres/data:/var/lib/postgresql/data
|
||||||
environment:
|
|
||||||
POSTGRES_DB: ${POSTGRES_DB}
|
|
||||||
POSTGRES_USER: ${POSTGRES_USER}
|
|
||||||
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
|
|
||||||
|
|
||||||
keycloak:
|
keycloak:
|
||||||
container_name: MyINPulse-keycloak
|
container_name: MyINPulse-keycloak
|
||||||
|
@ -1,10 +1,14 @@
|
|||||||
POSTGRES_DB=keycloak_db
|
POSTGRES_DB=postgres_db
|
||||||
POSTGRES_USER=keycloak_db_user
|
POSTGRES_USER=postgres
|
||||||
POSTGRES_PASSWORD=keycloak_db_user_password
|
POSTGRES_PASSWORD=postgres_db_user_password
|
||||||
|
|
||||||
KEYCLOAK_ADMIN=admin
|
KEYCLOAK_ADMIN=admin
|
||||||
KEYCLOAK_ADMIN_PASSWORD=admin
|
KEYCLOAK_ADMIN_PASSWORD=admin
|
||||||
KEYCLOAK_HOSTNAME=localhost
|
KEYCLOAK_HOSTNAME=localhost
|
||||||
|
KEYCLOAK_DB=keycloak_db
|
||||||
|
KEYCLOAK_USER=keycloak_db_user
|
||||||
|
KEYCLOAK_PASSWORD=keycloak_db_user_password
|
||||||
|
|
||||||
MYINPULSE_DB=MyINPulse_db
|
BACKEND_DB=backend_db
|
||||||
MYINPULSE_DB_USER=MyINPulse_db_user
|
BACKEND_USER=backend_db_user
|
||||||
MYINPULSE_DB_PASS=MyINPulse_db_user_pass
|
BACKEND_PASSWORD=backend_db_user_password
|
@ -1,15 +1,15 @@
|
|||||||
services:
|
services:
|
||||||
postgres:
|
postgres:
|
||||||
image: postgres:latest
|
env_file: .env
|
||||||
|
build:
|
||||||
|
context: postgres/
|
||||||
|
dockerfile: Dockerfile
|
||||||
container_name: MyINPulse-DB
|
container_name: MyINPulse-DB
|
||||||
#ports:
|
#ports:
|
||||||
# - 5432:5432
|
# - 5432:5432
|
||||||
volumes:
|
volumes:
|
||||||
- ./postgres:/var/lib/postgresql/data
|
- ./postgres/data:/var/lib/postgresql/data
|
||||||
environment:
|
|
||||||
POSTGRES_DB: ${POSTGRES_DB}
|
|
||||||
POSTGRES_USER: ${POSTGRES_USER}
|
|
||||||
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
|
|
||||||
|
|
||||||
keycloak:
|
keycloak:
|
||||||
container_name: MyINPulse-keycloak
|
container_name: MyINPulse-keycloak
|
||||||
|
@ -1,6 +1,14 @@
|
|||||||
POSTGRES_DB=keycloak_db
|
POSTGRES_DB=postgres_db
|
||||||
POSTGRES_USER=keycloak_db_user
|
POSTGRES_USER=postgres
|
||||||
POSTGRES_PASSWORD=keycloak_db_user_password
|
POSTGRES_PASSWORD=postgres_db_user_password
|
||||||
|
|
||||||
KEYCLOAK_ADMIN=admin
|
KEYCLOAK_ADMIN=admin
|
||||||
KEYCLOAK_ADMIN_PASSWORD=admin
|
KEYCLOAK_ADMIN_PASSWORD=admin
|
||||||
KEYCLOAK_HOSTNAME=localhost
|
KEYCLOAK_HOSTNAME=localhost
|
||||||
|
KEYCLOAK_DB=keycloak_db
|
||||||
|
KEYCLOAK_USER=keycloak_db_user
|
||||||
|
KEYCLOAK_PASSWORD=keycloak_db_user_password
|
||||||
|
|
||||||
|
BACKEND_DB=backend_db
|
||||||
|
BACKEND_USER=backend_db_user
|
||||||
|
BACKEND_PASSWORD=backend_db_user_password
|
||||||
|
@ -1,11 +1,14 @@
|
|||||||
services:
|
services:
|
||||||
postgres:
|
postgres:
|
||||||
image: postgres:latest
|
env_file: .env
|
||||||
|
build:
|
||||||
|
context: postgres/
|
||||||
|
dockerfile: Dockerfile
|
||||||
container_name: MyINPulse-DB
|
container_name: MyINPulse-DB
|
||||||
#ports:
|
#ports:
|
||||||
# - 5432:5432
|
# - 5432:5432
|
||||||
volumes:
|
volumes:
|
||||||
- ./postgres:/var/lib/postgresql/data
|
- ./postgres/data:/var/lib/postgresql/data
|
||||||
environment:
|
environment:
|
||||||
POSTGRES_DB: ${POSTGRES_DB}
|
POSTGRES_DB: ${POSTGRES_DB}
|
||||||
POSTGRES_USER: ${POSTGRES_USER}
|
POSTGRES_USER: ${POSTGRES_USER}
|
||||||
|
@ -1,6 +1,14 @@
|
|||||||
POSTGRES_DB=keycloak_db
|
POSTGRES_DB=postgres_db
|
||||||
POSTGRES_USER=keycloak_db_user
|
POSTGRES_USER=postgres
|
||||||
POSTGRES_PASSWORD=keycloak_db_user_password
|
POSTGRES_PASSWORD=postgres_db_user_password
|
||||||
|
|
||||||
KEYCLOAK_ADMIN=admin
|
KEYCLOAK_ADMIN=admin
|
||||||
KEYCLOAK_ADMIN_PASSWORD=admin
|
KEYCLOAK_ADMIN_PASSWORD=admin
|
||||||
KEYCLOAK_HOSTNAME=0549cd63f912d5dc9b31278d6f.eirb.fr
|
KEYCLOAK_HOSTNAME=0549cd63f912d5dc9b31278d6f.eirb.fr
|
||||||
|
KEYCLOAK_DB=keycloak_db
|
||||||
|
KEYCLOAK_USER=keycloak_db_user
|
||||||
|
KEYCLOAK_PASSWORD=keycloak_db_user_password
|
||||||
|
|
||||||
|
BACKEND_DB=backend_db
|
||||||
|
BACKEND_USER=backend_db_user
|
||||||
|
BACKEND_PASSWORD=backend_db_user_password
|
||||||
|
5
postgres/Dockerfile
Normal file
5
postgres/Dockerfile
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
FROM postgres:latest
|
||||||
|
|
||||||
|
# Custom initialization scripts
|
||||||
|
COPY ./create_user.sh /docker-entrypoint-initdb.d/10-create_user.sh
|
||||||
|
COPY ./create_db.sh /docker-entrypoint-initdb.d/20-create_db.sh
|
17
postgres/create_db.sh
Normal file
17
postgres/create_db.sh
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
POSTGRES="psql --username ${POSTGRES_USER}"
|
||||||
|
|
||||||
|
echo "Creating database: ${DB_NAME}"
|
||||||
|
|
||||||
|
$POSTGRES <<EOSQL
|
||||||
|
CREATE DATABASE ${BACKEND_DB} OWNER ${BACKEND_USER};
|
||||||
|
EOSQL
|
||||||
|
|
||||||
|
|
||||||
|
echo "Creating database: ${DB_NAME}"
|
||||||
|
|
||||||
|
$POSTGRES <<EOSQL
|
||||||
|
CREATE DATABASE ${KEYCLOAK_DB} OWNER ${KEYCLOAK_USER};
|
||||||
|
EOSQL
|
16
postgres/create_user.sh
Normal file
16
postgres/create_user.sh
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
POSTGRES="psql --username ${POSTGRES_USER}"
|
||||||
|
|
||||||
|
echo "Creating database role: [${BACKEND_USER}]"
|
||||||
|
|
||||||
|
$POSTGRES <<-EOSQL
|
||||||
|
CREATE USER ${BACKEND_USER} WITH CREATEDB PASSWORD '${BACKEND_PASSWORD}';
|
||||||
|
EOSQL
|
||||||
|
|
||||||
|
|
||||||
|
echo "Creating database role: ${KEYCLOAK_USER}"
|
||||||
|
$POSTGRES <<-EOSQL
|
||||||
|
CREATE USER ${KEYCLOAK_USER} WITH CREATEDB PASSWORD '${KEYCLOAK_PASSWORD}';
|
||||||
|
EOSQL
|
Loading…
x
Reference in New Issue
Block a user