Skip to content

Commit

Permalink
Speed up some of the pageload requests
Browse files Browse the repository at this point in the history
  • Loading branch information
fm3 committed Dec 18, 2024
1 parent 32257f1 commit dcff37c
Show file tree
Hide file tree
Showing 8 changed files with 49 additions and 29 deletions.
3 changes: 2 additions & 1 deletion app/WebknossosModule.scala
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import com.google.inject.AbstractModule
import com.scalableminds.webknossos.datastore.storage.DataVaultService
import controllers.InitialDataService
import controllers.{Application, InitialDataService}
import files.TempFileService
import mail.MailchimpTicker
import models.analytics.AnalyticsSessionService
Expand All @@ -17,6 +17,7 @@ import utils.sql.SqlClient

class WebknossosModule extends AbstractModule {
override def configure(): Unit = {
bind(classOf[Application]).asEagerSingleton()
bind(classOf[Startup]).asEagerSingleton()
bind(classOf[SqlClient]).asEagerSingleton()
bind(classOf[InitialDataService]).asEagerSingleton()
Expand Down
9 changes: 6 additions & 3 deletions app/controllers/Application.scala
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import models.organization.OrganizationDAO
import models.user.UserService
import org.apache.pekko.actor.ActorSystem
import play.api.libs.json.Json
import play.api.mvc.{Action, AnyContent}
import play.api.mvc.{Action, AnyContent, Result}
import play.silhouette.api.Silhouette
import security.WkEnv
import utils.sql.{SimpleSQLDAO, SqlClient}
Expand Down Expand Up @@ -51,9 +51,12 @@ class Application @Inject()(actorSystem: ActorSystem,
}
}

// This only changes on server restart, so we can cache the full result.
private lazy val cachedFeaturesResult: Result = addNoCacheHeaderFallback(
Ok(conf.raw.underlying.getConfig("features").resolve.root.render(ConfigRenderOptions.concise())).as(jsonMimeType))

def features: Action[AnyContent] = sil.UserAwareAction {
addNoCacheHeaderFallback(
Ok(conf.raw.underlying.getConfig("features").resolve.root.render(ConfigRenderOptions.concise())).as(jsonMimeType))
cachedFeaturesResult
}

def health: Action[AnyContent] = Action {
Expand Down
3 changes: 2 additions & 1 deletion app/controllers/AuthenticationController.scala
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,8 @@ class AuthenticationController @Inject()(
case None => Future.successful(NotFound(Messages("error.noUser")))
case Some(user) =>
for {
token <- bearerTokenAuthenticatorService.createAndInit(user.loginInfo, TokenType.ResetPassword)
token <- bearerTokenAuthenticatorService
.createAndInit(user.loginInfo, TokenType.ResetPassword, deleteOld = true)
} yield {
Mailer ! Send(defaultMails.resetPasswordMail(user.name, email.toLowerCase, token))
Ok
Expand Down
4 changes: 2 additions & 2 deletions app/controllers/OrganizationController.scala
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,9 @@ class OrganizationController @Inject()(

def organizationsIsEmpty: Action[AnyContent] = Action.async { implicit request =>
for {
allOrgs <- organizationDAO.findAll(GlobalAccessContext) ?~> "organization.list.failed"
orgaTableIsEmpty <- organizationDAO.isEmpty ?~> "organization.list.failed"
} yield {
Ok(Json.toJson(allOrgs.isEmpty))
Ok(Json.toJson(orgaTableIsEmpty))
}
}

Expand Down
6 changes: 6 additions & 0 deletions app/models/organization/Organization.scala
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,12 @@ class OrganizationDAO @Inject()(sqlClient: SqlClient)(implicit ec: ExecutionCont
parsed <- parseAll(r)
} yield parsed

def isEmpty: Fox[Boolean] =
for {
rows <- run(q"SELECT COUNT(*) FROM $existingCollectionName".as[Int])
value <- rows.headOption
} yield value == 0

@deprecated("use findOne with string type instead", since = "")
override def findOne(id: ObjectId)(implicit ctx: DBAccessContext): Fox[Organization] =
Fox.failure("Cannot find organization by ObjectId. Use findOne with string type instead")
Expand Down
20 changes: 12 additions & 8 deletions app/security/BearerTokenAuthenticatorRepository.scala
Original file line number Diff line number Diff line change
Expand Up @@ -56,16 +56,20 @@ class BearerTokenAuthenticatorRepository(tokenDAO: TokenDAO)(implicit ec: Execut

def add(authenticator: BearerTokenAuthenticator,
tokenType: TokenType,
deleteOld: Boolean = true): Future[BearerTokenAuthenticator] =
deleteOld: Boolean = true): Future[BearerTokenAuthenticator] = {
if (deleteOld) {
removeByLoginInfoIfPresent(authenticator.loginInfo, tokenType)
}
for {
oldAuthenticatorOpt <- findOneByLoginInfo(authenticator.loginInfo, tokenType)
_ <- insert(authenticator, tokenType).futureBox
} yield {
if (deleteOld) {
oldAuthenticatorOpt.map(a => remove(a.id))
}
authenticator
}
} yield authenticator
}

private def removeByLoginInfoIfPresent(loginInfo: LoginInfo, tokenType: TokenType): Unit =
for {
oldOpt <- findOneByLoginInfo(loginInfo, tokenType)
_ = oldOpt.foreach(old => remove(old.id))
} yield ()

private def insert(authenticator: BearerTokenAuthenticator, tokenType: TokenType): Fox[Unit] =
for {
Expand Down
20 changes: 10 additions & 10 deletions app/security/CombinedAuthenticatorService.scala
Original file line number Diff line number Diff line change
Expand Up @@ -39,14 +39,14 @@ case class CombinedAuthenticatorService(cookieSettings: CookieAuthenticatorSetti

private val cookieSigner = new JcaSigner(JcaSignerSettings(conf.Silhouette.CookieAuthenticator.signerSecret))

val cookieAuthenticatorService = new CookieAuthenticatorService(cookieSettings,
None,
cookieSigner,
cookieHeaderEncoding,
new Base64AuthenticatorEncoder,
fingerprintGenerator,
idGenerator,
clock)
private val cookieAuthenticatorService = new CookieAuthenticatorService(cookieSettings,
None,
cookieSigner,
cookieHeaderEncoding,
new Base64AuthenticatorEncoder,
fingerprintGenerator,
idGenerator,
clock)

val tokenAuthenticatorService =
new WebknossosBearerTokenAuthenticatorService(tokenSettings, tokenDao, idGenerator, clock, userService, conf)
Expand All @@ -55,9 +55,9 @@ case class CombinedAuthenticatorService(cookieSettings: CookieAuthenticatorSetti
override def create(loginInfo: LoginInfo)(implicit request: RequestHeader): Future[CombinedAuthenticator] =
cookieAuthenticatorService.create(loginInfo).map(CombinedAuthenticator(_))

def createToken(loginInfo: LoginInfo): Future[CombinedAuthenticator] = {
private def createToken(loginInfo: LoginInfo): Future[CombinedAuthenticator] = {
val tokenAuthenticator = tokenAuthenticatorService.create(loginInfo, TokenType.Authentication)
tokenAuthenticator.map(tokenAuthenticatorService.init(_, TokenType.Authentication))
tokenAuthenticator.map(tokenAuthenticatorService.init(_, TokenType.Authentication, deleteOld = true))
tokenAuthenticator.map(CombinedAuthenticator(_))
}

Expand Down
13 changes: 9 additions & 4 deletions app/security/WebknossosBearerTokenAuthenticatorService.scala
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ class WebknossosBearerTokenAuthenticatorService(settings: BearerTokenAuthenticat
}
}

def init(authenticator: BearerTokenAuthenticator, tokenType: TokenType, deleteOld: Boolean = true): Future[String] =
def init(authenticator: BearerTokenAuthenticator, tokenType: TokenType, deleteOld: Boolean): Future[String] =
repository
.add(authenticator, tokenType, deleteOld)
.map { a =>
Expand All @@ -64,10 +64,15 @@ class WebknossosBearerTokenAuthenticatorService(settings: BearerTokenAuthenticat
case e => throw new AuthenticatorInitializationException(InitError.format(ID, authenticator), Some(e))
}

def createAndInitDataStoreTokenForUser(user: User): Fox[String] =
createAndInit(user.loginInfo, TokenType.DataStore, deleteOld = false)
def createAndInitDataStoreTokenForUser(user: User): Fox[String] = {
val before = Instant.now
for {
res <- createAndInit(user.loginInfo, TokenType.DataStore, deleteOld = false)
_ = Instant.logSince(before, "createAndInit")
} yield res
}

def createAndInit(loginInfo: LoginInfo, tokenType: TokenType, deleteOld: Boolean = true): Future[String] =
def createAndInit(loginInfo: LoginInfo, tokenType: TokenType, deleteOld: Boolean): Future[String] =
for {
tokenAuthenticator <- create(loginInfo, tokenType)
tokenId <- init(tokenAuthenticator, tokenType, deleteOld)
Expand Down

0 comments on commit dcff37c

Please sign in to comment.