This is an automated email from the ASF dual-hosted git repository.
github-merge-queue[bot] pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/texera.git
The following commit(s) were added to refs/heads/main by this push:
new ffbda03134 refactor(auth): construct User via .tap instead of
positional constructor (#7057)
ffbda03134 is described below
commit ffbda031344176dbba2820406ac418b36d273c67
Author: Neil Ketteringham <[email protected]>
AuthorDate: Thu Jul 30 12:29:25 2026 -0700
refactor(auth): construct User via .tap instead of positional constructor
(#7057)
### What changes were proposed in this PR?
Classes relying on the POJO User generated by jOOq uses its positional
constructor which is fragile and requires us to refactor every
constructor every time we edit the User table even if the new fields
aren't used. Most instances of User() called it with mostly null fields
which is hard to read and isn't very clear.
This PR changes that by using the .tap{} feature of Scala which allows
you to construct and modify objects in place before assigned as a
parameter or variable.
This allows code like this:
```scala
val GUEST: User =
new User(null, "guest", null, null, null, null, UserRoleEnum.REGULAR,
null, null, null, null)
```
To be rewritten like this
```scala
val GUEST: User = {
new User().tap { user =>
user.setName("guest")
user.setRole(UserRoleEnum.REGULAR)
}
}
```
### Any related issues, documentation, discussions?
Closes #7044
### How was this PR tested?
PR was tested against current test suite.
### Was this PR authored or co-authored using generative AI tooling?
No.
---
.../activity/UserActivityEventListenerSpec.scala | 10 ++++--
.../texera/web/ServletAwareConfigurator.scala | 37 +++++++---------------
.../apache/texera/web/auth/GuestAuthFilter.scala | 7 ++--
.../scala/org/apache/texera/auth/JwtParser.scala | 24 +++++++-------
4 files changed, 35 insertions(+), 43 deletions(-)
diff --git
a/access-control-service/src/test/scala/org/apache/texera/service/activity/UserActivityEventListenerSpec.scala
b/access-control-service/src/test/scala/org/apache/texera/service/activity/UserActivityEventListenerSpec.scala
index 3d99f4e7fb..e0cfee03c5 100644
---
a/access-control-service/src/test/scala/org/apache/texera/service/activity/UserActivityEventListenerSpec.scala
+++
b/access-control-service/src/test/scala/org/apache/texera/service/activity/UserActivityEventListenerSpec.scala
@@ -31,12 +31,18 @@ import org.scalatest.matchers.should.Matchers
import java.security.Principal
import java.util.concurrent.ConcurrentLinkedQueue
+import scala.util.chaining.scalaUtilChainingOps
class UserActivityEventListenerSpec extends AnyFlatSpec with Matchers {
private def sessionUser(uid: Integer): SessionUser = {
- val u = new User(uid, "u", null, null, null, null, UserRoleEnum.REGULAR,
null, null, null, null)
- new SessionUser(u)
+ new SessionUser(
+ new User().tap { user =>
+ user.setUid(uid)
+ user.setName("u")
+ user.setRole(UserRoleEnum.REGULAR)
+ }
+ )
}
private def buildEvent(eventType: RequestEvent.Type, sc: SecurityContext):
RequestEvent = {
diff --git
a/amber/src/main/scala/org/apache/texera/web/ServletAwareConfigurator.scala
b/amber/src/main/scala/org/apache/texera/web/ServletAwareConfigurator.scala
index cb3628df5b..2e2fc6e082 100644
--- a/amber/src/main/scala/org/apache/texera/web/ServletAwareConfigurator.scala
+++ b/amber/src/main/scala/org/apache/texera/web/ServletAwareConfigurator.scala
@@ -31,6 +31,7 @@ import java.nio.charset.Charset
import javax.websocket.HandshakeResponse
import javax.websocket.server.{HandshakeRequest, ServerEndpointConfig}
import scala.jdk.CollectionConverters.{ListHasAsScala, _}
+import scala.util.chaining.scalaUtilChainingOps
/**
* This configurator extracts user identity from the HTTP handshake request
@@ -66,19 +67,11 @@ class ServletAwareConfigurator extends
ServerEndpointConfig.Configurator with La
config.getUserProperties.put(
classOf[User].getName,
- new User(
- userId,
- userName,
- userEmail,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null
- )
+ new User().tap { user =>
+ user.setUid(userId)
+ user.setName(userName)
+ user.setEmail(userEmail)
+ }
)
logger.debug(s"User created from headers: ID=$userId, Name=$userName")
} else {
@@ -97,19 +90,11 @@ class ServletAwareConfigurator extends
ServerEndpointConfig.Configurator with La
val claims = jwtConsumer.process(token).getJwtClaims
config.getUserProperties.put(
classOf[User].getName,
- new User(
- claims.getClaimValue("userId").asInstanceOf[Long].toInt,
- claims.getSubject,
-
String.valueOf(claims.getClaimValue("email").asInstanceOf[String]),
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null
- )
+ new User().tap { user =>
+
user.setUid(claims.getClaimValue("userId").asInstanceOf[Long].toInt)
+ user.setName(claims.getSubject)
+
user.setEmail(claims.getClaimValue("email").asInstanceOf[String])
+ }
)
})
}
diff --git
a/amber/src/main/scala/org/apache/texera/web/auth/GuestAuthFilter.scala
b/amber/src/main/scala/org/apache/texera/web/auth/GuestAuthFilter.scala
index b7dda09489..8682335e82 100644
--- a/amber/src/main/scala/org/apache/texera/web/auth/GuestAuthFilter.scala
+++ b/amber/src/main/scala/org/apache/texera/web/auth/GuestAuthFilter.scala
@@ -31,6 +31,7 @@ import javax.annotation.{Nullable, Priority}
import javax.ws.rs.Priorities
import javax.ws.rs.container.{ContainerRequestContext, PreMatching}
import javax.ws.rs.core.SecurityContext
+import scala.util.chaining.scalaUtilChainingOps
@PreMatching
@Priority(Priorities.AUTHENTICATION) object GuestAuthFilter {
@@ -38,8 +39,10 @@ import javax.ws.rs.core.SecurityContext
override protected def newInstance = new GuestAuthFilter
}
- val GUEST: User =
- new User(null, "guest", null, null, null, null, UserRoleEnum.REGULAR,
null, null, null, null)
+ val GUEST: User = new User().tap { user =>
+ user.setName("guest")
+ user.setRole(UserRoleEnum.REGULAR)
+ }
}
@PreMatching
diff --git a/common/auth/src/main/scala/org/apache/texera/auth/JwtParser.scala
b/common/auth/src/main/scala/org/apache/texera/auth/JwtParser.scala
index bb139e7093..cf324b0959 100644
--- a/common/auth/src/main/scala/org/apache/texera/auth/JwtParser.scala
+++ b/common/auth/src/main/scala/org/apache/texera/auth/JwtParser.scala
@@ -26,6 +26,7 @@ import org.jose4j.jwt.JwtClaims
import org.jose4j.lang.UnresolvableKeyException
import java.util.Optional
+import scala.util.chaining.scalaUtilChainingOps
/** Single source of truth for converting a verified JWT into a
[[SessionUser]].
*
@@ -63,19 +64,16 @@ object JwtParser extends LazyLogging {
val role =
UserRoleEnum.valueOf(claims.getClaimValue("role").asInstanceOf[String])
val googleId = claims.getClaimValue("googleId", classOf[String])
val googleAvatar = claims.getClaimValue("googleAvatar", classOf[String])
- val user = new User(
- userId,
- userName,
- email,
- null,
- googleId,
- googleAvatar,
- role,
- null,
- null,
- null,
- null
+
+ new SessionUser(
+ new User().tap { user =>
+ user.setUid(userId)
+ user.setName(userName)
+ user.setEmail(email)
+ user.setRole(role)
+ user.setGoogleId(googleId)
+ user.setGoogleAvatar(googleAvatar)
+ }
)
- new SessionUser(user)
}
}