-
Notifications
You must be signed in to change notification settings - Fork 93
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Authenticate using Snowflake authentication mechanism (#4315)
--------- Signed-off-by: Iliyan Velichkov <[email protected]>
- Loading branch information
1 parent
9db3de6
commit e6c4481
Showing
16 changed files
with
515 additions
and
35 deletions.
There are no files selected for viewing
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
29 changes: 29 additions & 0 deletions
29
...va/org/eclipse/dirigible/components/base/http/access/CorsConfigurationSourceProvider.java
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,29 @@ | ||
package org.eclipse.dirigible.components.base.http.access; | ||
|
||
import org.springframework.web.cors.CorsConfiguration; | ||
import org.springframework.web.cors.CorsConfigurationSource; | ||
import org.springframework.web.cors.UrlBasedCorsConfigurationSource; | ||
|
||
import java.util.Arrays; | ||
import java.util.List; | ||
|
||
public class CorsConfigurationSourceProvider { | ||
|
||
public static CorsConfigurationSource get() { | ||
CorsConfiguration configuration = new CorsConfiguration(); | ||
configuration.setAllowedOriginPatterns(List.of("*")); | ||
configuration.setAllowCredentials(true); | ||
configuration.setAllowedHeaders( | ||
Arrays.asList("Access-Control-Allow-Headers", "Access-Control-Allow-Origin", "Access-Control-Request-Method", | ||
"Access-Control-Request-Headers", "Origin", "Cache-Control", "Content-Type", "Authorization")); | ||
configuration.setExposedHeaders( | ||
Arrays.asList("Access-Control-Allow-Headers", "Access-Control-Allow-Origin", "Access-Control-Request-Method", | ||
"Access-Control-Request-Headers", "Origin", "Cache-Control", "Content-Type", "Authorization")); | ||
configuration.setAllowedMethods(Arrays.asList("HEAD", "DELETE", "GET", "POST", "PATCH", "PUT")); | ||
|
||
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); | ||
source.registerCorsConfiguration("/**", configuration); | ||
|
||
return source; | ||
} | ||
} |
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<project xmlns="http://maven.apache.org/POM/4.0.0" | ||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||
|
||
<modelVersion>4.0.0</modelVersion> | ||
|
||
<parent> | ||
<artifactId>dirigible-components-parent</artifactId> | ||
<groupId>org.eclipse.dirigible</groupId> | ||
<version>11.0.0-SNAPSHOT</version> | ||
<relativePath>../../pom.xml</relativePath> | ||
</parent> | ||
|
||
<name>Components - Security - Snowflake</name> | ||
<artifactId>dirigible-components-security-snowflake</artifactId> | ||
<packaging>jar</packaging> | ||
|
||
<dependencies> | ||
<dependency> | ||
<groupId>org.eclipse.dirigible</groupId> | ||
<artifactId>dirigible-components-core-base</artifactId> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.eclipse.dirigible</groupId> | ||
<artifactId>dirigible-components-core-tenants</artifactId> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.springframework.boot</groupId> | ||
<artifactId>spring-boot-starter-oauth2-client</artifactId> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.springframework.boot</groupId> | ||
<artifactId>spring-boot-starter-security</artifactId> | ||
</dependency> | ||
</dependencies> | ||
|
||
<properties> | ||
<license.header.location>../../../licensing-header.txt</license.header.location> | ||
<parent.pom.folder>../../../</parent.pom.folder> | ||
</properties> | ||
|
||
</project> |
8 changes: 8 additions & 0 deletions
8
.../org/eclipse/dirigible/components/security/snowflake/InvalidSecurityContextException.java
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,8 @@ | ||
package org.eclipse.dirigible.components.security.snowflake; | ||
|
||
public class InvalidSecurityContextException extends RuntimeException { | ||
|
||
public InvalidSecurityContextException(String message) { | ||
super(message); | ||
} | ||
} |
102 changes: 102 additions & 0 deletions
102
...va/org/eclipse/dirigible/components/security/snowflake/SnowflakeAdminUserInitializer.java
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,102 @@ | ||
/* | ||
* Copyright (c) 2024 Eclipse Dirigible contributors | ||
* | ||
* All rights reserved. This program and the accompanying materials are made available under the | ||
* terms of the Eclipse Public License v2.0 which accompanies this distribution, and is available at | ||
* http://www.eclipse.org/legal/epl-v20.html | ||
* | ||
* SPDX-FileCopyrightText: Eclipse Dirigible contributors SPDX-License-Identifier: EPL-2.0 | ||
*/ | ||
package org.eclipse.dirigible.components.security.snowflake; | ||
|
||
import org.apache.commons.lang3.StringUtils; | ||
import org.eclipse.dirigible.commons.config.DirigibleConfig; | ||
import org.eclipse.dirigible.components.base.ApplicationListenersOrder.ApplicationReadyEventListeners; | ||
import org.eclipse.dirigible.components.base.http.roles.Roles; | ||
import org.eclipse.dirigible.components.base.tenant.DefaultTenant; | ||
import org.eclipse.dirigible.components.base.tenant.Tenant; | ||
import org.eclipse.dirigible.components.tenants.domain.User; | ||
import org.eclipse.dirigible.components.tenants.domain.UserRoleAssignment; | ||
import org.slf4j.Logger; | ||
import org.slf4j.LoggerFactory; | ||
import org.springframework.boot.context.event.ApplicationReadyEvent; | ||
import org.springframework.context.ApplicationListener; | ||
import org.springframework.context.annotation.Profile; | ||
import org.springframework.core.annotation.Order; | ||
import org.springframework.stereotype.Component; | ||
|
||
import java.util.Optional; | ||
|
||
@Profile("snowflake") | ||
@Order(ApplicationReadyEventListeners.ADMIN_USER_INITIALIZER) | ||
@Component | ||
class SnowflakeAdminUserInitializer implements ApplicationListener<ApplicationReadyEvent> { | ||
|
||
private static final Logger LOGGER = LoggerFactory.getLogger(SnowflakeAdminUserInitializer.class); | ||
|
||
private final Tenant defaultTenant; | ||
|
||
private final SnowflakeUserManager snowflakeUserManager; | ||
|
||
SnowflakeAdminUserInitializer(@DefaultTenant Tenant defaultTenant, SnowflakeUserManager snowflakeUserManager) { | ||
this.defaultTenant = defaultTenant; | ||
this.snowflakeUserManager = snowflakeUserManager; | ||
} | ||
|
||
@Override | ||
public void onApplicationEvent(ApplicationReadyEvent event) { | ||
LOGGER.info("Executing..."); | ||
initAdminUser(); | ||
LOGGER.info("Completed."); | ||
|
||
} | ||
|
||
private void initAdminUser() { | ||
Optional<String> optionalUsername = getSnowflakeAdminUsername(); | ||
if (optionalUsername.isEmpty()) { | ||
LOGGER.warn("Admin user will not be initialized"); | ||
return; | ||
} | ||
String username = optionalUsername.get(); | ||
|
||
Optional<User> existingUser = snowflakeUserManager.findUserByUsernameAndTenantId(username, defaultTenant.getId()); | ||
if (existingUser.isPresent()) { | ||
LOGGER.info("A user with username [{}] for tenant [{}] already exists. Skipping its initialization.", username, | ||
defaultTenant.getId()); | ||
return; | ||
} | ||
User adminUser = snowflakeUserManager.createNewUser(username, defaultTenant.getId()); | ||
LOGGER.info("Created admin user with username [{}] for tenant with id [{}]", adminUser.getUsername(), adminUser.getTenant() | ||
.getId()); | ||
for (Roles predefinedRole : Roles.values()) { | ||
assignRole(adminUser, predefinedRole); | ||
} | ||
} | ||
|
||
/** | ||
* Assign role. | ||
* | ||
* @param user the user | ||
* @param predefinedRole the predefined role | ||
*/ | ||
private void assignRole(User user, Roles predefinedRole) { | ||
UserRoleAssignment assignment = new UserRoleAssignment(); | ||
assignment.setUser(user); | ||
|
||
String roleName = predefinedRole.getRoleName(); | ||
snowflakeUserManager.assignUserRoles(user, roleName); | ||
|
||
LOGGER.info("Assigned role [{}] to user [{}] in tenant [{}]", roleName, user.getUsername(), user.getTenant() | ||
.getId()); | ||
} | ||
|
||
private Optional<String> getSnowflakeAdminUsername() { | ||
String username = DirigibleConfig.SNOWFLAKE_ADMIN_USERNAME.getStringValue(); | ||
if (StringUtils.isBlank(username)) { | ||
LOGGER.warn("Missing snowflake admin username in configuration [{}].", DirigibleConfig.SNOWFLAKE_ADMIN_USERNAME.getKey()); | ||
return Optional.empty(); | ||
} | ||
return Optional.of(username); | ||
} | ||
|
||
} |
Oops, something went wrong.