<commit_before>package lampetia.security.service

import lampetia.model.sql.ModelFeatures
import lampetia.model.{Resource, ResourceId}
import lampetia.security.model._
import lampetia.sql.dialect.postgres.jdbc._

/**
 * @author <NAME>
 */
trait AclService {

  import lampetia.security.module.SecurityModule._

  protected def insertAcl(acl: Acl): IO[Int] = {
    val aclm = AclModel
    acl.data.parentResource match {
      case None =>
        aclm.insert(aclm.id := acl.id.bind,
          aclm.data.permission := acl.data.permission.bind.cast(Types.bit(32)),
          aclm.data.subject.subjectId := acl.data.subject.subjectId.bind,
          aclm.data.subject.subjectType := acl.data.subject.subjectType.bind,
          aclm.data.resource.resourceId := acl.data.resource.resourceId.bind,
          aclm.data.resource.resourceType := acl.data.resource.resourceType.bind)
      case Some(pr) =>
        aclm.insert(aclm.id := acl.id.bind,
          aclm.data.permission := acl.data.permission.bind.cast(Types.bit(32)),
          aclm.data.subject.subjectId := acl.data.subject.subjectId.bind,
          aclm.data.subject.subjectType := acl.data.subject.subjectType.bind,
          aclm.data.resource.resourceId := acl.data.resource.resourceId.bind,
          aclm.data.resource.resourceType := acl.data.resource.resourceType.bind,
          aclm.data.parentResource.resourceId := acl.data.parentResource.get.resourceId.bind,
          aclm.data.parentResource.resourceType := acl.data.parentResource.get.resourceType.bind
        )
    }
  }

  protected def insertAclRole(aclRole: AclRole): IO[Int] = {
    val aclrm = AclRoleModel
    aclrm.insert(aclrm.ref.aclId := aclRole.ref.aclId.bind,
      aclrm.ref.roleId := aclRole.ref.roleId.bind)
  }

  def grant(data: AclData): IO[Acl] = {
    val aclm = AclModel
    val acl = Acl(aclm.generate, data)
    insertAcl(acl)
      .transactionally
      .map(_ => acl)
  }

  def getAcl(subjectId: SubjectId, resource: Resource): IO[Option[AclId]] = {
    val aclm = AclModel
    select(aclm.id)
      .from(aclm.schemaPrefixed)
      .where(
        aclm.data.subject.subjectId === subjectId.bind and
          aclm.data.resource.resourceType === resource.resourceType.bind and
          aclm.data.resource.resourceType === resource.resourceType.bind)
      .lifted
      .read[AclId]
      .map(_.headOption)
  }

  def hasAcl(subjectId: SubjectId, resource: Resource): IO[Boolean] = {
    getAcl(subjectId, resource)
    .flatMap{
      case None => IO.pure(false)
      case _ => IO.pure(true)
    }<commit_msg>define ACL insert couples in a neater way<commit_after>package lampetia.security.service

import lampetia.model.sql.ModelFeatures
import lampetia.model.{Resource, ResourceId}
import lampetia.security.model._
import lampetia.sql.dialect.postgres.jdbc._

/**
 * @author <NAME>
 */
trait AclService {

  import lampetia.security.module.SecurityModule._

  protected def insertAcl(acl: Acl): IO[Int] = {
    val aclm = AclModel

    val parentResourceCouples =
      acl.data.parentResource match {
        case None => Seq.empty
        case Some(parentResource) =>
          Seq(
            aclm.data.parentResource.resourceId  := parentResource.resourceId.bind,
            aclm.data.parentResource.resourceType := parentResource.resourceType.bind)
      }

    val couples =
      parentResourceCouples ++
      Seq(aclm.id := acl.id.bind,
        aclm.data.permission := acl.data.permission.bind.cast(Types.bit(32)),
        aclm.data.subject.subjectId := acl.data.subject.subjectId.bind,
        aclm.data.subject.subjectType := acl.data.subject.subjectType.bind,
        aclm.data.resource.resourceId := acl.data.resource.resourceId.bind,
        aclm.data.resource.resourceType := acl.data.resource.resourceType.bind)

    aclm.insert(couples : _*)
  }

  protected def insertAclRole(aclRole: AclRole): IO[Int] = {
    val aclrm = AclRoleModel
    aclrm.insert(aclrm.ref.aclId := aclRole.ref.aclId.bind,
      aclrm.ref.roleId := aclRole.ref.roleId.bind)
  }

  def grant(data: AclData): IO[Acl] = {
    val aclm = AclModel
    val acl = Acl(aclm.generate, data)
    insertAcl(acl)
      .transactionally
      .map(_ => acl)
  }

  def getAcl(subjectId: SubjectId, resource: Resource): IO[Option[AclId]] = {
    val aclm = AclModel
    select(aclm.id)
      .from(aclm.schemaPrefixed)
      .where(
        aclm.data.subject.subjectId === subjectId.bind and
          aclm.data.resource.resourceType === resource.resourceType.bind and
          aclm.data.resource.resourceType === resource.resourceType.bind)
      .lifted
      .read[AclId]
      .map(_.headOption)
  }

  def hasAcl(subjectId: SubjectId, resource: Resource): IO[Boolean] = {
    getAcl(subjectId, resource)
      .flatMap {
      case None => IO.pure(false)
      case _ => IO.pure(true)
    }
{'fraction_non_alphanumeric': 0.12582781456953643, 'fraction_numerical': 0.0012417218543046358, 'mean_word_length': 2.900726392251816, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 15, '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': '5046284', 'n_tokens_mistral': 1678, 'n_tokens_neox': 1613, 'n_words': 249}