-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* #21 - divided base and jwt config - application.properties replaced by application.yaml - loading knownUsers objects from config - DummyAuthenticationProvider.scala -> ConfigUsersAuthenticationProvider (actually consumes config) - basic UserConfig validation on app startup - validates groups presence, may be empty - userconfig validation for duplicates added - introduced sealed trait ConfigValidationResult (with container impl ConfigValidationError and emptyConfigValidationSuccess). - ConfigValidationResult helper methods ( .merge(CVR), .getErrors, ConfigValidationError creation shorthand) - ConfigValidationResult.throwOnErrors - unit tests added
- Loading branch information
Showing
20 changed files
with
711 additions
and
110 deletions.
There are no files selected for viewing
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
logingw: | ||
rest: | ||
# Rest General Config | ||
jwt: | ||
exp-time: 4 | ||
alg-name: "RS256" | ||
config: | ||
some-key: "BETA" | ||
|
||
# Users (config-defined) | ||
users: | ||
known-users: | ||
- | ||
username: "user1" | ||
password: "password1" | ||
groups: | ||
- | ||
username: "TestUser" | ||
password: "password123" | ||
email: "[email protected]" | ||
groups: | ||
- "groupA" | ||
- "groupB" | ||
|
||
# Rest Auth Config (AD) | ||
auth: | ||
ad: | ||
ldap: | ||
domain: "some.domain.com" | ||
url: "ldaps://some.domain.com:636/" | ||
search-filter: "(samaccountname={1})" | ||
|
||
# App Config | ||
spring: | ||
application: | ||
name: "login-gateway" | ||
jmx: | ||
enabled: true | ||
server: | ||
port: 9090 | ||
|
||
# Health Check Config + JMX Config | ||
springdoc: | ||
show-actuator: true | ||
|
||
management: | ||
health: | ||
ldap: | ||
#TODO: Enable Ldap check for actuator/health when fully Implemented - issue #34 | ||
enabled: "false" | ||
endpoints: | ||
jmx: | ||
exposure: | ||
include: "health" | ||
web: | ||
exposure: | ||
include: "health" | ||
endpoint: | ||
health: | ||
show-details: "never" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
53 changes: 53 additions & 0 deletions
53
service/src/main/scala/za/co/absa/logingw/rest/AuthManagerConfig.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
/* | ||
* Copyright 2023 ABSA Group Limited | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
package za.co.absa.logingw.rest | ||
|
||
import org.springframework.beans.factory.annotation.Autowired | ||
import org.springframework.context.annotation.{Bean, Configuration} | ||
import org.springframework.security.authentication.AuthenticationManager | ||
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder | ||
import org.springframework.security.config.annotation.web.builders.HttpSecurity | ||
import za.co.absa.logingw.rest.config.{ActiveDirectoryLDAPConfig, UsersConfig} | ||
import za.co.absa.logingw.rest.provider.ConfigUsersAuthenticationProvider | ||
import za.co.absa.logingw.rest.provider.ad.ldap.ActiveDirectoryLDAPAuthenticationProvider | ||
|
||
@Configuration | ||
class AuthManagerConfig @Autowired()( | ||
// TODO make it autowired but only if in config AD LDAP provider is set up (#28) | ||
usersConfig: UsersConfig, | ||
adLDAPConfig: ActiveDirectoryLDAPConfig | ||
){ | ||
|
||
@Bean | ||
def authManager(http: HttpSecurity): AuthenticationManager = { | ||
val authenticationManagerBuilder = http.getSharedObject(classOf[AuthenticationManagerBuilder]) | ||
|
||
// TODO: take which providers and in which order to use from config (#28) | ||
authenticationManagerBuilder | ||
// if it is not null, on auth failure infinite recursion happens | ||
.parentAuthenticationManager(null) | ||
// currently, comment out or reorder the auth providers you want to use - #28 | ||
.authenticationProvider( | ||
new ConfigUsersAuthenticationProvider(usersConfig) | ||
) | ||
.authenticationProvider( | ||
new ActiveDirectoryLDAPAuthenticationProvider(adLDAPConfig) | ||
) | ||
.build | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
57 changes: 57 additions & 0 deletions
57
service/src/main/scala/za/co/absa/logingw/rest/config/JwtConfig.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
/* | ||
* Copyright 2023 ABSA Group Limited | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
package za.co.absa.logingw.rest.config | ||
|
||
import io.jsonwebtoken.SignatureAlgorithm | ||
import org.springframework.boot.context.properties.{ConfigurationProperties, ConstructorBinding} | ||
import za.co.absa.logingw.rest.config.validation.{ConfigValidatable, ConfigValidationException, ConfigValidationResult} | ||
import za.co.absa.logingw.rest.config.validation.ConfigValidationResult.{ConfigValidationError, ConfigValidationSuccess} | ||
|
||
import javax.annotation.PostConstruct | ||
import scala.util.{Failure, Success, Try} | ||
|
||
@ConstructorBinding | ||
@ConfigurationProperties(prefix = "logingw.rest.jwt") | ||
case class JwtConfig( | ||
algName: String, | ||
expTime: Int | ||
) extends ConfigValidatable { | ||
|
||
@PostConstruct | ||
def init(): Unit = { | ||
this.validate().throwOnErrors() | ||
} | ||
|
||
/** May throw ConfigValidationException or IllegalArgumentException */ | ||
override def validate(): ConfigValidationResult = { | ||
|
||
val algValidation = Try { | ||
SignatureAlgorithm.valueOf(algName) | ||
} match { | ||
case Success(_) => ConfigValidationSuccess | ||
case Failure(e: IllegalArgumentException) if e.getMessage.contains("No enum constant") => | ||
ConfigValidationError(ConfigValidationException(s"Invalid algName '$algName' was given.")) | ||
case Failure(e) => throw e | ||
} | ||
|
||
val expTimeResult = if (expTime < 1) { | ||
ConfigValidationError(ConfigValidationException("expTime must be positive (hours)")) | ||
} else ConfigValidationSuccess | ||
|
||
algValidation.merge(expTimeResult) | ||
} | ||
} |
91 changes: 91 additions & 0 deletions
91
service/src/main/scala/za/co/absa/logingw/rest/config/UsersConfig.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
/* | ||
* Copyright 2023 ABSA Group Limited | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
package za.co.absa.logingw.rest.config | ||
|
||
import org.springframework.boot.context.properties.{ConfigurationProperties, ConstructorBinding} | ||
import za.co.absa.logingw.rest.config.validation.ConfigValidationResult.{ConfigValidationError, ConfigValidationSuccess} | ||
import za.co.absa.logingw.rest.config.validation.{ConfigValidatable, ConfigValidationException, ConfigValidationResult} | ||
|
||
import javax.annotation.PostConstruct | ||
|
||
@ConstructorBinding | ||
@ConfigurationProperties(prefix = "logingw.rest.users") | ||
case class UsersConfig( | ||
knownUsers: Array[UserConfig], | ||
) extends ConfigValidatable { | ||
lazy val knownUsersMap: Map[String, UserConfig] = knownUsers | ||
.map { entry => (entry.username, entry) } | ||
.toMap | ||
|
||
// todo validation is done using a custom trait/method -- Issue #24 validation | ||
// Until is resolved https://github.com/spring-projects/spring-boot/issues/33669 | ||
override def validate(): ConfigValidationResult = { | ||
Option(knownUsers).map { existingKnownUsers => | ||
|
||
val kuDuplicatesResult = { | ||
val groupedByUsers = existingKnownUsers.groupBy(_.username) | ||
if (groupedByUsers.size < existingKnownUsers.size) { | ||
val duplicates = groupedByUsers.filter { case (username, configs) => configs.length > 1 }.keys | ||
ConfigValidationError(ConfigValidationException(s"knownUsers contain duplicates, duplicated usernames: ${duplicates.mkString(", ")}")) | ||
} else ConfigValidationSuccess | ||
} | ||
|
||
val usersResult = existingKnownUsers.map(_.validate()).toList | ||
|
||
(kuDuplicatesResult :: usersResult) | ||
.foldLeft[ConfigValidationResult](ConfigValidationSuccess)(ConfigValidationResult.merge) | ||
|
||
}.getOrElse(ConfigValidationError(ConfigValidationException("knownUsers is missing"))) | ||
} | ||
|
||
@PostConstruct | ||
def init(): Unit = { | ||
this.validate().throwOnErrors() | ||
} | ||
} | ||
|
||
@ConstructorBinding | ||
case class UserConfig( | ||
username: String, | ||
password: String, | ||
email: String, // may be null | ||
groups: Array[String] | ||
) extends ConfigValidatable { | ||
|
||
override def toString: String = { | ||
s"UserConfig($username, $password, $email, ${Option(groups).map(_.toList)})" | ||
} | ||
|
||
override def validate(): ConfigValidationResult = { | ||
val results = Seq( | ||
Option(username) | ||
.map(_ => ConfigValidationSuccess) | ||
.getOrElse(ConfigValidationError(ConfigValidationException("username is empty"))), | ||
|
||
Option(password) | ||
.map(_ => ConfigValidationSuccess) | ||
.getOrElse(ConfigValidationError(ConfigValidationException("password is empty"))), | ||
|
||
Option(groups) | ||
.map(_ => ConfigValidationSuccess) | ||
.getOrElse(ConfigValidationError(ConfigValidationException("groups are missing (empty groups are allowed)!"))) | ||
|
||
) | ||
|
||
results.foldLeft[ConfigValidationResult](ConfigValidationSuccess)(ConfigValidationResult.merge) | ||
} | ||
} |
22 changes: 22 additions & 0 deletions
22
service/src/main/scala/za/co/absa/logingw/rest/config/validation/ConfigValidatable.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
/* | ||
* Copyright 2023 ABSA Group Limited | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
package za.co.absa.logingw.rest.config.validation | ||
|
||
trait ConfigValidatable { | ||
def validate(): ConfigValidationResult | ||
|
||
} |
20 changes: 20 additions & 0 deletions
20
.../src/main/scala/za/co/absa/logingw/rest/config/validation/ConfigValidationException.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
/* | ||
* Copyright 2023 ABSA Group Limited | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
package za.co.absa.logingw.rest.config.validation | ||
|
||
case class ConfigValidationException(msg: String) extends Exception(msg) | ||
|
Oops, something went wrong.