use of io.trino.transaction.TransactionId in project trino by trinodb.
the class TestAccessControlManager method testReadOnlySystemAccessControl.
@Test
public void testReadOnlySystemAccessControl() {
Identity identity = Identity.forUser(USER_NAME).withPrincipal(PRINCIPAL).build();
QualifiedObjectName tableName = new QualifiedObjectName("catalog", "schema", "table");
TransactionManager transactionManager = createTestTransactionManager();
AccessControlManager accessControlManager = createAccessControlManager(transactionManager);
accessControlManager.setSystemAccessControl(ReadOnlySystemAccessControl.NAME, ImmutableMap.of());
accessControlManager.checkCanSetUser(Optional.of(PRINCIPAL), USER_NAME);
accessControlManager.checkCanSetSystemSessionProperty(identity, "property");
transaction(transactionManager, accessControlManager).execute(transactionId -> {
SecurityContext context = new SecurityContext(transactionId, identity, queryId);
accessControlManager.checkCanSetCatalogSessionProperty(context, "catalog", "property");
accessControlManager.checkCanShowSchemas(context, "catalog");
accessControlManager.checkCanShowTables(context, new CatalogSchemaName("catalog", "schema"));
accessControlManager.checkCanSelectFromColumns(context, tableName, ImmutableSet.of("column"));
accessControlManager.checkCanCreateViewWithSelectFromColumns(context, tableName, ImmutableSet.of("column"));
accessControlManager.checkCanGrantExecuteFunctionPrivilege(context, "function", Identity.ofUser("bob"), false);
accessControlManager.checkCanGrantExecuteFunctionPrivilege(context, "function", Identity.ofUser("bob"), true);
Set<String> catalogs = ImmutableSet.of("catalog");
assertEquals(accessControlManager.filterCatalogs(context, catalogs), catalogs);
Set<String> schemas = ImmutableSet.of("schema");
assertEquals(accessControlManager.filterSchemas(context, "catalog", schemas), schemas);
Set<SchemaTableName> tableNames = ImmutableSet.of(new SchemaTableName("schema", "table"));
assertEquals(accessControlManager.filterTables(context, "catalog", tableNames), tableNames);
});
assertThatThrownBy(() -> transaction(transactionManager, accessControlManager).execute(transactionId -> {
accessControlManager.checkCanInsertIntoTable(new SecurityContext(transactionId, identity, queryId), tableName);
})).isInstanceOf(AccessDeniedException.class).hasMessage("Access Denied: Cannot insert into table catalog.schema.table");
}
use of io.trino.transaction.TransactionId in project trino by trinodb.
the class TestAccessControlManager method testDenySystemAccessControl.
@Test
public void testDenySystemAccessControl() {
try (LocalQueryRunner queryRunner = LocalQueryRunner.create(TEST_SESSION)) {
TransactionManager transactionManager = queryRunner.getTransactionManager();
AccessControlManager accessControlManager = createAccessControlManager(transactionManager);
TestSystemAccessControlFactory accessControlFactory = new TestSystemAccessControlFactory("test");
accessControlManager.addSystemAccessControlFactory(accessControlFactory);
accessControlManager.setSystemAccessControl("test", ImmutableMap.of());
queryRunner.createCatalog("catalog", MockConnectorFactory.create(), ImmutableMap.of());
accessControlManager.addCatalogAccessControl(new CatalogName("connector"), new DenyConnectorAccessControl());
assertThatThrownBy(() -> transaction(transactionManager, accessControlManager).execute(transactionId -> {
accessControlManager.checkCanSelectFromColumns(context(transactionId), new QualifiedObjectName("secured_catalog", "schema", "table"), ImmutableSet.of("column"));
})).isInstanceOf(TrinoException.class).hasMessageMatching("Access Denied: Cannot select from table secured_catalog.schema.table");
}
}
use of io.trino.transaction.TransactionId in project trino by trinodb.
the class HttpRequestSessionContextFactory method createSessionContext.
public SessionContext createSessionContext(MultivaluedMap<String, String> headers, Optional<String> alternateHeaderName, Optional<String> remoteAddress, Optional<Identity> authenticatedIdentity) throws WebApplicationException {
ProtocolHeaders protocolHeaders;
try {
protocolHeaders = detectProtocol(alternateHeaderName, headers.keySet());
} catch (ProtocolDetectionException e) {
throw badRequest(e.getMessage());
}
Optional<String> catalog = Optional.ofNullable(trimEmptyToNull(headers.getFirst(protocolHeaders.requestCatalog())));
Optional<String> schema = Optional.ofNullable(trimEmptyToNull(headers.getFirst(protocolHeaders.requestSchema())));
Optional<String> path = Optional.ofNullable(trimEmptyToNull(headers.getFirst(protocolHeaders.requestPath())));
assertRequest((catalog.isPresent()) || (schema.isEmpty()), "Schema is set but catalog is not");
requireNonNull(authenticatedIdentity, "authenticatedIdentity is null");
Identity identity = buildSessionIdentity(authenticatedIdentity, protocolHeaders, headers);
SelectedRole selectedRole = parseSystemRoleHeaders(protocolHeaders, headers);
Optional<String> source = Optional.ofNullable(headers.getFirst(protocolHeaders.requestSource()));
Optional<String> traceToken = Optional.ofNullable(trimEmptyToNull(headers.getFirst(protocolHeaders.requestTraceToken())));
Optional<String> userAgent = Optional.ofNullable(headers.getFirst(USER_AGENT));
Optional<String> remoteUserAddress = requireNonNull(remoteAddress, "remoteAddress is null");
Optional<String> timeZoneId = Optional.ofNullable(headers.getFirst(protocolHeaders.requestTimeZone()));
Optional<String> language = Optional.ofNullable(headers.getFirst(protocolHeaders.requestLanguage()));
Optional<String> clientInfo = Optional.ofNullable(headers.getFirst(protocolHeaders.requestClientInfo()));
Set<String> clientTags = parseClientTags(protocolHeaders, headers);
Set<String> clientCapabilities = parseClientCapabilities(protocolHeaders, headers);
ResourceEstimates resourceEstimates = parseResourceEstimate(protocolHeaders, headers);
// parse session properties
ImmutableMap.Builder<String, String> systemProperties = ImmutableMap.builder();
Map<String, Map<String, String>> catalogSessionProperties = new HashMap<>();
for (Entry<String, String> entry : parseSessionHeaders(protocolHeaders, headers).entrySet()) {
String fullPropertyName = entry.getKey();
String propertyValue = entry.getValue();
List<String> nameParts = DOT_SPLITTER.splitToList(fullPropertyName);
if (nameParts.size() == 1) {
String propertyName = nameParts.get(0);
assertRequest(!propertyName.isEmpty(), "Invalid %s header", protocolHeaders.requestSession());
// catalog session properties cannot be validated until the transaction has stated, so we delay system property validation also
systemProperties.put(propertyName, propertyValue);
} else if (nameParts.size() == 2) {
String catalogName = nameParts.get(0);
String propertyName = nameParts.get(1);
assertRequest(!catalogName.isEmpty(), "Invalid %s header", protocolHeaders.requestSession());
assertRequest(!propertyName.isEmpty(), "Invalid %s header", protocolHeaders.requestSession());
// catalog session properties cannot be validated until the transaction has stated
catalogSessionProperties.computeIfAbsent(catalogName, id -> new HashMap<>()).put(propertyName, propertyValue);
} else {
throw badRequest(format("Invalid %s header", protocolHeaders.requestSession()));
}
}
requireNonNull(catalogSessionProperties, "catalogSessionProperties is null");
catalogSessionProperties = catalogSessionProperties.entrySet().stream().collect(toImmutableMap(Entry::getKey, entry -> ImmutableMap.copyOf(entry.getValue())));
Map<String, String> preparedStatements = parsePreparedStatementsHeaders(protocolHeaders, headers);
String transactionIdHeader = headers.getFirst(protocolHeaders.requestTransactionId());
boolean clientTransactionSupport = transactionIdHeader != null;
Optional<TransactionId> transactionId = parseTransactionId(transactionIdHeader);
return new SessionContext(protocolHeaders, catalog, schema, path, authenticatedIdentity, identity, selectedRole, source, traceToken, userAgent, remoteUserAddress, timeZoneId, language, clientTags, clientCapabilities, resourceEstimates, systemProperties.buildOrThrow(), catalogSessionProperties, preparedStatements, transactionId, clientTransactionSupport, clientInfo);
}
use of io.trino.transaction.TransactionId in project trino by trinodb.
the class TestInformationSchemaMetadata method testInformationSchemaPredicatePushdownWithConstraintPredicate.
@Test
public void testInformationSchemaPredicatePushdownWithConstraintPredicate() {
TransactionId transactionId = transactionManager.beginTransaction(false);
Constraint constraint = new Constraint(TupleDomain.all(), TestInformationSchemaMetadata::testConstraint, testConstraintColumns());
ConnectorSession session = createNewSession(transactionId);
ConnectorMetadata metadata = new InformationSchemaMetadata("test_catalog", this.metadata);
InformationSchemaTableHandle tableHandle = (InformationSchemaTableHandle) metadata.getTableHandle(session, new SchemaTableName("information_schema", "columns"));
tableHandle = metadata.applyFilter(session, tableHandle, constraint).map(ConstraintApplicationResult::getHandle).map(InformationSchemaTableHandle.class::cast).orElseThrow(AssertionError::new);
assertEquals(tableHandle.getPrefixes(), ImmutableSet.of(new QualifiedTablePrefix("test_catalog", "test_schema", "test_view")));
}
use of io.trino.transaction.TransactionId in project trino by trinodb.
the class TestInformationSchemaMetadata method testInformationSchemaPredicatePushdownForEmptyNames.
@Test
public void testInformationSchemaPredicatePushdownForEmptyNames() {
TransactionId transactionId = transactionManager.beginTransaction(false);
ConnectorSession session = createNewSession(transactionId);
ConnectorMetadata metadata = new InformationSchemaMetadata("test_catalog", this.metadata);
InformationSchemaColumnHandle tableSchemaColumn = new InformationSchemaColumnHandle("table_schema");
InformationSchemaColumnHandle tableNameColumn = new InformationSchemaColumnHandle("table_name");
ConnectorTableHandle tableHandle = metadata.getTableHandle(session, new SchemaTableName("information_schema", "tables"));
// Empty schema name
InformationSchemaTableHandle filtered = metadata.applyFilter(session, tableHandle, new Constraint(TupleDomain.withColumnDomains(ImmutableMap.of(tableSchemaColumn, Domain.singleValue(VARCHAR, Slices.utf8Slice("")))))).map(ConstraintApplicationResult::getHandle).map(InformationSchemaTableHandle.class::cast).orElseThrow(AssertionError::new);
// "" schema name is valid schema name, but is (currently) valid for QualifiedTablePrefix
assertEquals(filtered.getPrefixes(), ImmutableSet.of(new QualifiedTablePrefix("test_catalog", "")));
// Empty table name
filtered = metadata.applyFilter(session, tableHandle, new Constraint(TupleDomain.withColumnDomains(ImmutableMap.of(tableNameColumn, Domain.singleValue(VARCHAR, Slices.utf8Slice("")))))).map(ConstraintApplicationResult::getHandle).map(InformationSchemaTableHandle.class::cast).orElseThrow(AssertionError::new);
// "" table name is valid schema name, but is (currently) valid for QualifiedTablePrefix
// filter blindly applies filter to all visible schemas, so information_schema must be included
assertEquals(filtered.getPrefixes(), ImmutableSet.of(new QualifiedTablePrefix("test_catalog", "test_schema", ""), new QualifiedTablePrefix("test_catalog", "information_schema", "")));
}
Aggregations