-
Notifications
You must be signed in to change notification settings - Fork 154
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add a flag to control whether credentials are printed during bootstrapping #461
base: main
Are you sure you want to change the base?
Changes from 2 commits
65c3012
d9a1698
7b1e258
312453b
6e14558
4a3b1fd
ffcdf49
910bb2a
208b8cd
3b32662
a7a4e67
f922055
d0aeeee
fd49022
6ee09b4
fbd11a1
96885d0
df1d642
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
/* | ||
* 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.secrets; | ||
|
||
import static org.assertj.core.api.Assertions.assertThat; | ||
import static org.mockito.Mockito.doReturn; | ||
|
||
import org.apache.polaris.core.entity.PolarisPrincipalSecrets; | ||
import org.jetbrains.annotations.Nullable; | ||
import org.junit.jupiter.api.Assertions; | ||
import org.junit.jupiter.api.Test; | ||
import org.mockito.Mockito; | ||
|
||
class PrincipalSecretsGeneratorTest { | ||
|
||
@Test | ||
void testRandomSecrets() { | ||
RandomPrincipalSecretsGenerator rpsg = new RandomPrincipalSecretsGenerator("realm"); | ||
PolarisPrincipalSecrets s = rpsg.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 testRandomSecretsNullRealm() { | ||
RandomPrincipalSecretsGenerator rpsg = new RandomPrincipalSecretsGenerator(null); | ||
PolarisPrincipalSecrets s = rpsg.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 testEnvVariableSecrets() { | ||
EnvVariablePrincipalSecretsGenerator psg = | ||
Mockito.spy(new EnvVariablePrincipalSecretsGenerator("REALM")); | ||
|
||
String clientIdKey = "POLARIS_BOOTSTRAP_REALM_PRINCIPAL_CLIENT_ID"; | ||
String clientSecretKey = "POLARIS_BOOTSTRAP_REALM_PRINCIPAL_CLIENT_SECRET"; | ||
|
||
doReturn("test-id").when(psg).getEnvironmentVariable(clientIdKey); | ||
doReturn("test-secret").when(psg).getEnvironmentVariable(clientSecretKey); | ||
|
||
// Invoke the method | ||
PolarisPrincipalSecrets secrets = psg.produceSecrets("PRINCIPAL", 123); | ||
|
||
// Verify the result | ||
Assertions.assertNotNull(secrets); | ||
Assertions.assertEquals(123, secrets.getPrincipalId()); | ||
Assertions.assertEquals("test-id", secrets.getPrincipalClientId()); | ||
Assertions.assertEquals("test-secret", secrets.getMainSecret()); | ||
} | ||
|
||
@Test | ||
void testBoostrapGeneratorDelegationToRandomPrincipalSecrets() { | ||
EnvVariablePrincipalSecretsGenerator mockedEnvVariablePrincipalSecretsGenerator = | ||
Mockito.spy(new EnvVariablePrincipalSecretsGenerator("REALM")); | ||
|
||
String clientIdKey = "POLARIS_BOOTSTRAP_REALM_PRINCIPAL_CLIENT_ID"; | ||
String clientSecretKey = "POLARIS_BOOTSTRAP_REALM_PRINCIPAL_CLIENT_SECRET"; | ||
|
||
doReturn("test-id") | ||
.when(mockedEnvVariablePrincipalSecretsGenerator) | ||
.getEnvironmentVariable(clientIdKey); | ||
doReturn("test-secret") | ||
.when(mockedEnvVariablePrincipalSecretsGenerator) | ||
.getEnvironmentVariable(clientSecretKey); | ||
|
||
class ExposingPrincipalSecretsGenerator extends BootstrapPrincipalSecretsGenerator { | ||
public ExposingPrincipalSecretsGenerator(@Nullable String realmName) { | ||
super(realmName); | ||
} | ||
|
||
@Override | ||
protected PrincipalSecretsGenerator buildEnvVariablePrincipalSecretsGenerator( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. same here: I think we could have a simple factory that bind to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In this case what I think we really want is DI 😔 |
||
String realmName) { | ||
return mockedEnvVariablePrincipalSecretsGenerator; | ||
} | ||
|
||
public PrincipalSecretsGenerator seeDelegate(String principalName) { | ||
return this.getDelegate(principalName); | ||
} | ||
} | ||
|
||
ExposingPrincipalSecretsGenerator fallback = new ExposingPrincipalSecretsGenerator(null); | ||
Assertions.assertInstanceOf(RandomPrincipalSecretsGenerator.class, fallback.seeDelegate("p")); | ||
|
||
ExposingPrincipalSecretsGenerator hasVars = new ExposingPrincipalSecretsGenerator("REALM"); | ||
Assertions.assertInstanceOf( | ||
EnvVariablePrincipalSecretsGenerator.class, hasVars.seeDelegate("PRINCIPAL")); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it would be nicer to allow
EnvVariablePrincipalSecretsGenerator
to take an explicitMap
(or aFunction<String, String>
) as a constructor argument. The the "environment" part cab be just a static factory method likeEnvVariablePrincipalSecretsGenerator.fromEnv()
.Testing the static method would not really be necessary because it would be a one-line redirect to
System.env()
, but it would allow for nicer design that is testable withoutMockito
.Just my 2 cents :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like this idea, but my concern is that
EnvVariablePrincipalSecretsGenerator
essentially becomesMapPrincipalSecretsGenerator
with that approach. I would rather not place the burden on its callers to do thefromEnv
/getEnv
; this seems like the exact responsibility we would likeEnvVariablePrincipalSecretsGenerator
to take on.For example: if we later add command-line options to
bootstrap
that allow you to provide credentials, would we use theEnvVariablePrincipalSecretsGenerator
for that? If it takes a map, we could.Taking this further, we could even pass in a map with random secrets to
EnvVariablePrincipalSecretsGenerator
!And so its role, as well as that of
RandomPrincipalSecretsGenerator
, can quickly become quite unclearThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fair enough. I'm fine with the current code in this PR.