diff --git a/.github/workflows/create_cert.yml b/.github/workflows/create_cert.yml index 1f5d6fd0a..d0313c13b 100644 --- a/.github/workflows/create_cert.yml +++ b/.github/workflows/create_cert.yml @@ -10,6 +10,7 @@ jobs: run: | echo "$S3_KEY"|base64 -d > aws-key.properties echo "$FIREBASE_CONFIG"|base64 -d > firebase_config.json + echo "FIREBASE_TEST_CONFIG"|base64 -d > firebase_test_config.json mv docker-compose-run.yml docker-compose.yml sed -i -e "s/_YANDEX_AUTH_TOKEN_/\\$YANDEX_AUTH_TOKEN/" docker-compose.yml sed -i -e "s/_YANDEX_FOLDER_ID_/\\$YANDEX_FOLDER_ID/" docker-compose.yml @@ -18,6 +19,7 @@ jobs: env: S3_KEY: ${{ secrets.S3_KEY }} FIREBASE_CONFIG: ${{ secrets.FIREBASE_CONFIG }} + FIREBASE_TEST_CONFIG: ${{ secrets.FIREBASE_TEST_CONFIG }} YANDEX_AUTH_TOKEN: ${{ secrets.YANDEX_AUTH_TOKEN }} YANDEX_FOLDER_ID: ${{ secrets.YANDEX_FOLDER_ID }} POSTGRES_PASSWORD: ${{ secrets.POSTGRES_PASSWORD }} diff --git a/.github/workflows/java-ci.yml b/.github/workflows/java-ci.yml index 424e8c8b2..54d810c6c 100644 --- a/.github/workflows/java-ci.yml +++ b/.github/workflows/java-ci.yml @@ -16,10 +16,14 @@ jobs: with: java-version: 17 - name: Build, Unit and Integration Tests - run: ./gradlew build test integrationTest jacocoTestReport sonarqube + run: | + echo "$FIREBASE_TEST_CONFIG"|base64 -d > firebase_config.json + export FIREBASE_TEST_CONFIG_PATH=./firebase_config.json + ./gradlew build test integrationTest jacocoTestReport sonarqube env: SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + FIREBASE_TEST_CONFIG: ${{ secrets.FIREBASE_TEST_CONFIG }} - name: Publish Test Results uses: EnricoMi/publish-unit-test-result-action@v1 if: always() diff --git a/src/main/kotlin/com/epam/brn/config/FirebaseConfig.kt b/src/main/kotlin/com/epam/brn/config/FirebaseConfig.kt index 4bbf4764f..2e1b25a4f 100644 --- a/src/main/kotlin/com/epam/brn/config/FirebaseConfig.kt +++ b/src/main/kotlin/com/epam/brn/config/FirebaseConfig.kt @@ -8,9 +8,11 @@ import com.google.firebase.messaging.FirebaseMessaging import org.springframework.beans.factory.annotation.Value import org.springframework.context.annotation.Bean import org.springframework.context.annotation.Configuration +import org.springframework.context.annotation.Profile import java.io.FileInputStream @Configuration +@Profile("!integration-tests") class FirebaseConfig { @Value("\${firebase.credentials.path}") val firebaseCredentialsPath: String = "" diff --git a/src/test/kotlin/com/epam/brn/integration/AuthorizationAuthenticationIT.kt b/src/test/kotlin/com/epam/brn/integration/AuthorizationAuthenticationIT.kt index 4c9c94fbb..f1ed54f0e 100644 --- a/src/test/kotlin/com/epam/brn/integration/AuthorizationAuthenticationIT.kt +++ b/src/test/kotlin/com/epam/brn/integration/AuthorizationAuthenticationIT.kt @@ -4,6 +4,7 @@ import com.epam.brn.dto.request.UserAccountCreateRequest import com.epam.brn.enums.BrnGender import com.epam.brn.enums.BrnRole import com.epam.brn.integration.firebase.FirebaseWebClientTestMock +import com.epam.brn.integration.firebase.model.FirebaseVerifyPasswordRequest import com.epam.brn.model.Role import com.epam.brn.model.UserAccount import com.epam.brn.repo.RoleRepository @@ -12,7 +13,12 @@ import com.google.firebase.auth.FirebaseAuth import com.google.firebase.auth.UserRecord import org.junit.jupiter.api.AfterEach import org.junit.jupiter.api.BeforeEach +import org.junit.jupiter.api.Test import org.springframework.beans.factory.annotation.Autowired +import org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get +import org.springframework.test.web.servlet.result.MockMvcResultMatchers.status +import kotlin.test.assertEquals +import kotlin.test.assertNotNull class AuthorizationAuthenticationIT : BaseIT() { @Autowired @@ -73,65 +79,75 @@ class AuthorizationAuthenticationIT : BaseIT() { deleteFirebaseUser(uuidFirebaseUserRole) } -// @Test -// fun `test get groups authentication`() { -// val verifyPasswordResponse = -// firebaseWebClientTestMock.verifyPassword(FirebaseVerifyPasswordRequest(userRoleEmail, userRolePassword, true)) -// val idToken = "Bearer ${verifyPasswordResponse?.idToken}" -// // WHEN -// val resultAction = this.mockMvc -// .perform( -// get(baseUrl).header("Authorization", idToken) -// ) -// // THEN -// resultAction.andExpect(status().isOk) -// } -// -// @Test -// fun `test get groups authentication invalid token`() { -// val badToken = -// "Bearer eyJhbGciOiJSUzI1NiIsImtpZCI6ImYwNTM4MmFlMTgxYWJlNjFiOTYwYjA1Yzk3ZmE0MDljNDdhNDQ0ZTciLCJ0eXAiOiJKV1QifQ.eyJuYW1lIjoidGVzdFVzZXJGaXJzdE5hbWUiLCJpc3MiOiJodHRwczovL3NlY3VyZXRva2VuLmdvb2dsZS5jb20vYnJhaW5hcHAta295bHViYWV2IiwiYXVkIjoiYnJhaW5hcHAta295bHViYWV2IiwiYXV0aF90aW1lIjoxNjM0MTE2MjM4LCJ1c2VyX2lkIjoiZmVRRGRMTVRkU1F2UnVNVTNjeUNmRmt6dFNRMiIsInN1YiI6ImZlUURkTE1UZFNRdlJ1TVUzY3lDZkZrenRTUTIiLCJpYXQiOjE2MzQxMTYyMzgsImV4cCI6MTYzNDExOTgzOCwiZW1haWwiOiJ0ZXN0YWRtaW5AYWRtaW4uY29tIiwiZW1haWxfdmVyaWZpZWQiOmZhbHNlLCJmaXJlYmFzZSI6eyJpZGVudGl0aWVzIjp7ImVtYWlsIjpbInRlc3RhZG1pbkBhZG1pbi5jb20iXX0sInNpZ25faW5fcHJvdmlkZXIiOiJwYXNzd29yZCJ9fQ.PYLm9Zlo1edRmLWCK-RxW_GJ0oRtDYS4QHUV8SZ5rjG6R0AQucT8DcZD6Qlp0BOKLYzDrO3kEq5vs6e3FAvX-x7FT2hRUmuWTsWKDuC4sRhJBTM-zgP01BiqcTQ1vN23bZ70FW98BdhnPuLVDmB9wrDtVfDs4Zj3RsxOQGwPwyNr6FXJW0P9s55gnD5rFGr_2lNQRAIlOlTKKrYOboo1TqFYVUXcuY6GqDcKUkRGfr0sLdRorYCSZVGkjenyFCllIlMeIrTkbnWUtanKIHorwdMtmYTcneMV6bAMmOMvOQBA9lHH8pqeaDjHR_GxgzyXevEo74E2SxatGSUZ0lQK2Q" -// // WHEN -// val resultAction = this.mockMvc -// .perform( -// get(baseUrl).header("Authorization", badToken) -// ) -// // THEN -// resultAction.andExpect(status().isForbidden) -// } -// -// @Test -// fun `test create new user in local DB when login new firebase user`() { -// val verifyPasswordResponse = -// firebaseWebClientTestMock.verifyPassword(FirebaseVerifyPasswordRequest(newUserEmail, newUserPassword, true)) -// val idToken = "Bearer ${verifyPasswordResponse?.idToken}" -// -// // WHEN -// val resultAction = this.mockMvc -// .perform( -// get(baseUrl).header("Authorization", idToken) -// ) -// // THEN -// resultAction.andExpect(status().isOk) -// val userAccount = userAccountRepository.findUserAccountByEmail(newUserEmail).get() -// assertNotNull(userAccount) -// assertEquals(newUserFullName, userAccount.fullName) -// } -// -// @Test -// fun `test get admin-users when don't have permission for it`() { -// val verifyPasswordResponse = -// firebaseWebClientTestMock.verifyPassword(FirebaseVerifyPasswordRequest(userRoleEmail, userRolePassword, true)) -// val idToken = "Bearer ${verifyPasswordResponse?.idToken}" -// -// // WHEN -// val resultAction = this.mockMvc -// .perform( -// get(searchUsersPath).header("Authorization", idToken) -// ) -// // THEN -// resultAction.andExpect(status().isForbidden) -// } + @Test + fun `test get groups authentication`() { + val verifyPasswordResponse = + firebaseWebClientTestMock.verifyPassword( + FirebaseVerifyPasswordRequest( + userRoleEmail, + userRolePassword, + true, + ), + ) + val idToken = "Bearer ${verifyPasswordResponse?.idToken}" + // WHEN + val resultAction = + this.mockMvc + .perform( + get(baseUrl).header("Authorization", idToken), + ) + // THEN + resultAction.andExpect(status().isOk) + } + + @Test + fun `test get groups authentication invalid token`() { + val badToken = + "Bearer eyJhbGciOiJSUzI1NiIsImtpZCI6ImYwNTM4MmFlMTgxYWJlNjFiOTYwYjA1Yzk3ZmE0MDljNDdhNDQ0ZTciLCJ0eXAiOiJKV1QifQ.eyJuYW1lIjoidGVzdFVzZXJGaXJzdE5hbWUiLCJpc3MiOiJodHRwczovL3NlY3VyZXRva2VuLmdvb2dsZS5jb20vYnJhaW5hcHAta295bHViYWV2IiwiYXVkIjoiYnJhaW5hcHAta295bHViYWV2IiwiYXV0aF90aW1lIjoxNjM0MTE2MjM4LCJ1c2VyX2lkIjoiZmVRRGRMTVRkU1F2UnVNVTNjeUNmRmt6dFNRMiIsInN1YiI6ImZlUURkTE1UZFNRdlJ1TVUzY3lDZkZrenRTUTIiLCJpYXQiOjE2MzQxMTYyMzgsImV4cCI6MTYzNDExOTgzOCwiZW1haWwiOiJ0ZXN0YWRtaW5AYWRtaW4uY29tIiwiZW1haWxfdmVyaWZpZWQiOmZhbHNlLCJmaXJlYmFzZSI6eyJpZGVudGl0aWVzIjp7ImVtYWlsIjpbInRlc3RhZG1pbkBhZG1pbi5jb20iXX0sInNpZ25faW5fcHJvdmlkZXIiOiJwYXNzd29yZCJ9fQ.PYLm9Zlo1edRmLWCK-RxW_GJ0oRtDYS4QHUV8SZ5rjG6R0AQucT8DcZD6Qlp0BOKLYzDrO3kEq5vs6e3FAvX-x7FT2hRUmuWTsWKDuC4sRhJBTM-zgP01BiqcTQ1vN23bZ70FW98BdhnPuLVDmB9wrDtVfDs4Zj3RsxOQGwPwyNr6FXJW0P9s55gnD5rFGr_2lNQRAIlOlTKKrYOboo1TqFYVUXcuY6GqDcKUkRGfr0sLdRorYCSZVGkjenyFCllIlMeIrTkbnWUtanKIHorwdMtmYTcneMV6bAMmOMvOQBA9lHH8pqeaDjHR_GxgzyXevEo74E2SxatGSUZ0lQK2Q" + // WHEN + val resultAction = + this.mockMvc + .perform( + get(baseUrl).header("Authorization", badToken), + ) + // THEN + resultAction.andExpect(status().isForbidden) + } + + @Test + fun `test create new user in local DB when login new firebase user`() { + val verifyPasswordResponse = + firebaseWebClientTestMock.verifyPassword(FirebaseVerifyPasswordRequest(newUserEmail, newUserPassword, true)) + val idToken = "Bearer ${verifyPasswordResponse?.idToken}" + + // WHEN + val resultAction = + this.mockMvc + .perform( + get(baseUrl).header("Authorization", idToken), + ) + // THEN + resultAction.andExpect(status().isOk) + val userAccount = userAccountRepository.findUserAccountByEmail(newUserEmail).get() + assertNotNull(userAccount) + assertEquals(newUserFullName, userAccount.fullName) + } + + @Test + fun `test get admin-users when don't have permission for it`() { + val verifyPasswordResponse = + firebaseWebClientTestMock.verifyPassword(FirebaseVerifyPasswordRequest(userRoleEmail, userRolePassword, true)) + val idToken = "Bearer ${verifyPasswordResponse?.idToken}" + + // WHEN + val resultAction = + this.mockMvc + .perform( + get(searchUsersPath).header("Authorization", idToken), + ) + // THEN + resultAction.andExpect(status().isForbidden) + } private fun saveFirebaseUser( fullName: String, diff --git a/src/test/kotlin/com/epam/brn/integration/configuration/FirebaseTestConfig.kt b/src/test/kotlin/com/epam/brn/integration/configuration/FirebaseTestConfig.kt new file mode 100644 index 000000000..e7505bd22 --- /dev/null +++ b/src/test/kotlin/com/epam/brn/integration/configuration/FirebaseTestConfig.kt @@ -0,0 +1,38 @@ +package com.epam.brn.integration.configuration + +import com.google.auth.oauth2.GoogleCredentials +import com.google.firebase.FirebaseApp +import com.google.firebase.FirebaseOptions +import com.google.firebase.auth.FirebaseAuth +import com.google.firebase.messaging.FirebaseMessaging +import org.springframework.beans.factory.annotation.Value +import org.springframework.context.annotation.Bean +import org.springframework.context.annotation.Configuration +import org.testcontainers.junit.jupiter.Testcontainers +import java.io.FileInputStream + +@Configuration +@Testcontainers +class FirebaseTestConfig( + @Value("\${firebase.test.config.path}") private val firebaseTestConfigPath: String, +) { + @Bean + fun firebaseApp(): FirebaseApp { + if (FirebaseApp.getApps().isEmpty()) { + val refreshToken = FileInputStream(firebaseTestConfigPath) + val options = + FirebaseOptions + .builder() + .setCredentials(GoogleCredentials.fromStream(refreshToken)) + .build() + FirebaseApp.initializeApp(options) + } + return FirebaseApp.getInstance() + } + + @Bean + fun firebaseAuth(): FirebaseAuth = FirebaseAuth.getInstance(firebaseApp()) + + @Bean + fun firebaseMessaging(): FirebaseMessaging = FirebaseMessaging.getInstance(firebaseApp()) +} diff --git a/src/test/resources/application.properties b/src/test/resources/application.properties index c90744a63..8bc971504 100644 --- a/src/test/resources/application.properties +++ b/src/test/resources/application.properties @@ -90,7 +90,8 @@ webclient.firebase.url=https://www.googleapis.com webclient.firebase.path.verify-password=/identitytoolkit/v3/relyingparty/verifyPassword webclient.firebase.verify-password.query={'key':'AIzaSyB03Q4ZCxdqaKuN7cJqCQGhkibYD4Q-qsc'} firebase.import.batch-count=100 -firebase.credentials.path=src/test/resources/firebase-brainupspb-dev.json +# service account JSON provided via environment variable +firebase.test.config.path=${FIREBASE_TEST_CONFIG_PATH:src/test/resources/firebase-brainupspb-test.json} # yandex / azure default.tts.provider=yandex diff --git a/src/test/resources/firebase-brainupspb-dev.json b/src/test/resources/firebase-brainupspb-dev.json deleted file mode 100644 index aabac918e..000000000 --- a/src/test/resources/firebase-brainupspb-dev.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "type": "service_account", - "project_id": "brainup-spb-dev-bb6d0", - "private_key_id": "3cb0cd1dedd6878398b3888e5c2ed0118187e6ee", - "private_key": "-----BEGIN PRIVATE KEY-----\nMIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDFCKvFU1hGa8aU\nM/D6TGT6NeqZD/CFRSF9MsRFUlFMtF1oYbN0nRSfnadeZah4IDruVmbVzjDuIt0f\n1OKh0NRB1mlIP+I6PTDWSUY8709j7OyOdNsFwmC9eD4DL/AeuqFiJu0LlNSie2dc\n8MiHrK0hEhw0WVL06dWave/xh3cflt2LGAsNC2pyGB3YSSJpq9FEKnsWe7lBvzkO\nGHbcQ5/djjnG3ceHXxN4tbTs+D0v0QYrGqptOmJIp1stTrPEEhuBnmNtdPn9IEB1\njbkGKH8PsY4yNu5WmWjvtQEIDIh/SGzKh99dulztRupx2leDWQ4uQ5WioYBPheoL\nSyAAMSjjAgMBAAECggEANvcoyAbsoNSPFKf6yTCHmN9ynxl5vQvggEcpxrbklDPa\nvPRIdjcd2jtGRgiw+zXuiq+Sx4FaWAxkyG0Afii+FdHFFBEyQJHybk0JqZUO/i7J\nfSIvOYeUqjaBgi0c3M2umK2IQktWGC+50Y0gO+0ZbRjawmXKxST4YE8tQSFLw4U6\nGcCL/VKTqH99bBExier+4avLP9scd/QN6fCBwAg+v82C4ncmJKwFb4qFMuP07qeF\n97ef1ZktdQeLgGcfPS1xpHLciylH6Q6FjqpzAUzmkNIjFNt+3A2gBUPBCX1A0Bze\nFWMscxmpl5JXqKorS7vCOcy5DY8U0vqzTAbTx4yQLQKBgQD7C+mf70/oOW/70sR5\n+qlDfWzk1iOn0L4XEGgDN9G98kMdUx9W4/xrhhsBURsRt93yrZyqnXBX9MkwJtla\nmvhjKJc3aCC9yZJWOo8RGNdGtm0J6PtuAPTg2hYGbwygkSspO21NjrtjRNpKtzj0\nX61z3WGG41sMFONG4EaH+p35NQKBgQDI6+3rcYsTDgKcZTA6htlDa8HS4wwtYBwx\nw8wVOu+2MFJnX2QPQOy9ZD3syDqDP5jkPhZ23xnKY7RgldsaKMaeNrNv9d9uwKav\nCEx6sEZc8rJf2gt4RoNkyvS/KvUMwiwMOYYuRnajN6nVHQHSoNg1TSbwEiIFcNMR\nacoLlfh0twKBgQD2O0Dyda9SfsOvo5LCcXEDmUntSXu/ZaaMyLK8NUurmqrpYFYk\ny4kRjX9/UyXRwx4WoOJBFhrSqm2KpRAbJlTqLS3kUmWKwOKfYOBiTJMZ8GQSjEnQ\nI3AL+twPg2xHMRu8XWVf5Nc3DpltHzjlt9JRCppVyznKJ9Kj+eY0CURY4QKBgA6C\no2sWhyG4KE4dLK99X6Fz3cqaJR39y+t4JXv/BqLUuI7In9ROLwq6e5JnH3qtFCCf\nr0WkdRtdugAjsnAgM7/nWWwjiKBZ/2+ynLtbkalSybkMaTmldgXIdoZ71ri2KTI0\n0VD0O8sr0PMYJjKM9TBcQwyhcp2L+WJPjozppsjfAoGAOvlZ0CF3sKmF9QyuWoFV\nguQpkVo5f8Q2MJdPjp5CafFkK84HSOGcb/gaJkhUuUz/K8n8OTnwB1PhfxUJ86m9\nBMlU7Be/Wjxk+5V8crjQrcb8mnxBZLyl0CDtf+efaqPhYlWo0yb8b+eiDToVmico\np0DioqzUPIYy075MF189NPM=\n-----END PRIVATE KEY-----\n", - "client_email": "firebase-adminsdk-a3xzg@brainup-spb-dev-bb6d0.iam.gserviceaccount.com", - "client_id": "118039374628498438928", - "auth_uri": "https://accounts.google.com/o/oauth2/auth", - "token_uri": "https://oauth2.googleapis.com/token", - "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs", - "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/firebase-adminsdk-a3xzg%40brainup-spb-dev-bb6d0.iam.gserviceaccount.com" -} diff --git a/src/test/resources/firebase-brainupspb-test.json b/src/test/resources/firebase-brainupspb-test.json new file mode 100644 index 000000000..a16822a25 --- /dev/null +++ b/src/test/resources/firebase-brainupspb-test.json @@ -0,0 +1,12 @@ +{ + "type": "service_account", + "project_id": "brainup-spb-dev-bb6d0", + "private_key_id": "askElena https://t.me/ElenaBrainUp", + "private_key": "askElena https://t.me/ElenaBrainUp", + "client_email": "firebase-adminsdk-a3xzg@brainup-spb-dev-bb6d0.iam.gserviceaccount.com", + "client_id": "118039374628498438928", + "auth_uri": "https://accounts.google.com/o/oauth2/auth", + "token_uri": "https://oauth2.googleapis.com/token", + "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs", + "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/firebase-adminsdk-a3xzg%40brainup-spb-dev-bb6d0.iam.gserviceaccount.com" +} \ No newline at end of file