diff --git a/accountant/accountant-app/src/main/resources/application.yml b/accountant/accountant-app/src/main/resources/application.yml index 322f4fa83..1f71cb1b8 100644 --- a/accountant/accountant-app/src/main/resources/application.yml +++ b/accountant/accountant-app/src/main/resources/application.yml @@ -47,4 +47,4 @@ spring: app: address: 1 wallet: - url: lb://opex-wallet/ + url: lb://opex-wallet/ \ No newline at end of file diff --git a/docker-compose.override.yml b/docker-compose.override.yml index 038bf9623..c1e63580e 100644 --- a/docker-compose.override.yml +++ b/docker-compose.override.yml @@ -19,6 +19,9 @@ services: build: matching-gateway/matching-gateway-app auth: build: user-management/keycloak-gateway + volumes: + - "./preferences-dev.yml:/preferences.yml" + - "./whitelist.txt:/whitelist.txt" wallet: build: wallet/wallet-app volumes: diff --git a/docker-compose.yml b/docker-compose.yml index fe3f7fdb5..f5955b9dc 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -281,6 +281,7 @@ services: - FORGOT_REDIRECT_URL=$KEYCLOAK_FORGOT_REDIRECT_URL - VAULT_URL=http://vault:8200 - VAULT_HOST=vault + - PREFERENCES=$PREFERENCES depends_on: - captcha - kafka-1 diff --git a/preferences-demo.yml b/preferences-demo.yml index 5fbf3cbd3..b57dd1784 100644 --- a/preferences-demo.yml +++ b/preferences-demo.yml @@ -225,3 +225,7 @@ userLimits: system: walletTitle: system walletLevel: basic +auth: + whitelist: + enabled: false + file: /whitelist.txt diff --git a/preferences-dev.yml b/preferences-dev.yml index f79eb12c7..b598baf63 100644 --- a/preferences-dev.yml +++ b/preferences-dev.yml @@ -260,4 +260,8 @@ userLimits: monthlyCount: 3000 system: walletTitle: system - walletLevel: basic \ No newline at end of file + walletLevel: basic +auth: + whitelist: + enabled: false + file: /whitelist.txt \ No newline at end of file diff --git a/user-management/keycloak-gateway/src/main/kotlin/co/nilin/opex/auth/gateway/KeycloakGatewayApp.kt b/user-management/keycloak-gateway/src/main/kotlin/co/nilin/opex/auth/gateway/KeycloakGatewayApp.kt index 01c6a057f..a9edbf388 100644 --- a/user-management/keycloak-gateway/src/main/kotlin/co/nilin/opex/auth/gateway/KeycloakGatewayApp.kt +++ b/user-management/keycloak-gateway/src/main/kotlin/co/nilin/opex/auth/gateway/KeycloakGatewayApp.kt @@ -1,5 +1,6 @@ package co.nilin.opex.auth.gateway +import co.nilin.opex.utility.error.EnableOpexErrorHandler import org.springframework.boot.autoconfigure.SpringBootApplication import org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration import org.springframework.boot.context.properties.EnableConfigurationProperties @@ -7,7 +8,8 @@ import org.springframework.boot.runApplication import org.springframework.context.annotation.ComponentScan @SpringBootApplication(exclude = [LiquibaseAutoConfiguration::class]) -@ComponentScan(basePackages = ["co.nilin.opex.auth.gateway"]) +@ComponentScan("co.nilin.opex") +@EnableOpexErrorHandler @EnableConfigurationProperties class KeycloakGatewayApp diff --git a/user-management/keycloak-gateway/src/main/kotlin/co/nilin/opex/auth/gateway/config/ErrorHandlerConfig.kt b/user-management/keycloak-gateway/src/main/kotlin/co/nilin/opex/auth/gateway/config/ErrorHandlerConfig.kt deleted file mode 100644 index cbb6fe5cc..000000000 --- a/user-management/keycloak-gateway/src/main/kotlin/co/nilin/opex/auth/gateway/config/ErrorHandlerConfig.kt +++ /dev/null @@ -1,18 +0,0 @@ -package co.nilin.opex.auth.gateway.config - -import co.nilin.opex.utility.error.DefaultErrorTranslator -import co.nilin.opex.utility.error.EnableOpexErrorHandler -import co.nilin.opex.utility.error.spi.ErrorTranslator -import org.springframework.context.annotation.Bean -import org.springframework.context.annotation.Configuration - -@Configuration -@EnableOpexErrorHandler -class ErrorHandlerConfig { - - @Bean - fun errorTranslator(): ErrorTranslator { - return DefaultErrorTranslator() - } - -} \ No newline at end of file diff --git a/user-management/keycloak-gateway/src/main/kotlin/co/nilin/opex/auth/gateway/config/WhitelistConfig.kt b/user-management/keycloak-gateway/src/main/kotlin/co/nilin/opex/auth/gateway/config/WhitelistConfig.kt new file mode 100644 index 000000000..abd3742f3 --- /dev/null +++ b/user-management/keycloak-gateway/src/main/kotlin/co/nilin/opex/auth/gateway/config/WhitelistConfig.kt @@ -0,0 +1,38 @@ +package co.nilin.opex.auth.gateway.config + +import co.nilin.opex.auth.gateway.data.Whitelist +import co.nilin.opex.utility.preferences.Preferences +import org.slf4j.LoggerFactory +import org.springframework.context.annotation.Bean +import org.springframework.context.annotation.Configuration +import java.io.File + +@Configuration +class WhitelistConfig(private val preferences: Preferences) { + + private val logger = LoggerFactory.getLogger(WhitelistConfig::class.java) + + @Bean("whitelist") + fun whitelist(): Whitelist { + val whitelist = with(preferences.auth.whitelist) { + val file = File(file) + if (!enabled) { + logger.info("whitelist disabled by preferences") + Whitelist() + } + + if (!file.exists()) { + logger.info("whitelist file doesn't exists") + Whitelist() + } + + val list = file.readLines().onEach { it.trim().toLowerCase() } + Whitelist(list.isNotEmpty(), list) + } + + logger.info("whitelist enabled: ${whitelist.isEnabled}") + logger.info("whitelist emails: ${whitelist.emails}") + return whitelist + } + +} \ No newline at end of file diff --git a/user-management/keycloak-gateway/src/main/kotlin/co/nilin/opex/auth/gateway/data/Whitelist.kt b/user-management/keycloak-gateway/src/main/kotlin/co/nilin/opex/auth/gateway/data/Whitelist.kt new file mode 100644 index 000000000..e08374f9e --- /dev/null +++ b/user-management/keycloak-gateway/src/main/kotlin/co/nilin/opex/auth/gateway/data/Whitelist.kt @@ -0,0 +1,6 @@ +package co.nilin.opex.auth.gateway.data + +data class Whitelist( + val isEnabled: Boolean = false, + val emails: List = emptyList() +) \ No newline at end of file diff --git a/user-management/keycloak-gateway/src/main/kotlin/co/nilin/opex/auth/gateway/extension/UserManagementResource.kt b/user-management/keycloak-gateway/src/main/kotlin/co/nilin/opex/auth/gateway/extension/UserManagementResource.kt index 11e6ea85d..38623607f 100644 --- a/user-management/keycloak-gateway/src/main/kotlin/co/nilin/opex/auth/gateway/extension/UserManagementResource.kt +++ b/user-management/keycloak-gateway/src/main/kotlin/co/nilin/opex/auth/gateway/extension/UserManagementResource.kt @@ -41,6 +41,7 @@ class UserManagementResource(private val session: KeycloakSession) : RealmResour private val logger = LoggerFactory.getLogger(UserManagementResource::class.java) private val opexRealm = session.realms().getRealm("opex") + private val whitelist by lazy { ApplicationContextHolder.getCurrentContext()!!.getBean("whitelist") as Whitelist } private val verifyUrl by lazy { ApplicationContextHolder.getCurrentContext()!!.environment.resolvePlaceholders("\${verify-redirect-url}") } @@ -59,6 +60,10 @@ class UserManagementResource(private val session: KeycloakSession) : RealmResour val auth = ResourceAuthenticator.bearerAuth(session) if (!auth.hasScopeAccess("trust")) return ErrorHandler.forbidden() + if (whitelist.isEnabled && request.email != null && !whitelist.emails.contains(request.email!!.toLowerCase())) { + return ErrorHandler.forbidden() + } + runCatching { validateCaptcha("${request.captchaAnswer}-${session.context.connection.remoteAddr}") }.onFailure { diff --git a/user-management/keycloak-gateway/src/main/resources/application.yml b/user-management/keycloak-gateway/src/main/resources/application.yml index c89d68fd4..0a1e3e74c 100644 --- a/user-management/keycloak-gateway/src/main/resources/application.yml +++ b/user-management/keycloak-gateway/src/main/resources/application.yml @@ -73,3 +73,5 @@ keycloak: app: verify-redirect-url: ${VERIFY_REDIRECT_URL} forgot-redirect-url: ${FORGOT_REDIRECT_URL} + whitelist: + enabled: ${WHITELIST_ENABLED:false} diff --git a/user-management/pom.xml b/user-management/pom.xml index a8d376b21..1d8c5530e 100644 --- a/user-management/pom.xml +++ b/user-management/pom.xml @@ -30,6 +30,10 @@ org.springframework.boot spring-boot-starter-test + + co.nilin.opex.utility.preferences + preferences + @@ -39,6 +43,11 @@ error-handler ${project.version} + + co.nilin.opex.utility.preferences + preferences + ${project.version} + diff --git a/utility/preferences/src/main/kotlin/co/nilin/opex/utility/preferences/Auth.kt b/utility/preferences/src/main/kotlin/co/nilin/opex/utility/preferences/Auth.kt new file mode 100644 index 000000000..b4cb971c9 --- /dev/null +++ b/utility/preferences/src/main/kotlin/co/nilin/opex/utility/preferences/Auth.kt @@ -0,0 +1,3 @@ +package co.nilin.opex.utility.preferences + +data class Auth(val whitelist: WhitelistConfig = WhitelistConfig()) \ No newline at end of file diff --git a/utility/preferences/src/main/kotlin/co/nilin/opex/utility/preferences/Preferences.kt b/utility/preferences/src/main/kotlin/co/nilin/opex/utility/preferences/Preferences.kt index 6d42a5e23..543bd25d1 100644 --- a/utility/preferences/src/main/kotlin/co/nilin/opex/utility/preferences/Preferences.kt +++ b/utility/preferences/src/main/kotlin/co/nilin/opex/utility/preferences/Preferences.kt @@ -6,5 +6,6 @@ data class Preferences( var currencies: List = emptyList(), var markets: List = emptyList(), var userLimits: List = emptyList(), - var system: System = System() + var system: System = System(), + val auth: Auth = Auth() ) diff --git a/utility/preferences/src/main/kotlin/co/nilin/opex/utility/preferences/WhitelistConfig.kt b/utility/preferences/src/main/kotlin/co/nilin/opex/utility/preferences/WhitelistConfig.kt new file mode 100644 index 000000000..0cf8dbf12 --- /dev/null +++ b/utility/preferences/src/main/kotlin/co/nilin/opex/utility/preferences/WhitelistConfig.kt @@ -0,0 +1,6 @@ +package co.nilin.opex.utility.preferences + +data class WhitelistConfig( + val enabled: Boolean = false, + val file: String = "/whitelist.txt" +) \ No newline at end of file diff --git a/whitelist.txt b/whitelist.txt new file mode 100644 index 000000000..e69de29bb