<commit_before>package lila.oauth

import org.joda.time.DateTime
import play.api.http.HeaderNames.AUTHORIZATION
import play.api.libs.json.Json
import play.api.mvc.{ RequestHeader, Result }
import scala.concurrent.duration._

import lila.db.dsl._
import lila.user.{ User, UserRepo }

final class OAuthServer(
    tokenColl: Coll,
    asyncCache: lila.memo.AsyncCache.Builder
) {

  import AccessToken.{ accessTokenIdHandler, ForAuth, ForAuthBSONReader }
  import AccessToken.{ BSONFields => F }
  import OAuthServer._

  def auth(req: RequestHeader, scopes: List[OAuthScope]): Fu[AuthResult] = {
    req.headers.get(AUTHORIZATION).map(_.split(" ", 2)) match {
      case Some(Array("Bearer", tokenStr)) =>
        val tokenId = AccessToken.Id(tokenStr)
        accessTokenCache.get(tokenId) flattenWith NoSuchToken flatMap {
          case at if scopes.nonEmpty && !scopes.exists(at.scopes.contains) => fufail(MissingScope(at.scopes))
          case at => UserRepo enabledById at.userId flatMap {
            case None => fufail(NoSuchUser)
            case Some(u) => fuccess(OAuthScope.Scoped(u, at.scopes))
          }
        } map Right.apply
      case Some(_) => fufail(InvalidAuthorizationHeader)
      case None => fufail(MissingAuthorizationHeader)
    }
  } recover {
    case e: AuthError => Left(e)
  }

  private val accessTokenCache = asyncCache.multi[AccessToken.Id, Option[AccessToken.ForAuth]](
    name = "oauth.server.personal_access_token",
    f = fetchAccessToken,
    expireAfter = _.ExpireAfterWrite(3 minutes)
  )

  private def fetchAccessToken(tokenId: AccessToken.Id): Fu[Option[AccessToken.ForAuth]] =
    tokenColl.findAndUpdate(
      selector = $id(tokenId),<commit_msg>fix oauth access token selector<commit_after>package lila.oauth

import org.joda.time.DateTime
import play.api.http.HeaderNames.AUTHORIZATION
import play.api.libs.json.Json
import play.api.mvc.{ RequestHeader, Result }
import scala.concurrent.duration._

import lila.db.dsl._
import lila.user.{ User, UserRepo }

final class OAuthServer(
    tokenColl: Coll,
    asyncCache: lila.memo.AsyncCache.Builder
) {

  import AccessToken.{ accessTokenIdHandler, ForAuth, ForAuthBSONReader }
  import AccessToken.{ BSONFields => F }
  import OAuthServer._

  def auth(req: RequestHeader, scopes: List[OAuthScope]): Fu[AuthResult] = {
    req.headers.get(AUTHORIZATION).map(_.split(" ", 2)) match {
      case Some(Array("Bearer", tokenStr)) =>
        val tokenId = AccessToken.Id(tokenStr)
        accessTokenCache.get(tokenId) flattenWith NoSuchToken flatMap {
          case at if scopes.nonEmpty && !scopes.exists(at.scopes.contains) => fufail(MissingScope(at.scopes))
          case at => UserRepo enabledById at.userId flatMap {
            case None => fufail(NoSuchUser)
            case Some(u) => fuccess(OAuthScope.Scoped(u, at.scopes))
          }
        } map Right.apply
      case Some(_) => fufail(InvalidAuthorizationHeader)
      case None => fufail(MissingAuthorizationHeader)
    }
  } recover {
    case e: AuthError => Left(e)
  }

  private val accessTokenCache = asyncCache.multi[AccessToken.Id, Option[AccessToken.ForAuth]](
    name = "oauth.server.personal_access_token",
    f = fetchAccessToken,
    expireAfter = _.ExpireAfterWrite(3 minutes)
  )

  private def fetchAccessToken(tokenId: AccessToken.Id): Fu[Option[AccessToken.ForAuth]] =
    tokenColl.findAndUpdate(
      selector = $doc(F.id -> tokenId),
{'fraction_non_alphanumeric': 0.11337802389973768, 'fraction_numerical': 0.0011658408627222385, 'mean_word_length': 3.707818930041152, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 22, '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': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4319676', 'n_tokens_mistral': 1098, 'n_tokens_neox': 1091, 'n_words': 222}