Skip to content

Commit

Permalink
review: accept initial secrets via env. in the bootstrap command
Browse files Browse the repository at this point in the history
  • Loading branch information
dimas-b committed Nov 8, 2024
1 parent f106ec0 commit 3d5640f
Show file tree
Hide file tree
Showing 4 changed files with 95 additions and 37 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
*/
package org.apache.polaris.core.persistence;

import java.util.Locale;
import java.util.function.Function;
import org.apache.polaris.core.entity.PolarisPrincipalSecrets;
import org.jetbrains.annotations.NotNull;

Expand All @@ -27,4 +29,22 @@ public interface PrincipalSecretsGenerator {
PrincipalSecretsGenerator RANDOM_SECRETS = (name, id) -> new PolarisPrincipalSecrets(id);

PolarisPrincipalSecrets produceSecrets(@NotNull String principalName, long principalId);

static Function<String, PrincipalSecretsGenerator> bootstrap(Function<String, String> config) {
return (realmName) ->
(principalName, principalId) -> {
String propId =
String.format("POLARIS_BOOTSTRAP_%s_%s_CLIENT_ID", realmName, principalName);
String propSecret =
String.format("POLARIS_BOOTSTRAP_%s_%s_CLIENT_SECRET", realmName, principalName);
String clientId = config.apply(propId.toUpperCase(Locale.ROOT));
String secret = config.apply(propSecret.toUpperCase(Locale.ROOT));
if (clientId == null || secret == null) {
return new PolarisPrincipalSecrets(principalId); // random secrets
} else {
// Use the same secondary secret for bootstrapping. It can be rotated later, if required
return new PolarisPrincipalSecrets(principalId, clientId, secret, secret);
}
};
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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 org.apache.polaris.core.persistence;

import static org.apache.polaris.core.persistence.PrincipalSecretsGenerator.bootstrap;
import static org.assertj.core.api.Assertions.assertThat;

import java.util.Map;
import org.apache.polaris.core.entity.PolarisPrincipalSecrets;
import org.junit.jupiter.api.Test;

class PrincipalSecretsGeneratorTest {

@Test
void testRandomSecrets() {
PolarisPrincipalSecrets s =
bootstrap((name) -> null).apply("test").produceSecrets("name1", 123);
assertThat(s).isNotNull();
assertThat(s.getPrincipalId()).isEqualTo(123);
assertThat(s.getPrincipalClientId()).isNotNull();
assertThat(s.getMainSecret()).isNotNull();
assertThat(s.getSecondarySecret()).isNotNull();
}

@Test
void testSecretOverride() {
PolarisPrincipalSecrets s =
bootstrap(
Map.of(
"POLARIS_BOOTSTRAP_TEST-REALM_USER1_CLIENT_ID",
"client1",
"POLARIS_BOOTSTRAP_TEST-REALM_USER1_CLIENT_SECRET",
"sec2")
::get)
.apply("test-Realm")
.produceSecrets("user1", 123);
assertThat(s).isNotNull();
assertThat(s.getPrincipalId()).isEqualTo(123);
assertThat(s.getPrincipalClientId()).isEqualTo("client1");
assertThat(s.getMainSecret()).isEqualTo("sec2");
assertThat(s.getSecondarySecret()).isEqualTo("sec2");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,14 @@
*/
package org.apache.polaris.service;

import static org.apache.polaris.core.persistence.PrincipalSecretsGenerator.RANDOM_SECRETS;

import io.dropwizard.core.cli.ConfiguredCommand;
import io.dropwizard.core.setup.Bootstrap;
import java.util.Map;
import net.sourceforge.argparse4j.inf.Namespace;
import org.apache.polaris.core.PolarisConfigurationStore;
import org.apache.polaris.core.persistence.MetaStoreManagerFactory;
import org.apache.polaris.core.persistence.PolarisMetaStoreManager;
import org.apache.polaris.core.persistence.PrincipalSecretsGenerator;
import org.apache.polaris.service.config.ConfigurationStoreAware;
import org.apache.polaris.service.config.PolarisApplicationConfig;
import org.apache.polaris.service.context.CallContextResolver;
Expand Down Expand Up @@ -65,7 +64,8 @@ protected void run(
// Execute the bootstrap
Map<String, PolarisMetaStoreManager.PrincipalSecretsResult> results =
metaStoreManagerFactory.bootstrapRealms(
configuration.getDefaultRealms(), name -> RANDOM_SECRETS);
configuration.getDefaultRealms(),
PrincipalSecretsGenerator.bootstrap(System.getenv()::get));

// Log any errors:
boolean success = true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,19 +18,14 @@
*/
package org.apache.polaris.service.persistence;

import static org.apache.polaris.core.persistence.PrincipalSecretsGenerator.RANDOM_SECRETS;

import com.fasterxml.jackson.annotation.JsonTypeName;
import java.util.Collections;
import java.util.HashSet;
import java.util.Map;
import java.util.Random;
import java.util.Set;
import java.util.function.Function;
import java.util.function.Supplier;
import org.apache.polaris.core.PolarisDiagnostics;
import org.apache.polaris.core.context.RealmContext;
import org.apache.polaris.core.entity.PolarisPrincipalSecrets;
import org.apache.polaris.core.persistence.LocalPolarisMetaStoreManagerFactory;
import org.apache.polaris.core.persistence.PolarisMetaStoreManager;
import org.apache.polaris.core.persistence.PolarisMetaStoreSession;
Expand Down Expand Up @@ -76,36 +71,20 @@ public synchronized Supplier<PolarisMetaStoreSession> getOrCreateSessionSupplier
}

private void bootstrapRealmAndPrintCredentials(String realmId) {
Function<String, PrincipalSecretsGenerator> rootSecrets =
realm -> {
Random r = new Random(); // does not have to be secure in this case
return (name, id) -> {
// Allow env-based root ID definition for testing
String rootClientId = System.getenv("POLARIS_UNSAFE_BOOTSTRAP_ROOT_CLIENT_ID");
PolarisPrincipalSecrets secrets;
if (rootClientId == null) {
secrets = RANDOM_SECRETS.produceSecrets(name, id);
} else {
secrets =
new PolarisPrincipalSecrets(
id,
rootClientId,
Long.toHexString(r.nextLong()),
Long.toHexString(r.nextLong()));
}

String msg =
String.format(
"realm: %1s root principal credentials: %2s:%3s",
realm, secrets.getPrincipalClientId(), secrets.getMainSecret());
System.out.println(msg);

return secrets;
};
};

Map<String, PolarisMetaStoreManager.PrincipalSecretsResult> results =
this.bootstrapRealms(Collections.singletonList(realmId), rootSecrets);
this.bootstrapRealms(
Collections.singletonList(realmId),
PrincipalSecretsGenerator.bootstrap(System.getenv()::get));
bootstrappedRealms.add(realmId);

PolarisMetaStoreManager.PrincipalSecretsResult principalSecrets = results.get(realmId);

String msg =
String.format(
"realm: %1s root principal credentials: %2s:%3s",
realmId,
principalSecrets.getPrincipalSecrets().getPrincipalClientId(),
principalSecrets.getPrincipalSecrets().getMainSecret());
System.out.println(msg);
}
}

0 comments on commit 3d5640f

Please sign in to comment.