-
Notifications
You must be signed in to change notification settings - Fork 3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
9 changed files
with
393 additions
and
0 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
========================= | ||
File Based Group Provider | ||
========================= | ||
|
||
Presto can map user names onto groups for easier access control and | ||
resource group management. Group file resolves group membership using | ||
a file on the coordinator. | ||
|
||
Group File Configuration | ||
------------------------ | ||
|
||
Enable group file by creating an ``etc/group-provider.properties`` | ||
file on the coordinator: | ||
|
||
.. code-block:: none | ||
group-provider.name=file | ||
file.group-file=/path/to/group.txt | ||
The following configuration properties are available: | ||
|
||
==================================== ============================================== | ||
Property Description | ||
==================================== ============================================== | ||
``file.group-file`` Path of the group file. | ||
|
||
``file.refresh-period`` How often to reload the group file. | ||
Defaults to ``5s``. | ||
==================================== ============================================== | ||
|
||
Group Files | ||
----------- | ||
|
||
File Format | ||
^^^^^^^^^^^ | ||
|
||
The group file contains a list of groups and members, one per line, | ||
separated by a colon. Users are separated by a comma. | ||
|
||
.. code-block:: none | ||
group_name:user_1,user_2,user_3 |
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
62 changes: 62 additions & 0 deletions
62
...sword-authenticators/src/main/java/io/prestosql/plugin/password/file/FileGroupConfig.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,62 @@ | ||
/* | ||
* Licensed 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 io.prestosql.plugin.password.file; | ||
|
||
import io.airlift.configuration.Config; | ||
import io.airlift.configuration.ConfigDescription; | ||
import io.airlift.configuration.validation.FileExists; | ||
import io.airlift.units.Duration; | ||
import io.airlift.units.MinDuration; | ||
|
||
import javax.validation.constraints.NotNull; | ||
|
||
import java.io.File; | ||
|
||
import static java.util.concurrent.TimeUnit.SECONDS; | ||
|
||
public class FileGroupConfig | ||
{ | ||
private File groupFile; | ||
private Duration refreshPeriod = new Duration(5, SECONDS); | ||
|
||
@NotNull | ||
@FileExists | ||
public File getGroupFile() | ||
{ | ||
return groupFile; | ||
} | ||
|
||
@Config("file.group-file") | ||
@ConfigDescription("Location of the file that provides user group membership") | ||
public FileGroupConfig setGroupFile(File groupFile) | ||
{ | ||
this.groupFile = groupFile; | ||
return this; | ||
} | ||
|
||
@NotNull | ||
@MinDuration("1ms") | ||
public Duration getRefreshPeriod() | ||
{ | ||
return refreshPeriod; | ||
} | ||
|
||
@Config("file.refresh-period") | ||
@ConfigDescription("How often to reload the group file") | ||
public FileGroupConfig setRefreshPeriod(Duration refreshPeriod) | ||
{ | ||
this.refreshPeriod = refreshPeriod; | ||
return this; | ||
} | ||
} |
110 changes: 110 additions & 0 deletions
110
...ord-authenticators/src/main/java/io/prestosql/plugin/password/file/FileGroupProvider.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,110 @@ | ||
/* | ||
* Licensed 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 io.prestosql.plugin.password.file; | ||
|
||
import com.google.common.base.Splitter; | ||
import com.google.common.collect.HashMultimap; | ||
import com.google.common.collect.ImmutableSet; | ||
import com.google.common.collect.Multimap; | ||
import io.prestosql.spi.PrestoException; | ||
import io.prestosql.spi.security.GroupProvider; | ||
|
||
import javax.inject.Inject; | ||
|
||
import java.io.File; | ||
import java.io.IOException; | ||
import java.nio.file.Files; | ||
import java.util.List; | ||
import java.util.Map; | ||
import java.util.Map.Entry; | ||
import java.util.Set; | ||
import java.util.function.Function; | ||
import java.util.function.Supplier; | ||
|
||
import static com.google.common.base.Suppliers.memoizeWithExpiration; | ||
import static com.google.common.collect.ImmutableMap.toImmutableMap; | ||
import static io.prestosql.spi.StandardErrorCode.CONFIGURATION_INVALID; | ||
import static io.prestosql.spi.StandardErrorCode.CONFIGURATION_UNAVAILABLE; | ||
import static java.lang.String.format; | ||
import static java.util.Objects.requireNonNull; | ||
import static java.util.concurrent.TimeUnit.MILLISECONDS; | ||
|
||
public class FileGroupProvider | ||
implements GroupProvider | ||
{ | ||
private static final Splitter LINE_SPLITTER = Splitter.on(":").limit(2).trimResults(); | ||
private static final Splitter GROUP_SPLITTER = Splitter.on(',').trimResults().omitEmptyStrings(); | ||
|
||
private final Supplier<Function<String, Set<String>>> userGroupSupplier; | ||
|
||
@Inject | ||
public FileGroupProvider(FileGroupConfig config) | ||
{ | ||
File file = config.getGroupFile(); | ||
|
||
userGroupSupplier = memoizeWithExpiration( | ||
() -> loadGroupFile(file), | ||
config.getRefreshPeriod().toMillis(), | ||
MILLISECONDS); | ||
} | ||
|
||
@Override | ||
public Set<String> getGroups(String user) | ||
{ | ||
requireNonNull(user, "user is null"); | ||
return userGroupSupplier.get().apply(user); | ||
} | ||
|
||
private static Function<String, Set<String>> loadGroupFile(File file) | ||
{ | ||
Map<String, Set<String>> groups = loadGroupFile(readGroupFile(file)); | ||
return user -> groups.getOrDefault(user, ImmutableSet.of()); | ||
} | ||
|
||
private static Map<String, Set<String>> loadGroupFile(List<String> lines) | ||
{ | ||
Multimap<String, String> userGroups = HashMultimap.create(); | ||
for (int lineNumber = 1; lineNumber <= lines.size(); lineNumber++) { | ||
String line = lines.get(lineNumber - 1).trim(); | ||
if (line.isEmpty() || line.startsWith("#")) { | ||
continue; | ||
} | ||
|
||
List<String> parts = LINE_SPLITTER.splitToList(line); | ||
if (parts.size() != 2) { | ||
throw invalidFile(lineNumber, "Expected two parts for group and users", null); | ||
} | ||
String group = parts.get(0); | ||
GROUP_SPLITTER.splitToStream(parts.get(1)) | ||
.forEach(user -> userGroups.put(user, group)); | ||
} | ||
return userGroups.asMap().entrySet().stream() | ||
.collect(toImmutableMap(Entry::getKey, entry -> ImmutableSet.copyOf(entry.getValue()))); | ||
} | ||
|
||
private static RuntimeException invalidFile(int lineNumber, String message, Throwable cause) | ||
{ | ||
return new PrestoException(CONFIGURATION_INVALID, format("Error in group file line %s: %s", lineNumber, message), cause); | ||
} | ||
|
||
private static List<String> readGroupFile(File file) | ||
{ | ||
try { | ||
return Files.readAllLines(file.toPath()); | ||
} | ||
catch (IOException e) { | ||
throw new PrestoException(CONFIGURATION_UNAVAILABLE, "Failed to read group file: " + file, e); | ||
} | ||
} | ||
} |
52 changes: 52 additions & 0 deletions
52
...henticators/src/main/java/io/prestosql/plugin/password/file/FileGroupProviderFactory.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,52 @@ | ||
/* | ||
* Licensed 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 io.prestosql.plugin.password.file; | ||
|
||
import com.google.inject.Injector; | ||
import com.google.inject.Scopes; | ||
import io.airlift.bootstrap.Bootstrap; | ||
import io.prestosql.spi.security.GroupProvider; | ||
import io.prestosql.spi.security.GroupProviderFactory; | ||
|
||
import java.util.Map; | ||
|
||
import static io.airlift.configuration.ConfigBinder.configBinder; | ||
|
||
public class FileGroupProviderFactory | ||
implements GroupProviderFactory | ||
{ | ||
@Override | ||
public String getName() | ||
{ | ||
return "file"; | ||
} | ||
|
||
@Override | ||
public GroupProvider create(Map<String, String> config) | ||
{ | ||
Bootstrap app = new Bootstrap( | ||
binder -> { | ||
configBinder(binder).bindConfig(FileGroupConfig.class); | ||
binder.bind(FileGroupProvider.class).in(Scopes.SINGLETON); | ||
}); | ||
|
||
Injector injector = app | ||
.strictConfig() | ||
.doNotInitializeLogging() | ||
.setRequiredConfigurationProperties(config) | ||
.initialize(); | ||
|
||
return injector.getInstance(FileGroupProvider.class); | ||
} | ||
} |
58 changes: 58 additions & 0 deletions
58
...d-authenticators/src/test/java/io/prestosql/plugin/password/file/TestFileGroupConfig.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,58 @@ | ||
|
||
/* | ||
* Licensed 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 io.prestosql.plugin.password.file; | ||
|
||
import com.google.common.collect.ImmutableMap; | ||
import io.airlift.units.Duration; | ||
import org.testng.annotations.Test; | ||
|
||
import java.io.IOException; | ||
import java.nio.file.Files; | ||
import java.nio.file.Path; | ||
import java.util.Map; | ||
|
||
import static io.airlift.configuration.testing.ConfigAssertions.assertFullMapping; | ||
import static io.airlift.configuration.testing.ConfigAssertions.assertRecordedDefaults; | ||
import static io.airlift.configuration.testing.ConfigAssertions.recordDefaults; | ||
import static java.util.concurrent.TimeUnit.SECONDS; | ||
|
||
public class TestFileGroupConfig | ||
{ | ||
@Test | ||
public void testDefault() | ||
{ | ||
assertRecordedDefaults(recordDefaults(FileGroupConfig.class) | ||
.setGroupFile(null) | ||
.setRefreshPeriod(new Duration(5, SECONDS))); | ||
} | ||
|
||
@Test | ||
public void testExplicitConfig() | ||
throws IOException | ||
{ | ||
Path groupFile = Files.createTempFile(null, null); | ||
|
||
Map<String, String> properties = new ImmutableMap.Builder<String, String>() | ||
.put("file.group-file", groupFile.toString()) | ||
.put("file.refresh-period", "42s") | ||
.build(); | ||
|
||
FileGroupConfig expected = new FileGroupConfig() | ||
.setGroupFile(groupFile.toFile()) | ||
.setRefreshPeriod(new Duration(42, SECONDS)); | ||
|
||
assertFullMapping(properties, expected); | ||
} | ||
} |
Oops, something went wrong.