Skip to content
Closed
Show file tree
Hide file tree
Changes from all 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
37 changes: 37 additions & 0 deletions allure-java-commons/src/main/java/io/qameta/allure/Secret.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*
* Copyright 2020 Qameta Software OÜ
*
* 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 io.qameta.allure;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
* Annotation to mark secret step method parameters that should be masked in the Allure report.
* Ex. For password or credit card data that shouldn't be displayed, add this to print ****** instead of the real value:
* <p/>
* <code>
* {@literal @}Step
* public void myStep(String username, {@literal @}Secret String password)
* </code>
*/
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.PARAMETER)
public @interface Secret {
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
*/
package io.qameta.allure.util;

import io.qameta.allure.Secret;
import io.qameta.allure.model.Parameter;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.reflect.MethodSignature;
Expand Down Expand Up @@ -80,10 +81,20 @@ public static Map<String, Object> getParametersMap(final JoinPoint joinPoint) {
return params;
}

/**
* Returns a list of parameters for the specified method. If any of the parameters are annotated with
* {@literal @}Secret, instead of returning the parameter's actual value, a mask of '******' will be returned.
*
* @param signature The method signature whose parameters we want to get.
* @param args The values of the method parameters.
* @return A list of Parameters containing the name and value of each method parameter.
*/
public static List<Parameter> getParameters(final MethodSignature signature, final Object... args) {
return IntStream
.range(0, args.length)
.mapToObj(index -> createParameter(signature.getParameterNames()[index], args[index]))
.mapToObj(index -> createParameter(
signature.getParameterNames()[index],
isSecretParameter(signature.getMethod().getParameters()[index]) ? "******" : args[index]))
.collect(Collectors.toList());
}

Expand All @@ -94,4 +105,14 @@ public static List<Parameter> getParameters(final MethodSignature signature, fin
public static String objectToString(final Object object) {
return ObjectUtils.toString(object);
}

/**
* Returns true if the specified method parameter has the {@literal @}Secret annotation.
*
* @param parameter The method parameter to check for the presence of the {@literal @}Secret annotation.
* @return True if the parameter is annotated with {@literal @}Secret, otherwise false.
*/
private static boolean isSecretParameter(java.lang.reflect.Parameter parameter) {
return (parameter.getAnnotation(Secret.class) != null);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
package io.qameta.allure.aspects;

import io.qameta.allure.Issue;
import io.qameta.allure.Secret;
import io.qameta.allure.Step;
import io.qameta.allure.model.Parameter;
import io.qameta.allure.model.Status;
Expand Down Expand Up @@ -115,6 +116,22 @@ void shouldAddParams() {
);
}

@SuppressWarnings("unchecked")
@Test
void shouldMaskSecretParams() {
final AllureResults results = runWithinTestContext(() -> stepWithSecretParams("first", "second"));

assertThat(results.getTestResults())
.hasSize(1)
.flatExtracting(TestResult::getSteps)
.flatExtracting(StepResult::getParameters)
.extracting(Parameter::getName, Parameter::getValue)
.containsExactlyInAnyOrder(
tuple("a", "first"),
tuple("b", "******")
);
}

@Test
void shouldUseOldStyleParams() {
final AllureResults results = runWithinTestContext(() -> stepWithOldStylePattern("hello", "world"));
Expand Down Expand Up @@ -301,6 +318,10 @@ void stepWithMethodPlaceholder() {
void stepWithParams(final String a, final String b) {
}

@Step
void stepWithSecretParams(final String a, @Secret final String b) {
}

@Step("go to {0} then to {1}")
void stepWithOldStylePattern(final String first, final String second) {
}
Expand Down