<commit_before>package viscel.server


import java.io.ByteArrayInputStream

import better.files._
import io.javalin.Javalin
import io.javalin.core.compression.Gzip
import io.javalin.core.util.Header
import io.javalin.http.staticfiles.Location
import loci.communicator.ws.javalin.WS
import loci.communicator.ws.javalin.WS.Properties
import loci.registry.Registry
import rescala.default.Signal
import rescala.extra.distributables.LociDist
import viscel.shared.BookmarksMap.BookmarksMap
import viscel.shared.{Bindings, JsoniterCodecs, Vid}
import viscel.store.{BlobStore, RowStoreV4, User}
import viscel.{FolderImporter, Viscel}

import scala.collection.mutable
import scala.concurrent.Future
import scala.concurrent.duration._
import scala.jdk.CollectionConverters._
import scala.jdk.FutureConverters._


class JavalinServer(blobStore: BlobStore,
                    terminate: () => Unit,
                    pages: ServerPages,
                    folderImporter: FolderImporter,
                    interactions: Interactions,
                    staticPath: File,
                    urlPrefix: String,
                    rowStore: RowStoreV4
                   ) {

  def stop() = jl.stop()
  def start(interface: String, port: Int) = {
    setup()
    wsSetup()
    jl.start(interface, port)
  }


  lazy val jl: Javalin = Javalin.create { config =>
    config.contextPath = urlPrefix
    config.defaultContentType = "text/html; charset=UTF-8"
    config.accessManager { case (handler, ctx, roles) =>
      Option.when(ctx.basicAuthCredentialsExist()) {
        val cred = ctx.basicAuthCredentials()
        interactions.authenticate(cred.getUsername, cred.getPassword)
      }.flatten match {
        case None       =>
          ctx.status(401).header(Header.WWW_AUTHENTICATE, "Basic")
        case Some(user) =>
          ctx.attribute("user", user)
          handler.handle(ctx)
      }
    }
    config.addStaticFiles(staticPath.pathAsString, Location.EXTERNAL)
    config.compressionStrategy(null, new Gzip())
    config.showJavalinBanner = false
  }<commit_msg>store auth in cookie because browsers are crap with basic auth<commit_after>package viscel.server


import java.io.ByteArrayInputStream

import better.files._
import io.javalin.Javalin
import io.javalin.core.compression.Gzip
import io.javalin.core.util.Header
import io.javalin.http.staticfiles.Location
import loci.communicator.ws.javalin.WS
import loci.communicator.ws.javalin.WS.Properties
import loci.registry.Registry
import rescala.default.Signal
import rescala.extra.distributables.LociDist
import viscel.shared.BookmarksMap.BookmarksMap
import viscel.shared.{Bindings, JsoniterCodecs, Vid}
import viscel.store.{BlobStore, RowStoreV4, User}
import viscel.{FolderImporter, Viscel}

import scala.collection.mutable
import scala.concurrent.Future
import scala.concurrent.duration._
import scala.jdk.CollectionConverters._
import scala.jdk.FutureConverters._


class JavalinServer(blobStore: BlobStore,
                    terminate: () => Unit,
                    pages: ServerPages,
                    folderImporter: FolderImporter,
                    interactions: Interactions,
                    staticPath: File,
                    urlPrefix: String,
                    rowStore: RowStoreV4
                   ) {

  def stop() = jl.stop()
  def start(interface: String, port: Int) = {
    setup()
    wsSetup()
    jl.start(interface, port)
  }


  lazy val jl: Javalin = Javalin.create { config =>
    config.contextPath = urlPrefix
    config.defaultContentType = "text/html; charset=UTF-8"
    config.accessManager { case (handler, ctx, roles) =>
      Option.when(ctx.basicAuthCredentialsExist()) {
        val cred = ctx.basicAuthCredentials()
        interactions.authenticate(cred.getUsername, cred.getPassword)
      }.flatten.orElse{
        val cm = ctx.cookieMap().asScala
        (cm.get("viscel-user"), cm.get("viscel-password")) match {
          case (Some(user), Some(password)) => interactions.authenticate(user, password)
          case _ => None
        }
      } match {
        case None       =>
          ctx.status(401).header(Header.WWW_AUTHENTICATE, "Basic")
        case Some(user) =>
          ctx.attribute("user", user)
          ctx.cookie("viscel-user",user.id, 5_000_000)
          ctx.cookie("viscel-password", <PASSWORD>, 5_000_000)
          handler.handle(ctx)
      }
    }
    config.addStaticFiles(staticPath.pathAsString, Location.EXTERNAL)
    config.compressionStrategy(null, new Gzip())
    config.showJavalinBanner = false
  }
{'fraction_non_alphanumeric': 0.10063582547686911, 'fraction_numerical': 0.005700504275378207, 'mean_word_length': 2.9091688089117396, 'pattern_counts': {'":': 0, '<': 4, '<?xml version=': 0, '>': 16, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 1, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5100633', 'n_tokens_mistral': 1404, 'n_tokens_neox': 1343, 'n_words': 260}