Skip to content

Commit

Permalink
Merge pull request #1188 from Mee-Tree/fix/masking
Browse files Browse the repository at this point in the history
fix: Masking for contramapped loggables
  • Loading branch information
dos65 authored May 7, 2024
2 parents 8581ef7 + b6de562 commit fe3acc9
Show file tree
Hide file tree
Showing 5 changed files with 120 additions and 197 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package tofu.logging.derivation

import java.time.LocalDate
import java.util.UUID

import derevo.derive
import tofu.logging.derivation.MaskMode.Custom

object DerivedLoggableSamples {
@derive(loggable)
final case class Foo(lol: String, kek: Option[Long])

@derive(loggable)
final case class Bar(
@hidden foo1: Option[Foo] = None,
@unembed foo2: Option[Foo] = None,
foo3: Option[Foo] = None
)

@derive(loggable)
final case class Jak(
@masked(MaskMode.Erase) one: String,
@masked(MaskMode.ForLength(1)) two: Long,
@masked(MaskMode.Regexp("\\d*\\.(\\d*)".r)) three: Double,
@masked(MaskMode.Regexp("-?\\d*\\.(\\d*)".r)) four: List[Double],
)

@derive(loggable)
final case class Baz(foos: List[Foo] = Nil, ys: Vector[Int] = Vector(), zs: Option[List[List[String]]] = None)

@derive(loggable)
final case class MaskedBaz(@masked kek: Option[String], @ignoreOpt a: Option[String] = None)

@derive(loggable)
final case class MaskedOptBaz(
@masked maybeStr: Option[String],
@masked maybeInt: Option[Int],
@masked maybeBool: Option[Boolean],
@masked maybeDouble: Option[Double],
@masked maybeStr2: Option[String]
)

@derive(loggable)
final case class MaskedCustom(
@masked(Custom(_ => "*")) sensitiveField: String,
@masked(Custom(name => name.take(1) + "***")) firstName: Option[String],
@masked(Custom(i => "*" * i.length())) age: Int
)

@derive(loggable)
final case class MaskedContra(
@masked(MaskMode.Erase) id: UUID,
@masked(MaskMode.ForLength(4)) date: LocalDate,
)
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package tofu.logging
package derivation

import java.time.LocalDate
import java.util.UUID

import tofu.logging.derivation.MaskMode.Custom

object DerivedLoggableSamples:
final case class Foo(lol: String, kek: Option[Long]) derives Loggable

final case class Bar(
@hidden foo1: Option[Foo] = None,
@unembed foo2: Option[Foo] = None,
foo3: Option[Foo] = None
) derives Loggable

final case class Jak(
@masked(MaskMode.Erase) one: String,
@masked(MaskMode.ForLength(1)) two: Long,
@masked(MaskMode.Regexp("\\d*\\.(\\d*)".r)) three: Double,
@masked(MaskMode.Regexp("-?\\d*\\.(\\d*)".r)) four: List[Double],
) derives Loggable

final case class Baz(foos: List[Foo] = Nil, ys: Vector[Int] = Vector(), zs: Option[List[List[String]]] = None)
derives Loggable

final case class MaskedBaz(@masked kek: Option[String], @ignoreOpt a: Option[String] = None) derives Loggable

final case class MaskedOptBaz(
@masked maybeStr: Option[String],
@masked maybeInt: Option[Int],
@masked maybeBool: Option[Boolean],
@masked maybeDouble: Option[Double],
@masked maybeStr2: Option[String]
) derives Loggable

final case class MaskedCustom(
@masked(Custom(_ => "*")) sensitiveField: String,
@masked(Custom(name => name.take(1) + "***")) firstName: Option[String],
@masked(Custom(i => "*" * i.length())) age: Int
) derives Loggable

final case class MaskedContra(
@masked(MaskMode.Erase) id: UUID,
@masked(MaskMode.ForLength(4)) date: LocalDate,
) derives Loggable
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
package tofu.logging
package derivation

import java.time.LocalDate
import java.util.UUID

import org.scalatest.flatspec.AnyFlatSpec
import org.scalatest.matchers.should.Matchers
import tofu.logging.derivation.MaskMode.Custom

class DerivedLoggableSuite extends AnyFlatSpec with Matchers {

import DerivedLoggableSuite._
import DerivedLoggableSamples._

val foo = Foo("zaz", Some(1))

Expand Down Expand Up @@ -97,47 +99,10 @@ class DerivedLoggableSuite extends AnyFlatSpec with Matchers {
Loggable[MaskedCustom].logShow(maskedCustom) shouldBe
"MaskedCustom{sensitiveField=*,firstName=Some(J***),age=**}"
}
}

object DerivedLoggableSuite {
final case class Foo(lol: String, kek: Option[Long]) derives Loggable

final case class Bar(
@hidden foo1: Option[Foo] = None,
@unembed foo2: Option[Foo] = None,
foo3: Option[Foo] = None
) derives Loggable

final case class Jak(
@masked(MaskMode.Erase) one: String,
@masked(MaskMode.ForLength(1)) two: Long,
@masked(MaskMode.Regexp("\\d*\\.(\\d*)".r)) three: Double,
@masked(MaskMode.Regexp("-?\\d*\\.(\\d*)".r)) four: List[Double],
) derives Loggable

final case class Baz(foos: List[Foo] = Nil, ys: Vector[Int] = Vector(), zs: Option[List[List[String]]] = None)
derives Loggable

final case class MaskedBaz(@masked kek: Option[String], @ignoreOpt a: Option[String] = None) derives Loggable

final case class MaskedOptBaz(
@masked maybeStr: Option[String],
@masked maybeInt: Option[Int],
@masked maybeBool: Option[Boolean],
@masked maybeDouble: Option[Double],
@masked maybeStr2: Option[String]
) derives Loggable

final case class MaskedCustom(
@masked(Custom(_ => "*")) sensitiveField: String,
@masked(Custom(maskName)) firstName: Option[String],
@masked(Custom(maskAge)) age: Int
) derives Loggable

def maskName(name: String): String =
name.take(1) + "***"

def maskAge(i: String): String =
"*" * i.length

"MaskedContra logging" should "mask fields" in {
json(
MaskedContra(UUID.randomUUID(), LocalDate.of(2023, 12, 1))
) shouldBe """{"id":"...","date":"2023-##-##"}"""
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,14 @@ class ContramapLoggable[A, B](val self: Loggable.Base[A], val f: B => A) extends
def fields[I, V, R, M](b: B, input: I)(implicit receiver: LogRenderer[I, V, R, M]): R = self.fields(f(b), input)
def putValue[I, V, R, M](a: B, v: V)(implicit r: LogRenderer[I, V, R, M]): M = self.putValue(f(a), v)

override def putField[I, V, R, M](a: B, name: String, input: I)(implicit receiver: LogRenderer[I, V, R, M]): R =
override def putField[I, V, R, M](a: B, name: String, input: I)(implicit receiver: LogRenderer[I, V, R, M]): R =
self.putField(f(a), name, input)
override def logVia(a: B, addParam: (String, Any) => Unit): Unit = self.logVia(f(a), addParam)
override def logShow(a: B): String = self.logShow(f(a))
override def contramap[C](g: C => B): Loggable[C] = self.contramap(AndThen(g).andThen(f))
override def logVia(a: B, addParam: (String, Any) => Unit): Unit = self.logVia(f(a), addParam)
override def logShow(a: B): String = self.logShow(f(a))
override def contramap[C](g: C => B): Loggable[C] = self.contramap(AndThen(g).andThen(f))
override def putMaskedValue[I, V, R, M](b: B, v: V)(m: String => String)(implicit r: LogRenderer[I, V, R, M]): M =
self.putMaskedValue(f(b), v)(m)
override def putMaskedField[I, V, R, M](b: B, name: String, input: I)(m: String => String)(implicit
receiver: LogRenderer[I, V, R, M]
): R = self.putMaskedField(f(b), name, input)(m)
}

0 comments on commit fe3acc9

Please sign in to comment.