Skip to content

Commit

Permalink
credential framework
Browse files Browse the repository at this point in the history
  • Loading branch information
FANNG1 committed Sep 23, 2024
1 parent 5b73abd commit bdf04fa
Show file tree
Hide file tree
Showing 11 changed files with 496 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*
* 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.gravitino.credential;

public class CredentialConstants {
public static final String CREDENTIAL_TYPE = "credential-type";
public static final String EXPIRE_TIME_SECS = "expire-time-secs";

private CredentialConstants() {}
}
1 change: 1 addition & 0 deletions common/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ plugins {

dependencies {
implementation(project(":api"))
implementation(project(":catalogs:catalog-common"))

implementation(libs.commons.collections4)
implementation(libs.commons.lang3)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/*
* 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.gravitino.credential;

import com.google.common.collect.ImmutableMap;
import java.util.Map;

/** Interface representing a credential with type, expiration time, and additional information. */
public interface Credential {

/**
* Returns the type of the credential. It should same with the credential type of the credential
* provider.
*
* @return the credential type as a String.
*/
String getCredentialType();

/**
* Returns the expiration time of the credential in seconds since the epoch.
*
* @return the expiration time as a long.
*/
long getExpireTimeSecs();

/**
* Returns additional information related to the credential.
*
* @return a map of credential information.
*/
Map<String, String> getCredentialInfo();

/**
* Converts the credential to properties to transfer the credential.
*
* @return a map containing credential properties.
*/
default Map<String, String> toProperties() {
return new ImmutableMap.Builder<String, String>()
.putAll(getCredentialInfo())
.put(CredentialConstants.CREDENTIAL_TYPE, getCredentialType())
.put(CredentialConstants.EXPIRE_TIME_SECS, String.valueOf(getExpireTimeSecs()))
.build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*
* 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.gravitino.credential;

import com.google.common.base.Preconditions;
import javax.validation.constraints.NotNull;

/** CatalogContext is generated when user requesting catalog credentials. */
public class CatalogContext implements Context {
@NotNull private final String userName;

public CatalogContext(String userName) {
Preconditions.checkNotNull(userName, "User name should not be null");
this.userName = userName;
}

@Override
public String getUserName() {
return userName;
}
}
30 changes: 30 additions & 0 deletions core/src/main/java/org/apache/gravitino/credential/Context.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
* 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.gravitino.credential;

/** Contains context information to get credential from credential provider. */
public interface Context {
/**
* Providing the username.
*
* @return A string identifying user name.
*/
String getUserName();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/*
* 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.gravitino.credential;

import java.util.Map;
import javax.annotation.Nullable;

/**
* Interface for credential providers.
*
* <p>A credential provider is responsible for managing and retrieving credentials.
*/
public interface CredentialProvider {
/**
* Initializes the credential provider with catalog properties.
*
* @param properties catalog properties that can be used to configure the provider. The specific
* properties required vary by implementation.
*/
void initialize(Map<String, String> properties);

/** Stops the credential provider, performing any necessary cleanup. */
void stop();

/**
* Returns the type of credential, it should be identical in Gravitino.
*
* @return A string identifying the type of credentials.
*/
String credentialType();

/**
* Obtains a credential based on the provided context information.
*
* @param context A context object providing necessary information for retrieving credentials.
* @return A Credential object containing the authentication information needed to access a system
* or resource. Null will be returned if no credential is available.
*/
@Nullable
Credential getCredential(Context context);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/*
* 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.gravitino.credential;

import com.google.common.collect.Iterables;
import com.google.common.collect.Streams;
import java.util.List;
import java.util.Map;
import java.util.ServiceLoader;
import java.util.stream.Collectors;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class CredentialProviderFactory {
private static final Logger LOG = LoggerFactory.getLogger(CredentialProviderFactory.class);

public static CredentialProvider create(
String credentialType, Map<String, String> catalogProperties) {
Class<? extends CredentialProvider> providerClz = lookupCredentialProvider(credentialType);
try {
CredentialProvider provider = providerClz.getDeclaredConstructor().newInstance();
provider.initialize(catalogProperties);
return provider;
} catch (Exception e) {
LOG.warn("Create credential provider failed, {}", credentialType, e);
throw new RuntimeException(e);
}
}

private static Class<? extends CredentialProvider> lookupCredentialProvider(
String credentialType) {
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
ServiceLoader<CredentialProvider> serviceLoader =
ServiceLoader.load(CredentialProvider.class, classLoader);
List<Class<? extends CredentialProvider>> providers =
Streams.stream(serviceLoader.iterator())
.filter(
credentialProvider ->
credentialType.equalsIgnoreCase(credentialProvider.credentialType()))
.map(CredentialProvider::getClass)
.collect(Collectors.toList());

if (providers.isEmpty()) {
throw new IllegalArgumentException("No credential provider found for: " + credentialType);
} else if (providers.size() > 1) {
throw new IllegalArgumentException(
"Multiple credential providers found for: " + credentialType);
} else {
return Iterables.getOnlyElement(providers);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/*
* 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.gravitino.credential;

import com.google.common.base.Preconditions;
import java.util.Set;
import javax.validation.constraints.NotNull;

/**
* LocationContext is generated when user requesting resources associated with storage location like
* table, fileset, etc.
*/
public class LocationContext implements Context {

@NotNull private final Set<String> writeLocations;
@NotNull private final Set<String> readLocations;
@NotNull private final String userName;

public LocationContext(String userName, Set<String> writeLocations, Set<String> readLocations) {
Preconditions.checkNotNull(userName, "User name should not be null");
Preconditions.checkNotNull(writeLocations, "Write locations should not be null");
Preconditions.checkNotNull(readLocations, "Read locations should not be null");
this.userName = userName;
this.writeLocations = writeLocations;
this.readLocations = readLocations;
}

@Override
public String getUserName() {
return userName;
}

public Set<String> getWriteLocations() {
return writeLocations;
}

public Set<String> getReadLocations() {
return readLocations;
}
}
Loading

0 comments on commit bdf04fa

Please sign in to comment.