Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add log masking feature #138

Open
wants to merge 15 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions code/src/main/kotlin/com/expediagroup/sdk/core/common/Feature.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/*
* Copyright (C) 2024 Expedia, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.expediagroup.sdk.core.common
Mohammad-Dwairi marked this conversation as resolved.
Show resolved Hide resolved

/**
* Interface representing a feature that can be enabled.
* Implementations of this interface should provide the logic for enabling the feature.
*/
internal interface Feature {
/**
* Enables the feature.
* This method should contain the logic required to activate or enable the feature.
*/
fun enable()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*
* Copyright (C) 2024 Expedia, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.expediagroup.sdk.core.logging.masking

import com.expediagroup.sdk.core.common.Feature

/**
* Interface representing the configuration for masking.
*/
internal abstract class AbstractLogMaskingFeature: Feature {
/**
* A set of globally masked fields.
*
* @return A set of strings representing the global masked fields.
*/
open val globalMaskedFields: Set<String>
get() = emptySet()

/**
* A set of path-specific masked fields.
*
* @return A set of lists of strings representing the path masked fields.
*/
open val pathMaskedFields: Set<List<String>>
get() = emptySet()

override fun enable() {
mask.addPatternIfNotExists(
*MaskingPatternBuilder().apply {
globalFields(*globalMaskedFields.toTypedArray())
pathFields(*pathMaskedFields.toTypedArray())
}.build().toTypedArray()
)
}
}

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
/*
* Copyright (C) 2024 Expedia, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.expediagroup.sdk.core.logging.masking
Mohammad-Dwairi marked this conversation as resolved.
Show resolved Hide resolved

import com.ebay.ejmask.api.MaskingPattern

/**
* Interface for pattern-based masking.
*/
internal interface PatternBasedMask : (String) -> String {
/**
* Adds masking patterns if they do not already exist.
*
* @param maskingPatterns Vararg of MaskingPattern to be added.
* @return True if patterns were added, false if they already existed.
*/
fun addPatternIfNotExists(vararg maskingPatterns: MaskingPattern): Boolean

/**
* Retrieves the list of current masking patterns.
*
* @return A list of MaskingPattern.
*/
fun patterns(): List<MaskingPattern>

/**
* Clears all existing masking patterns.
*/
fun clear()
}

/**
* Object implementing the PatternBasedMask interface.
*/
internal val mask = object : PatternBasedMask {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need this to be an object? Couldn't we build and pass the masking configs somewhere?

val patterns: MutableList<MaskingPattern> = mutableListOf()

/**
* Applies all masking patterns to the input string.
*
* @param input The input string to be masked.
* @return The masked string.
*/
override fun invoke(input: String): String {
var masked = input

patterns.forEach { pattern: MaskingPattern ->
masked = pattern.replaceAll(masked)
}

return masked
}

/**
* Retrieves the list of current masking patterns.
*
* @return A list of MaskingPattern.
*/
override fun patterns() =
this.patterns.toList()

/**
* Clears all existing masking patterns.
*/
override fun clear() {
patterns.clear()
}

/**
* Adds masking patterns if they do not already exist.
*
* @param maskingPatterns Vararg of MaskingPattern to be added.
* @return True if patterns were added, false if they already existed.
*/
override fun addPatternIfNotExists(vararg maskingPatterns: MaskingPattern): Boolean {
var addedPattern = false

maskingPatterns.forEach newPatterns@{ pattern ->
patterns.forEach existingPatterns@{
val patternExists = (it.pattern.pattern() == pattern.pattern.pattern())
.and(it.replacement == pattern.replacement)

if (patternExists) {
return@newPatterns
}
}

patterns.add(pattern).also { addedPattern = true }
}

return addedPattern
}
}

This file was deleted.

Loading