Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,9 @@ stale_outputs_checked
# Docker
.dockerenv
cluster-info.properties

# VS Code
.metals/
.bloop/
.ammonite/
metals.sbt
21 changes: 11 additions & 10 deletions build.sbt
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//version := "1.0"

val projectName = "trino-plugins"
val trinoVersion = "357"
val trinoVersion = "445"

// Should the com.simondata.trino.Run object be exported in the jar?
val addEntryPoint = true
Expand All @@ -11,7 +11,8 @@ name := projectName
// Synchronized with the version of Trino we are supporting
version := trinoVersion

scalaVersion := "2.13.1"
//scalaVersion := "3.4.2"
scalaVersion := "2.13.14"

// https://mvnrepository.com/artifact/io.trino/trino-spi
if (addEntryPoint) {
Expand All @@ -21,23 +22,23 @@ if (addEntryPoint) {
}

// https://mvnrepository.com/artifact/com.typesafe.play/play-json
libraryDependencies += "com.typesafe.play" %% "play-json" % "2.8.1"
libraryDependencies += "com.typesafe.play" %% "play-json" % "2.10.6"

// https://mvnrepository.com/artifact/commons-codec/commons-codec
libraryDependencies += "commons-codec" % "commons-codec" % "1.15"
libraryDependencies += "commons-codec" % "commons-codec" % "1.17.1"

// https://mvnrepository.com/artifact/org.scalatest/scalatest
libraryDependencies += "org.scalatest" %% "scalatest" % "3.1.1" % Test
libraryDependencies += "org.scalatest" %% "scalatest" % "3.2.19" % Test

// Helpful when testing (recommended by scalatest)
logBuffered in Test := false
Test / logBuffered := false

// The single Java source acts as the entry point for our plugin
compileOrder := CompileOrder.ScalaThenJava

// Target Java SE 11
scalacOptions += "-target:jvm-11"
javacOptions ++= Seq("-source", "11", "-target", "11", "-Xlint")
scalacOptions += "-target:jvm-21"
javacOptions ++= Seq("-source", "21", "-target", "21", "-Xlint")

val dateTime = {
import java.util.{Date, TimeZone}
Expand Down Expand Up @@ -69,7 +70,7 @@ def buildArtifactName(extension: String = ".jar") = {
name
}

assemblyMergeStrategy in assembly := {
assembly / assemblyMergeStrategy := {
case PathList("io", "trino", "spi", "license", "LicenseManager.class") => MergeStrategy.discard
case PathList("META-INF", "services", "io.trino.spi.Plugin") => MergeStrategy.first
case PathList("META-INF", xs @ _*) => MergeStrategy.discard
Expand All @@ -90,6 +91,6 @@ artifactName := { (sv: ScalaVersion, module: ModuleID, artifact: Artifact) =>
buildArtifactName(s".${artifact.extension}")
}

assemblyJarName in assembly := {
assembly / assemblyJarName := {
buildArtifactName()
}
2 changes: 1 addition & 1 deletion docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
version: "3.7"
services:
trino:
image: trinodb/trino:351
image: trinodb/trino:445
env_file:
- .dockerenv
volumes:
Expand Down
2 changes: 1 addition & 1 deletion project/build.properties
Original file line number Diff line number Diff line change
@@ -1 +1 @@
sbt.version = 1.3.8
sbt.version = 1.9.9
14 changes: 10 additions & 4 deletions src/main/scala/com/simondata/trino/Auth.scala
Original file line number Diff line number Diff line change
Expand Up @@ -9,22 +9,24 @@ package com.simondata.trino

import java.nio.file.AccessDeniedException
import java.security.Principal

import io.trino.spi.security.SystemSecurityContext
import io.trino.spi.security.{Identity, SystemSecurityContext}

// Auth Identities (who is trying to access/modify the resource)
sealed abstract class AuthId(category: String) {
def name: String
override def toString(): String = s"id:${category}:${name}"
}
case class AuthIdPrincipal(name: String) extends AuthId("principal")
@deprecated("Use AuthIdIdentity instead")
case class AuthIdUser(name: String) extends AuthId("user")
case class AuthIdIdentity(name: String) extends AuthId("identity")
case object AuthIdUnknown extends AuthId("anonymous") {
val name = "unknown"
}
object AuthId {
def of(securityContext: SystemSecurityContext): AuthId = AuthIdUser(securityContext.getIdentity.getUser)
def of(principal: Principal): AuthId = AuthIdUser(principal.getName)
def of(securityContext: SystemSecurityContext): AuthId = AuthIdIdentity(securityContext.getIdentity.getUser)
def of(principal: Principal): AuthId = AuthIdIdentity(principal.getName)
def of(identity: Identity): AuthId = AuthIdIdentity(identity.getUser)
def unknown: AuthId = AuthIdUnknown
}

Expand All @@ -38,7 +40,9 @@ case object AuthActionCreate extends AuthAction("create")
case object AuthActionRead extends AuthAction("read")
case object AuthActionUpdate extends AuthAction("update")
case object AuthActionDelete extends AuthAction("delete")
case object AuthActionDeny extends AuthAction("deny")
case object AuthActionExecute extends AuthAction("execute")
case object AuthActionKill extends AuthAction("kill")

// Auth Resources (which resource are they trying to read/modify)
sealed trait AuthResource {
Expand All @@ -55,6 +59,8 @@ case class AuthResourceRecord(resource: Record) extends AuthResource
case class AuthResourceFunction(resource: XFunction) extends AuthResource
case class AuthResourceProcedure(resource: XProcedure) extends AuthResource
case class AuthResourceQuery(resource: XQuery) extends AuthResource
case class AuthResourceIdentity(resource: XIdentity) extends AuthResource
case class AuthResourcePrivilege(resource: XEntityPrivilege) extends AuthResource
case object AuthResourceSystemInfo extends AuthResource {
def resource: Resource = SystemInfo
}
Expand Down
53 changes: 47 additions & 6 deletions src/main/scala/com/simondata/trino/Context.scala
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,11 @@
package com.simondata.trino

import com.simondata.util.Types
import io.trino.spi.connector.{CatalogSchemaName, CatalogSchemaTableName}
import io.trino.spi.security.SystemSecurityContext
import io.trino.spi.QueryId
import io.trino.spi.connector.{CatalogSchemaName, CatalogSchemaTableName, EntityPrivilege}
import io.trino.spi.security.{Identity, SystemSecurityContext}

import java.util.Optional

/**
* The general concept of a namespace. This is used in multiple places and is context-specific.
Expand Down Expand Up @@ -98,6 +101,30 @@ object XProcedure {
def of(name: String): XProcedure = XProcedure(name)
}

case class XIdentity(name: String) extends Resource {
override def category: String = "identity"
override def toString: String = s"${name}"
}
object XIdentity {
def of(name: String): XIdentity = XIdentity(name)

def from(identity: Identity): XIdentity = XIdentity.of(
identity.getUser
)
}

case class XEntityPrivilege(name: String) extends Resource {
override def category: String = "entity-privilege"
override def toString: String = s"${name}"
}
object XEntityPrivilege {
def of(name: String): XEntityPrivilege = XEntityPrivilege(name)

def from(privilege: EntityPrivilege): XEntityPrivilege = XEntityPrivilege.of(
privilege.name()
)
}

/**
* Identifies a query resource against which auth permissions for a given
* user may be evaluated. The presence of the id and/or the owner determines
Expand All @@ -117,11 +144,25 @@ case class XQuery(id: Option[String], owner: Option[AuthId]) extends Resource {
object XQuery {
def any: XQuery = of(None, None)
def of(id: Option[String], owner: Option[AuthId] = None): XQuery = XQuery(id, owner)
def from(context: SystemSecurityContext): XQuery = of(Types.toOption(context.getQueryId).map(_.getId))
def from(owner: String): XQuery = of(None, Some(AuthIdUser(owner)))
def from(context: SystemSecurityContext): XQuery = {
of(Types.toOption(Optional.of(context.getQueryId)).map(_.getId))
}
def from(owner: String): XQuery = of(None, Some(AuthIdIdentity(owner)))

@deprecated
def from(context: SystemSecurityContext, owner: String): XQuery = of(
Types.toOption(context.getQueryId.map(_.getId)),
Some(AuthIdUser(owner))
Types.toOption(Optional.of(context.getQueryId).map(_.getId)),
Some(AuthIdIdentity(owner))
)

def from(context: SystemSecurityContext, owner: Identity): XQuery = of(
Types.toOption(Optional.of(context.getQueryId).map(_.getId)),
Some(AuthIdIdentity(owner.getUser))
)

def from(queryId: QueryId, owner: Identity): XQuery = of(
Types.toOption(Optional.of(queryId).map(_.getId)),
Some(AuthIdIdentity(owner.getUser))
)
}

Expand Down
Loading