mirror of
https://github.com/open-metadata/OpenMetadata.git
synced 2025-07-12 19:48:26 +00:00
[OMOperations] Add Reset Password option (#19253)
* Add Reset Password option * Add Email option * Add option to set initial password in yaml
This commit is contained in:
parent
26bfde8f9c
commit
dba3e58e4c
@ -4,7 +4,9 @@ import static org.flywaydb.core.internal.info.MigrationInfoDumper.dumpToAsciiTab
|
|||||||
import static org.openmetadata.common.utils.CommonUtil.nullOrEmpty;
|
import static org.openmetadata.common.utils.CommonUtil.nullOrEmpty;
|
||||||
import static org.openmetadata.service.Entity.FIELD_OWNERS;
|
import static org.openmetadata.service.Entity.FIELD_OWNERS;
|
||||||
import static org.openmetadata.service.formatter.decorators.MessageDecorator.getDateStringEpochMilli;
|
import static org.openmetadata.service.formatter.decorators.MessageDecorator.getDateStringEpochMilli;
|
||||||
|
import static org.openmetadata.service.jdbi3.UserRepository.AUTH_MECHANISM_FIELD;
|
||||||
import static org.openmetadata.service.util.AsciiTable.printOpenMetadataText;
|
import static org.openmetadata.service.util.AsciiTable.printOpenMetadataText;
|
||||||
|
import static org.openmetadata.service.util.UserUtil.updateUserWithHashedPwd;
|
||||||
|
|
||||||
import ch.qos.logback.classic.Level;
|
import ch.qos.logback.classic.Level;
|
||||||
import ch.qos.logback.classic.Logger;
|
import ch.qos.logback.classic.Logger;
|
||||||
@ -23,6 +25,7 @@ import java.io.File;
|
|||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.LinkedHashSet;
|
import java.util.LinkedHashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@ -41,6 +44,8 @@ import org.openmetadata.schema.ServiceEntityInterface;
|
|||||||
import org.openmetadata.schema.entity.app.App;
|
import org.openmetadata.schema.entity.app.App;
|
||||||
import org.openmetadata.schema.entity.app.AppRunRecord;
|
import org.openmetadata.schema.entity.app.AppRunRecord;
|
||||||
import org.openmetadata.schema.entity.services.ingestionPipelines.IngestionPipeline;
|
import org.openmetadata.schema.entity.services.ingestionPipelines.IngestionPipeline;
|
||||||
|
import org.openmetadata.schema.entity.teams.User;
|
||||||
|
import org.openmetadata.schema.services.connections.metadata.AuthProvider;
|
||||||
import org.openmetadata.schema.settings.Settings;
|
import org.openmetadata.schema.settings.Settings;
|
||||||
import org.openmetadata.schema.settings.SettingsType;
|
import org.openmetadata.schema.settings.SettingsType;
|
||||||
import org.openmetadata.schema.system.EventPublisherJob;
|
import org.openmetadata.schema.system.EventPublisherJob;
|
||||||
@ -60,6 +65,7 @@ import org.openmetadata.service.jdbi3.IngestionPipelineRepository;
|
|||||||
import org.openmetadata.service.jdbi3.ListFilter;
|
import org.openmetadata.service.jdbi3.ListFilter;
|
||||||
import org.openmetadata.service.jdbi3.MigrationDAO;
|
import org.openmetadata.service.jdbi3.MigrationDAO;
|
||||||
import org.openmetadata.service.jdbi3.SystemRepository;
|
import org.openmetadata.service.jdbi3.SystemRepository;
|
||||||
|
import org.openmetadata.service.jdbi3.UserRepository;
|
||||||
import org.openmetadata.service.jdbi3.locator.ConnectionType;
|
import org.openmetadata.service.jdbi3.locator.ConnectionType;
|
||||||
import org.openmetadata.service.migration.api.MigrationWorkflow;
|
import org.openmetadata.service.migration.api.MigrationWorkflow;
|
||||||
import org.openmetadata.service.resources.CollectionRegistry;
|
import org.openmetadata.service.resources.CollectionRegistry;
|
||||||
@ -166,13 +172,12 @@ public class OpenMetadataOperations implements Callable<Integer> {
|
|||||||
public Integer syncEmailFromEnv() {
|
public Integer syncEmailFromEnv() {
|
||||||
try {
|
try {
|
||||||
parseConfig();
|
parseConfig();
|
||||||
Entity.setCollectionDAO(jdbi.onDemand(CollectionDAO.class));
|
|
||||||
SystemRepository systemRepository = new SystemRepository();
|
|
||||||
Settings updatedSettings =
|
Settings updatedSettings =
|
||||||
new Settings()
|
new Settings()
|
||||||
.withConfigType(SettingsType.EMAIL_CONFIGURATION)
|
.withConfigType(SettingsType.EMAIL_CONFIGURATION)
|
||||||
.withConfigValue(config.getSmtpSettings());
|
.withConfigValue(config.getSmtpSettings());
|
||||||
systemRepository.createOrUpdate(updatedSettings);
|
Entity.getSystemRepository().createOrUpdate(updatedSettings);
|
||||||
|
LOG.info("Synced Email Configuration from Environment.");
|
||||||
return 0;
|
return 0;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
LOG.error("Email Sync failed due to ", e);
|
LOG.error("Email Sync failed due to ", e);
|
||||||
@ -221,6 +226,58 @@ public class OpenMetadataOperations implements Callable<Integer> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Command(name = "reset-password", description = "Reset the password for a user.")
|
||||||
|
public Integer resetUserPassword(
|
||||||
|
@Option(
|
||||||
|
names = {"-e", "--email"},
|
||||||
|
description = "Email for which to reset the password.",
|
||||||
|
required = true)
|
||||||
|
String email,
|
||||||
|
@Option(
|
||||||
|
names = {"-p", "--password"},
|
||||||
|
description = "Enter user password",
|
||||||
|
arity = "0..1",
|
||||||
|
interactive = true,
|
||||||
|
required = true)
|
||||||
|
char[] password) {
|
||||||
|
try {
|
||||||
|
LOG.info("Resetting password for user : {}", email);
|
||||||
|
if (nullOrEmpty(password)) {
|
||||||
|
throw new IllegalArgumentException("Password cannot be empty.");
|
||||||
|
}
|
||||||
|
parseConfig();
|
||||||
|
CollectionRegistry.initialize();
|
||||||
|
AuthProvider authProvider = config.getAuthenticationConfiguration().getProvider();
|
||||||
|
|
||||||
|
// Only Basic Auth provider is supported for password reset
|
||||||
|
if (!authProvider.equals(AuthProvider.BASIC)) {
|
||||||
|
LOG.error("Auth Provider is Not Basic. Cannot apply Password");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
UserRepository userRepository = (UserRepository) Entity.getEntityRepository(Entity.USER);
|
||||||
|
Set<String> fieldList = new HashSet<>(userRepository.getPatchFields().getFieldList());
|
||||||
|
fieldList.add(AUTH_MECHANISM_FIELD);
|
||||||
|
User originalUser = userRepository.getByEmail(null, email, new EntityUtil.Fields(fieldList));
|
||||||
|
|
||||||
|
// Check if the user is a bot user
|
||||||
|
if (Boolean.TRUE.equals(originalUser.getIsBot())) {
|
||||||
|
LOG.error("Bot user : {} cannot have password.", originalUser.getName());
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
User updatedUser = JsonUtils.deepCopy(originalUser, User.class);
|
||||||
|
String inputPwd = new String(password);
|
||||||
|
updateUserWithHashedPwd(updatedUser, inputPwd);
|
||||||
|
UserUtil.addOrUpdateUser(updatedUser);
|
||||||
|
LOG.info("Password updated successfully.");
|
||||||
|
return 0;
|
||||||
|
} catch (Exception e) {
|
||||||
|
LOG.error("Failed to reset user password.", e);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Command(
|
@Command(
|
||||||
name = "migrate",
|
name = "migrate",
|
||||||
description = "Migrates the OpenMetadata database schema and search index mappings.")
|
description = "Migrates the OpenMetadata database schema and search index mappings.")
|
||||||
@ -652,6 +709,7 @@ public class OpenMetadataOperations implements Callable<Integer> {
|
|||||||
collectionDAO = jdbi.onDemand(CollectionDAO.class);
|
collectionDAO = jdbi.onDemand(CollectionDAO.class);
|
||||||
Entity.setSearchRepository(searchRepository);
|
Entity.setSearchRepository(searchRepository);
|
||||||
Entity.setCollectionDAO(collectionDAO);
|
Entity.setCollectionDAO(collectionDAO);
|
||||||
|
Entity.setSystemRepository(new SystemRepository());
|
||||||
Entity.initializeRepositories(config, jdbi);
|
Entity.initializeRepositories(config, jdbi);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,6 +19,7 @@ import static org.openmetadata.schema.entity.teams.AuthenticationMechanism.AuthT
|
|||||||
import static org.openmetadata.schema.type.Include.NON_DELETED;
|
import static org.openmetadata.schema.type.Include.NON_DELETED;
|
||||||
import static org.openmetadata.service.Entity.ADMIN_ROLE;
|
import static org.openmetadata.service.Entity.ADMIN_ROLE;
|
||||||
import static org.openmetadata.service.Entity.ADMIN_USER_NAME;
|
import static org.openmetadata.service.Entity.ADMIN_USER_NAME;
|
||||||
|
import static org.openmetadata.service.jdbi3.UserRepository.AUTH_MECHANISM_FIELD;
|
||||||
|
|
||||||
import at.favre.lib.crypto.bcrypt.BCrypt;
|
import at.favre.lib.crypto.bcrypt.BCrypt;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@ -62,8 +63,18 @@ public final class UserUtil {
|
|||||||
public static void addUsers(
|
public static void addUsers(
|
||||||
AuthProvider authProvider, Set<String> adminUsers, String domain, Boolean isAdmin) {
|
AuthProvider authProvider, Set<String> adminUsers, String domain, Boolean isAdmin) {
|
||||||
try {
|
try {
|
||||||
for (String username : adminUsers) {
|
for (String keyValue : adminUsers) {
|
||||||
createOrUpdateUser(authProvider, username, domain, isAdmin);
|
String userName = "";
|
||||||
|
String password = "";
|
||||||
|
if (keyValue.contains(":")) {
|
||||||
|
String[] keyValueArray = keyValue.split(":");
|
||||||
|
userName = keyValueArray[0];
|
||||||
|
password = keyValueArray[1];
|
||||||
|
} else {
|
||||||
|
userName = keyValue;
|
||||||
|
password = getPassword(userName);
|
||||||
|
}
|
||||||
|
createOrUpdateUser(authProvider, userName, password, domain, isAdmin);
|
||||||
}
|
}
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
LOG.error("[BootstrapUser] Encountered Exception while bootstrapping admin user", ex);
|
LOG.error("[BootstrapUser] Encountered Exception while bootstrapping admin user", ex);
|
||||||
@ -71,27 +82,26 @@ public final class UserUtil {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static void createOrUpdateUser(
|
private static void createOrUpdateUser(
|
||||||
AuthProvider authProvider, String username, String domain, Boolean isAdmin) {
|
AuthProvider authProvider, String username, String password, String domain, Boolean isAdmin) {
|
||||||
UserRepository userRepository = (UserRepository) Entity.getEntityRepository(Entity.USER);
|
UserRepository userRepository = (UserRepository) Entity.getEntityRepository(Entity.USER);
|
||||||
User updatedUser = null;
|
User updatedUser = null;
|
||||||
try {
|
try {
|
||||||
// Create Required Fields List
|
// Create Required Fields List
|
||||||
Set<String> fieldList = new HashSet<>(userRepository.getPatchFields().getFieldList());
|
Set<String> fieldList = new HashSet<>(userRepository.getPatchFields().getFieldList());
|
||||||
fieldList.add("authenticationMechanism");
|
fieldList.add(AUTH_MECHANISM_FIELD);
|
||||||
|
|
||||||
// Fetch Original User, is available
|
// Fetch Original User, is available
|
||||||
User originalUser = userRepository.getByName(null, username, new Fields(fieldList));
|
User originalUser = userRepository.getByName(null, username, new Fields(fieldList));
|
||||||
if (Boolean.FALSE.equals(originalUser.getIsBot())
|
if (Boolean.FALSE.equals(originalUser.getIsBot())
|
||||||
&& Boolean.FALSE.equals(originalUser.getIsAdmin())) {
|
&& Boolean.TRUE.equals(originalUser.getIsAdmin())) {
|
||||||
updatedUser = originalUser;
|
updatedUser = originalUser;
|
||||||
|
|
||||||
// Update Auth Mechanism if not present, and send mail to the user
|
// Update Auth Mechanism if not present, and send mail to the user
|
||||||
if (authProvider.equals(AuthProvider.BASIC)) {
|
if (authProvider.equals(AuthProvider.BASIC)) {
|
||||||
if (originalUser.getAuthenticationMechanism() == null
|
if (originalUser.getAuthenticationMechanism() == null
|
||||||
|| originalUser.getAuthenticationMechanism().equals(new AuthenticationMechanism())) {
|
|| originalUser.getAuthenticationMechanism().equals(new AuthenticationMechanism())) {
|
||||||
String randomPwd = getPassword(username);
|
updateUserWithHashedPwd(updatedUser, password);
|
||||||
updateUserWithHashedPwd(updatedUser, randomPwd);
|
EmailUtil.sendInviteMailToAdmin(updatedUser, password);
|
||||||
EmailUtil.sendInviteMailToAdmin(updatedUser, randomPwd);
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
updatedUser.setAuthenticationMechanism(new AuthenticationMechanism());
|
updatedUser.setAuthenticationMechanism(new AuthenticationMechanism());
|
||||||
@ -114,9 +124,8 @@ public final class UserUtil {
|
|||||||
updatedUser = user(username, domain, username).withIsAdmin(isAdmin).withIsEmailVerified(true);
|
updatedUser = user(username, domain, username).withIsAdmin(isAdmin).withIsEmailVerified(true);
|
||||||
// Update Auth Mechanism if not present, and send mail to the user
|
// Update Auth Mechanism if not present, and send mail to the user
|
||||||
if (authProvider.equals(AuthProvider.BASIC)) {
|
if (authProvider.equals(AuthProvider.BASIC)) {
|
||||||
String randomPwd = getPassword(username);
|
updateUserWithHashedPwd(updatedUser, password);
|
||||||
updateUserWithHashedPwd(updatedUser, randomPwd);
|
EmailUtil.sendInviteMailToAdmin(updatedUser, password);
|
||||||
EmailUtil.sendInviteMailToAdmin(updatedUser, randomPwd);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user