500 error with embedded SSO login
Was able to get it working locally with the paseto token.
Deployed it to staging and it hits upsert-user-and-login, and I can see a valid token in the request body but I get a 500 error. Is this something I'm doing wrong?
500 Internal Server Error
Something went wrong: [DwE500REX]
java.lang.IllegalArgumentException: requirement failed: TyE5KBW06
at scala.Predef$.require(Predef.scala:281)
at com.debiki.core.ExternalUser.<init>(user.scala:849)
at talkyard.server.parser.PasetoParSer$.apiV0_parseExternalUserImpl(PasetoParSer.scala:59)
at talkyard.server.parser.PasetoParSer$.apiV0_parseExternalUser(PasetoParSer.scala:14)
at talkyard.server.authn.SsoAuthnController.$anonfun$apiV0_upsertUserAndLogin$3(SsoAuthnController.scala:232)
at scala.Option.map(Option.scala:230)
at talkyard.server.authn.SsoAuthnController.$anonfun$apiV0_upsertUserAndLogin$1(SsoAuthnController.scala:216)
at scala.Function1.$anonfun$andThen$1(Function1.scala:57)
at ed.server.http.PlainApiActions$$anon$1.runBlockIfAuthOk(PlainApiActions.scala:684)
at ed.server.http.PlainApiActions$$anon$1.invokeBlockAuthViaCookie(PlainApiActions.scala:432)
at ed.server.http.PlainApiActions$$anon$1.invokeBlockImpl(PlainApiActions.scala:250)
at ed.server.http.PlainApiActions$$anon$1.invokeBlock(PlainApiActions.scala:136)
at ed.server.http.PlainApiActions$$anon$1.invokeBlock(PlainApiActions.scala:109)
at play.api.mvc.ActionBuilder$$anon$9.apply(Action.scala:379)
at ed.server.http.PlainApiActions$$anon$1.$anonfun$composeAction$1(PlainApiActions.scala:123)
at ed.server.http.SafeActions$ExceptionAction$.invokeBlock(SafeActions.scala:126)
at ed.server.http.SafeActions$ExceptionAction$.invokeBlock(SafeActions.scala:83)
at play.api.mvc.ActionBuilder$$anon$9.apply(Action.scala:379)
at play.api.mvc.Action.$anonfun$apply$4(Action.scala:82)
at play.api.libs.streams.StrictAccumulator.$anonfun$mapFuture$4(Accumulator.scala:168)
at scala.util.Try$.apply(Try.scala:213)
at play.api.libs.streams.StrictAccumulator.$anonfun$mapFuture$3(Accumulator.scala:168)
at scala.Function1.$anonfun$andThen$1(Function1.scala:57)
at scala.Function1.$anonfun$andThen$1(Function1.scala:57)
at play.api.libs.streams.StrictAccumulator.run(Accumulator.scala:200)
at play.core.server.AkkaHttpServer.$anonfun$runAction$4(AkkaHttpServer.scala:418)
at akka.http.scaladsl.util.FastFuture$.strictTransform$1(FastFuture.scala:41)
at akka.http.scaladsl.util.FastFuture$.transformWith$extension1(FastFuture.scala:55)
at akka.http.scaladsl.util.FastFuture$.flatMap$extension(FastFuture.scala:26)
at play.core.server.AkkaHttpServer.runAction(AkkaHttpServer.scala:415)
at play.core.server.AkkaHttpServer.executeHandler(AkkaHttpServer.scala:360)
at play.core.server.AkkaHttpServer.handleRequest(AkkaHttpServer.scala:323)
at play.core.server.AkkaHttpServer.$anonfun$createServerBinding$1(AkkaHttpServer.scala:224)
at akka.stream.impl.fusing.MapAsync$$anon$30.onPush(Ops.scala:1307)
at akka.stream.impl.fusing.GraphInterpreter.processPush(GraphInterpreter.scala:542)
at akka.stream.impl.fusing.GraphInterpreter.processEvent(GraphInterpreter.scala:496)
at akka.stream.impl.fusing.GraphInterpreter.execute(GraphInterpreter.scala:390)
at akka.stream.impl.fusing.GraphInterpreterShell.runBatch(ActorGraphInterpreter.scala:650)
at akka.stream.impl.fusing.GraphInterpreterShell$AsyncInput.execute(ActorGraphInterpreter.scala:521)
at akka.stream.impl.fusing.GraphInterpreterShell.processEvent(ActorGraphInterpreter.scala:625)
at akka.stream.impl.fusing.ActorGraphInterpreter.akka$stream$impl$fusing$ActorGraphInterpreter$$processEvent(ActorGraphInterpreter.scala:800)
at akka.stream.impl.fusing.ActorGraphInterpreter$$anonfun$receive$1.applyOrElse(ActorGraphInterpreter.scala:818)
at akka.actor.Actor.aroundReceive(Actor.scala:537)
at akka.actor.Actor.aroundReceive$(Actor.scala:535)
at akka.stream.impl.fusing.ActorGraphInterpreter.aroundReceive(ActorGraphInterpreter.scala:716)
at akka.actor.ActorCell.receiveMessage(ActorCell.scala:580)
at akka.actor.ActorCell.invoke(ActorCell.scala:548)
at akka.dispatch.Mailbox.processMailbox(Mailbox.scala:270)
at akka.dispatch.Mailbox.run(Mailbox.scala:231)
at akka.dispatch.Mailbox.exec(Mailbox.scala:243)
at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:289)
at java.util.concurrent.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1056)
at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1692)
at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:157)
- KajMagnus @KajMagnus2022-01-18 07:19:40.436Z
Seems you can work around this problem (util it's been fixed),
by either including no full name at all — that is, leaving out thefullName
field,
or, when including a full name, make sure it doesn't start or end with spaces, and that it's not the empty string (""
).Details: Looks like a Talkyard bug, in that the PASETO parser allows non-trimmed or empty names,
but other code doesn't allow it (requires that any full name either 1) is left out, or that 2) it's non-empty and doesn't start/end with spaces).(If you're curious, here's how the double check that fails looks:
require(fullName.forall(_.isTrimmedNonEmpty), "TyE5KBW06")
)Thanks for having including the stack trace
***
Was able to get it working locally
(I suppose the local environment didn't include any user name fields that triggered the bug.)
***
Apart from running into this, how did the PASETO integration go this far?
How hard / easy / (or maybe annoying?) was it to find the right PASETO lib for you to use, and write the code? (What lib did you use, if I may ask?)
What's your use case b.t.w., I suppose this is for a blog somewhere? (Or embedded comments ... for something else than a blog?) - MIn reply tomazurbeam⬆:Walter Mazur @mazurbeam
Awesome thanks removing username from the payload worked.
Other than that the integration went pretty well using the python PASETO library. Struggled a little bit figuring out how to inject the key, but it ended up being pretty simple and obvious. Convert to hex and overwrite the key. Definitely a fan of these tokens now.
And yep using this for embedded comments on a blog
import paseto from paseto.keys.symmetric_key import SymmetricKey from paseto.protocols.v2 import ProtocolVersion2 shared_secret_key_bytes = bytes.fromhex(SSO_TOKEN_SECRET) shared_key = SymmetricKey.generate(protocol=ProtocolVersion2) shared_key.key = shared_secret_key_bytes authn_message = { ... } token = paseto.create( key=shared_key, purpose='local', exp_seconds=300, claims=authn_message )
- Progresswith handling this problem