From 301a9965f5a20f718e82c8b24732d1468c4f45c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20=C3=81lvarez=20=C3=81lvarez?= Date: Wed, 18 Sep 2024 10:05:34 +0200 Subject: [PATCH] Remove spring-jdbc from the security tests --- .../spring-security-5/build.gradle | 3 -- .../spring-security-5/gradle.lockfile | 8 ----- .../springsecurity5/SecurityConfig.groovy | 26 +++++++--------- .../SpringBootBasedTest.groovy | 9 +----- .../src/test/resources/schema.sql | 30 ------------------- .../spring-security-6/build.gradle | 3 -- .../spring-security-6/gradle.lockfile | 9 ------ .../springsecurity6/SecurityConfig.groovy | 26 +++++++--------- .../SpringBootBasedTest.groovy | 9 +----- .../src/test/resources/schema.sql | 30 ------------------- 10 files changed, 24 insertions(+), 129 deletions(-) delete mode 100644 dd-java-agent/instrumentation/spring-security-5/src/test/resources/schema.sql delete mode 100644 dd-java-agent/instrumentation/spring-security-6/src/test/resources/schema.sql diff --git a/dd-java-agent/instrumentation/spring-security-5/build.gradle b/dd-java-agent/instrumentation/spring-security-5/build.gradle index c6530f36366..51bc36007cf 100644 --- a/dd-java-agent/instrumentation/spring-security-5/build.gradle +++ b/dd-java-agent/instrumentation/spring-security-5/build.gradle @@ -19,14 +19,11 @@ dependencies { testImplementation group: 'org.springframework.boot', name: 'spring-boot-starter-test', version: springBootVersion testImplementation group: 'org.springframework.boot', name: 'spring-boot-starter-web', version: springBootVersion testImplementation group: 'org.springframework.boot', name: 'spring-boot-starter-security', version: springBootVersion - testImplementation group: 'org.springframework.boot', name: 'spring-boot-starter-jdbc', version: springBootVersion latestDepTestImplementation group: 'org.springframework.boot', name: 'spring-boot-starter-test', version: '2.+' latestDepTestImplementation group: 'org.springframework.boot', name: 'spring-boot-starter-web', version: '2.+' latestDepTestImplementation group: 'org.springframework.boot', name: 'spring-boot-starter-security', version: '2.+' - latestDepTestImplementation group: 'org.springframework.boot', name: 'spring-boot-starter-jdbc', version: '2.+' testRuntimeOnly project(':dd-java-agent:instrumentation:tomcat-appsec-6') testRuntimeOnly project(':dd-java-agent:instrumentation:tomcat-5.5') - testRuntimeOnly 'com.h2database:h2:2.1.212' } diff --git a/dd-java-agent/instrumentation/spring-security-5/gradle.lockfile b/dd-java-agent/instrumentation/spring-security-5/gradle.lockfile index cf2d77b65cd..c4422c4872b 100644 --- a/dd-java-agent/instrumentation/spring-security-5/gradle.lockfile +++ b/dd-java-agent/instrumentation/spring-security-5/gradle.lockfile @@ -52,7 +52,6 @@ com.google.guava:guava:27.0.1-jre=annotationProcessor,latestDepTestAnnotationPro com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava=annotationProcessor,latestDepTestAnnotationProcessor,testAnnotationProcessor com.google.j2objc:j2objc-annotations:1.1=annotationProcessor,latestDepTestAnnotationProcessor,testAnnotationProcessor com.google.re2j:re2j:1.7=instrumentPluginClasspath,latestDepTestRuntimeClasspath,muzzleTooling,runtimeClasspath,testRuntimeClasspath -com.h2database:h2:2.1.212=latestDepTestRuntimeClasspath,testRuntimeClasspath com.jayway.jsonpath:json-path:2.6.0=testCompileClasspath,testRuntimeClasspath com.jayway.jsonpath:json-path:2.7.0=latestDepTestCompileClasspath,latestDepTestRuntimeClasspath com.squareup.moshi:moshi:1.11.0=compileClasspath,instrumentPluginClasspath,latestDepTestCompileClasspath,latestDepTestRuntimeClasspath,muzzleTooling,runtimeClasspath,testCompileClasspath,testRuntimeClasspath @@ -61,7 +60,6 @@ com.squareup.okhttp3:okhttp:3.12.12=latestDepTestCompileClasspath,latestDepTestR com.squareup.okio:okio:1.17.5=compileClasspath,instrumentPluginClasspath,latestDepTestCompileClasspath,latestDepTestRuntimeClasspath,muzzleTooling,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.thoughtworks.qdox:qdox:1.12.1=latestDepTestRuntimeClasspath,testRuntimeClasspath com.vaadin.external.google:android-json:0.0.20131108.vaadin1=latestDepTestCompileClasspath,latestDepTestRuntimeClasspath,testCompileClasspath,testRuntimeClasspath -com.zaxxer:HikariCP:4.0.3=latestDepTestCompileClasspath,latestDepTestRuntimeClasspath,testCompileClasspath,testRuntimeClasspath commons-codec:commons-codec:1.15=spotbugs commons-fileupload:commons-fileupload:1.5=latestDepTestCompileClasspath,latestDepTestRuntimeClasspath,testCompileClasspath,testRuntimeClasspath commons-io:commons-io:2.11.0=latestDepTestCompileClasspath,latestDepTestRuntimeClasspath,testCompileClasspath,testRuntimeClasspath @@ -195,8 +193,6 @@ org.spockframework:spock-core:2.2-groovy-3.0=latestDepTestCompileClasspath,lates org.spockframework:spock-junit4:2.2-groovy-3.0=latestDepTestCompileClasspath,latestDepTestRuntimeClasspath,testCompileClasspath,testRuntimeClasspath org.springframework.boot:spring-boot-autoconfigure:2.6.0=testCompileClasspath,testRuntimeClasspath org.springframework.boot:spring-boot-autoconfigure:2.7.18=latestDepTestCompileClasspath,latestDepTestRuntimeClasspath -org.springframework.boot:spring-boot-starter-jdbc:2.6.0=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-jdbc:2.7.18=latestDepTestCompileClasspath,latestDepTestRuntimeClasspath org.springframework.boot:spring-boot-starter-json:2.6.0=testCompileClasspath,testRuntimeClasspath org.springframework.boot:spring-boot-starter-json:2.7.18=latestDepTestCompileClasspath,latestDepTestRuntimeClasspath org.springframework.boot:spring-boot-starter-logging:2.6.0=testCompileClasspath,testRuntimeClasspath @@ -245,12 +241,8 @@ org.springframework:spring-expression:5.3.31=latestDepTestCompileClasspath,lates org.springframework:spring-jcl:5.3.13=testCompileClasspath,testRuntimeClasspath org.springframework:spring-jcl:5.3.25=compileClasspath org.springframework:spring-jcl:5.3.31=latestDepTestCompileClasspath,latestDepTestRuntimeClasspath -org.springframework:spring-jdbc:5.3.13=testCompileClasspath,testRuntimeClasspath -org.springframework:spring-jdbc:5.3.31=latestDepTestCompileClasspath,latestDepTestRuntimeClasspath org.springframework:spring-test:5.3.13=testCompileClasspath,testRuntimeClasspath org.springframework:spring-test:5.3.31=latestDepTestCompileClasspath,latestDepTestRuntimeClasspath -org.springframework:spring-tx:5.3.13=testCompileClasspath,testRuntimeClasspath -org.springframework:spring-tx:5.3.31=latestDepTestCompileClasspath,latestDepTestRuntimeClasspath org.springframework:spring-web:5.3.13=testCompileClasspath,testRuntimeClasspath org.springframework:spring-web:5.3.31=latestDepTestCompileClasspath,latestDepTestRuntimeClasspath org.springframework:spring-webmvc:5.3.13=testCompileClasspath,testRuntimeClasspath diff --git a/dd-java-agent/instrumentation/spring-security-5/src/test/groovy/datadog/trace/instrumentation/springsecurity5/SecurityConfig.groovy b/dd-java-agent/instrumentation/spring-security-5/src/test/groovy/datadog/trace/instrumentation/springsecurity5/SecurityConfig.groovy index af047f072df..d5ce025ad32 100644 --- a/dd-java-agent/instrumentation/spring-security-5/src/test/groovy/datadog/trace/instrumentation/springsecurity5/SecurityConfig.groovy +++ b/dd-java-agent/instrumentation/spring-security-5/src/test/groovy/datadog/trace/instrumentation/springsecurity5/SecurityConfig.groovy @@ -2,20 +2,18 @@ package datadog.trace.instrumentation.springsecurity5 import custom.CustomAuthenticationFilter import custom.CustomAuthenticationProvider -import org.springframework.boot.jdbc.DataSourceBuilder import org.springframework.context.annotation.Bean import org.springframework.context.annotation.Configuration import org.springframework.security.authentication.AuthenticationManager import org.springframework.security.config.annotation.web.builders.HttpSecurity import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer -import org.springframework.security.provisioning.JdbcUserDetailsManager +import org.springframework.security.core.userdetails.UserDetails +import org.springframework.security.provisioning.InMemoryUserDetailsManager import org.springframework.security.provisioning.UserDetailsManager import org.springframework.security.web.SecurityFilterChain import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter -import javax.sql.DataSource - import static datadog.trace.instrumentation.springsecurity5.SecurityConfig.CustomDsl.customDsl @Configuration @@ -34,19 +32,17 @@ class SecurityConfig { return http.build() } - @Bean - DataSource getDataSource() { - DataSourceBuilder dataSourceBuilder = DataSourceBuilder.create() - dataSourceBuilder.driverClassName("org.h2.Driver") - dataSourceBuilder.url("jdbc:h2:mem:authDB;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE;INIT=RUNSCRIPT FROM 'classpath:schema.sql';") - dataSourceBuilder.username("SA") - dataSourceBuilder.password("") - return dataSourceBuilder.build() - } - @Bean UserDetailsManager userDetailsService() { - return new JdbcUserDetailsManager(dataSource) + return new InMemoryUserDetailsManager() { + @Override + void createUser(UserDetails user) { + if (user.username == 'cant_create_me') { + throw new IllegalArgumentException('cannot create user') + } + super.createUser(user) + } + } } static class CustomDsl extends AbstractHttpConfigurer { diff --git a/dd-java-agent/instrumentation/spring-security-5/src/test/groovy/datadog/trace/instrumentation/springsecurity5/SpringBootBasedTest.groovy b/dd-java-agent/instrumentation/spring-security-5/src/test/groovy/datadog/trace/instrumentation/springsecurity5/SpringBootBasedTest.groovy index 0be4094e117..96f9c21836c 100644 --- a/dd-java-agent/instrumentation/spring-security-5/src/test/groovy/datadog/trace/instrumentation/springsecurity5/SpringBootBasedTest.groovy +++ b/dd-java-agent/instrumentation/spring-security-5/src/test/groovy/datadog/trace/instrumentation/springsecurity5/SpringBootBasedTest.groovy @@ -216,7 +216,7 @@ class SpringBootBasedTest extends AppSecHttpServerTest - (1..length).collect { Character.valueOf((char) (random.nextInt(26) + (char)'a')) } - }.join() - } } diff --git a/dd-java-agent/instrumentation/spring-security-5/src/test/resources/schema.sql b/dd-java-agent/instrumentation/spring-security-5/src/test/resources/schema.sql deleted file mode 100644 index f7a9a7728ca..00000000000 --- a/dd-java-agent/instrumentation/spring-security-5/src/test/resources/schema.sql +++ /dev/null @@ -1,30 +0,0 @@ -create table IF NOT EXISTS users( - username varchar_ignorecase(50) not null primary key, - password varchar_ignorecase(500) not null, - enabled boolean not null -); - -create table IF NOT EXISTS authorities ( - username varchar_ignorecase(50) not null, - authority varchar_ignorecase(50) not null, - constraint fk_authorities_users foreign key(username) references users(username) -); -create unique index IF NOT EXISTS ix_auth_username on authorities (username,authority); - -create table IF NOT EXISTS groups ( - id bigint generated by default as identity(start with 0) primary key, - group_name varchar_ignorecase(50) not null -); - -create table IF NOT EXISTS group_authorities ( - group_id bigint not null, - authority varchar(50) not null, - constraint fk_group_authorities_group foreign key(group_id) references groups(id) -); - -create table IF NOT EXISTS group_members ( - id bigint generated by default as identity(start with 0) primary key, - username varchar(50) not null, - group_id bigint not null, - constraint fk_group_members_group foreign key(group_id) references groups(id) -); \ No newline at end of file diff --git a/dd-java-agent/instrumentation/spring-security-6/build.gradle b/dd-java-agent/instrumentation/spring-security-6/build.gradle index 6a3998850d6..e746ed3f9c5 100644 --- a/dd-java-agent/instrumentation/spring-security-6/build.gradle +++ b/dd-java-agent/instrumentation/spring-security-6/build.gradle @@ -22,14 +22,11 @@ dependencies { testImplementation group: 'org.springframework.boot', name: 'spring-boot-starter-test', version: springBootVersion testImplementation group: 'org.springframework.boot', name: 'spring-boot-starter-web', version: springBootVersion testImplementation group: 'org.springframework.boot', name: 'spring-boot-starter-security', version: springBootVersion - testImplementation group: 'org.springframework.boot', name: 'spring-boot-starter-jdbc', version: springBootVersion latestDepTestImplementation group: 'org.springframework.boot', name: 'spring-boot-starter-test', version: '+' latestDepTestImplementation group: 'org.springframework.boot', name: 'spring-boot-starter-web', version: '+' latestDepTestImplementation group: 'org.springframework.boot', name: 'spring-boot-starter-security', version: '+' - latestDepTestImplementation group: 'org.springframework.boot', name: 'spring-boot-starter-jdbc', version: '+' testRuntimeOnly project(':dd-java-agent:instrumentation:tomcat-appsec-6') testRuntimeOnly project(':dd-java-agent:instrumentation:tomcat-5.5') - testRuntimeOnly 'com.h2database:h2:2.1.212' } diff --git a/dd-java-agent/instrumentation/spring-security-6/gradle.lockfile b/dd-java-agent/instrumentation/spring-security-6/gradle.lockfile index 7ecc4a50a89..0f542362a9c 100644 --- a/dd-java-agent/instrumentation/spring-security-6/gradle.lockfile +++ b/dd-java-agent/instrumentation/spring-security-6/gradle.lockfile @@ -53,7 +53,6 @@ com.google.guava:guava:27.0.1-jre=annotationProcessor,latestDepTestAnnotationPro com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava=annotationProcessor,latestDepTestAnnotationProcessor,testAnnotationProcessor com.google.j2objc:j2objc-annotations:1.1=annotationProcessor,latestDepTestAnnotationProcessor,testAnnotationProcessor com.google.re2j:re2j:1.7=instrumentPluginClasspath,latestDepTestRuntimeClasspath,main_java17RuntimeClasspath,muzzleTooling,runtimeClasspath,testRuntimeClasspath -com.h2database:h2:2.1.212=latestDepTestRuntimeClasspath,testRuntimeClasspath com.jayway.jsonpath:json-path:2.7.0=testCompileClasspath,testRuntimeClasspath com.jayway.jsonpath:json-path:2.9.0=latestDepTestCompileClasspath,latestDepTestRuntimeClasspath com.squareup.moshi:moshi:1.11.0=compileClasspath,instrumentPluginClasspath,latestDepTestCompileClasspath,latestDepTestRuntimeClasspath,main_java17CompileClasspath,main_java17RuntimeClasspath,muzzleTooling,runtimeClasspath,testCompileClasspath,testRuntimeClasspath @@ -62,8 +61,6 @@ com.squareup.okhttp3:okhttp:3.12.12=latestDepTestCompileClasspath,latestDepTestR com.squareup.okio:okio:1.17.5=compileClasspath,instrumentPluginClasspath,latestDepTestCompileClasspath,latestDepTestRuntimeClasspath,main_java17CompileClasspath,main_java17RuntimeClasspath,muzzleTooling,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.thoughtworks.qdox:qdox:1.12.1=latestDepTestRuntimeClasspath,testRuntimeClasspath com.vaadin.external.google:android-json:0.0.20131108.vaadin1=latestDepTestCompileClasspath,latestDepTestRuntimeClasspath,testCompileClasspath,testRuntimeClasspath -com.zaxxer:HikariCP:5.0.1=testCompileClasspath,testRuntimeClasspath -com.zaxxer:HikariCP:5.1.0=latestDepTestCompileClasspath,latestDepTestRuntimeClasspath commons-codec:commons-codec:1.15=spotbugs commons-fileupload:commons-fileupload:1.5=latestDepTestCompileClasspath,latestDepTestRuntimeClasspath,testCompileClasspath,testRuntimeClasspath commons-io:commons-io:2.11.0=latestDepTestCompileClasspath,latestDepTestRuntimeClasspath,testCompileClasspath,testRuntimeClasspath @@ -218,8 +215,6 @@ org.spockframework:spock-core:2.2-groovy-3.0=latestDepTestCompileClasspath,lates org.spockframework:spock-junit4:2.2-groovy-3.0=latestDepTestCompileClasspath,latestDepTestRuntimeClasspath,testCompileClasspath,testRuntimeClasspath org.springframework.boot:spring-boot-autoconfigure:3.0.0=testCompileClasspath,testRuntimeClasspath org.springframework.boot:spring-boot-autoconfigure:3.3.3=latestDepTestCompileClasspath,latestDepTestRuntimeClasspath -org.springframework.boot:spring-boot-starter-jdbc:3.0.0=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-jdbc:3.3.3=latestDepTestCompileClasspath,latestDepTestRuntimeClasspath org.springframework.boot:spring-boot-starter-json:3.0.0=testCompileClasspath,testRuntimeClasspath org.springframework.boot:spring-boot-starter-json:3.3.3=latestDepTestCompileClasspath,latestDepTestRuntimeClasspath org.springframework.boot:spring-boot-starter-logging:3.0.0=testCompileClasspath,testRuntimeClasspath @@ -260,12 +255,8 @@ org.springframework:spring-expression:6.0.2=testCompileClasspath,testRuntimeClas org.springframework:spring-expression:6.1.12=latestDepTestCompileClasspath,latestDepTestRuntimeClasspath org.springframework:spring-jcl:6.0.2=testCompileClasspath,testRuntimeClasspath org.springframework:spring-jcl:6.1.12=latestDepTestCompileClasspath,latestDepTestRuntimeClasspath -org.springframework:spring-jdbc:6.0.2=testCompileClasspath,testRuntimeClasspath -org.springframework:spring-jdbc:6.1.12=latestDepTestCompileClasspath,latestDepTestRuntimeClasspath org.springframework:spring-test:6.0.2=testCompileClasspath,testRuntimeClasspath org.springframework:spring-test:6.1.12=latestDepTestCompileClasspath,latestDepTestRuntimeClasspath -org.springframework:spring-tx:6.0.2=testCompileClasspath,testRuntimeClasspath -org.springframework:spring-tx:6.1.12=latestDepTestCompileClasspath,latestDepTestRuntimeClasspath org.springframework:spring-web:6.0.2=testCompileClasspath,testRuntimeClasspath org.springframework:spring-web:6.1.12=latestDepTestCompileClasspath,latestDepTestRuntimeClasspath org.springframework:spring-webmvc:6.0.2=testCompileClasspath,testRuntimeClasspath diff --git a/dd-java-agent/instrumentation/spring-security-6/src/test/groovy/datadog/trace/instrumentation/springsecurity6/SecurityConfig.groovy b/dd-java-agent/instrumentation/spring-security-6/src/test/groovy/datadog/trace/instrumentation/springsecurity6/SecurityConfig.groovy index 03fc67ca040..623698699b7 100644 --- a/dd-java-agent/instrumentation/spring-security-6/src/test/groovy/datadog/trace/instrumentation/springsecurity6/SecurityConfig.groovy +++ b/dd-java-agent/instrumentation/spring-security-6/src/test/groovy/datadog/trace/instrumentation/springsecurity6/SecurityConfig.groovy @@ -2,20 +2,18 @@ package datadog.trace.instrumentation.springsecurity6 import custom.CustomAuthenticationFilter import custom.CustomAuthenticationProvider -import org.springframework.boot.jdbc.DataSourceBuilder import org.springframework.context.annotation.Bean import org.springframework.context.annotation.Configuration import org.springframework.security.authentication.AuthenticationManager import org.springframework.security.config.annotation.web.builders.HttpSecurity import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer -import org.springframework.security.provisioning.JdbcUserDetailsManager +import org.springframework.security.core.userdetails.UserDetails +import org.springframework.security.provisioning.InMemoryUserDetailsManager import org.springframework.security.provisioning.UserDetailsManager import org.springframework.security.web.SecurityFilterChain import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter -import javax.sql.DataSource - @Configuration @EnableWebSecurity class SecurityConfig { @@ -32,19 +30,17 @@ class SecurityConfig { return http.build() } - @Bean - DataSource getDataSource() { - DataSourceBuilder dataSourceBuilder = DataSourceBuilder.create() - dataSourceBuilder.driverClassName("org.h2.Driver") - dataSourceBuilder.url("jdbc:h2:mem:authDB;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE;INIT=RUNSCRIPT FROM 'classpath:schema.sql';") - dataSourceBuilder.username("SA") - dataSourceBuilder.password("") - return dataSourceBuilder.build() - } - @Bean UserDetailsManager userDetailsService() { - return new JdbcUserDetailsManager(dataSource) + return new InMemoryUserDetailsManager() { + @Override + void createUser(UserDetails user) { + if (user.username == 'cant_create_me') { + throw new IllegalArgumentException('cannot create user') + } + super.createUser(user) + } + } } static class CustomDsl extends AbstractHttpConfigurer { diff --git a/dd-java-agent/instrumentation/spring-security-6/src/test/groovy/datadog/trace/instrumentation/springsecurity6/SpringBootBasedTest.groovy b/dd-java-agent/instrumentation/spring-security-6/src/test/groovy/datadog/trace/instrumentation/springsecurity6/SpringBootBasedTest.groovy index 7470c6fe747..0dca21ff574 100644 --- a/dd-java-agent/instrumentation/spring-security-6/src/test/groovy/datadog/trace/instrumentation/springsecurity6/SpringBootBasedTest.groovy +++ b/dd-java-agent/instrumentation/spring-security-6/src/test/groovy/datadog/trace/instrumentation/springsecurity6/SpringBootBasedTest.groovy @@ -216,7 +216,7 @@ class SpringBootBasedTest extends AppSecHttpServerTest - (1..length).collect { Character.valueOf((char) (random.nextInt(26) + (char)'a')) } - }.join() - } } diff --git a/dd-java-agent/instrumentation/spring-security-6/src/test/resources/schema.sql b/dd-java-agent/instrumentation/spring-security-6/src/test/resources/schema.sql deleted file mode 100644 index 33c0bebd937..00000000000 --- a/dd-java-agent/instrumentation/spring-security-6/src/test/resources/schema.sql +++ /dev/null @@ -1,30 +0,0 @@ -create table IF NOT EXISTS users( - username varchar_ignorecase(50) not null primary key, - password varchar_ignorecase(500) not null, - enabled boolean not null - ); - -create table IF NOT EXISTS authorities ( - username varchar_ignorecase(50) not null, - authority varchar_ignorecase(50) not null, - constraint fk_authorities_users foreign key(username) references users(username) - ); -create unique index IF NOT EXISTS ix_auth_username on authorities (username,authority); - -create table IF NOT EXISTS groups ( - id bigint generated by default as identity(start with 0) primary key, - group_name varchar_ignorecase(50) not null - ); - -create table IF NOT EXISTS group_authorities ( - group_id bigint not null, - authority varchar(50) not null, - constraint fk_group_authorities_group foreign key(group_id) references groups(id) - ); - -create table IF NOT EXISTS group_members ( - id bigint generated by default as identity(start with 0) primary key, - username varchar(50) not null, - group_id bigint not null, - constraint fk_group_members_group foreign key(group_id) references groups(id) - );