diff --git a/java-plugin/src/main/java/fr/greencodeinitiative/java/checks/CookieWithoutExpirationRule.java b/java-plugin/src/main/java/fr/greencodeinitiative/java/checks/CookieWithoutExpirationRule.java new file mode 100644 index 00000000..4e7dd54f --- /dev/null +++ b/java-plugin/src/main/java/fr/greencodeinitiative/java/checks/CookieWithoutExpirationRule.java @@ -0,0 +1,100 @@ +package fr.greencodeinitiative.java.checks; +import java.util.*; + + +import org.sonar.check.Priority; +import org.sonar.check.Rule; +import org.sonar.java.model.declaration.VariableTreeImpl; +import org.sonar.plugins.java.api.IssuableSubscriptionVisitor; +import org.sonar.plugins.java.api.tree.*; +import org.sonar.plugins.java.api.tree.Tree.Kind; + + +@Rule( + key = "CRJVM207-JAVA", + name = "Developpement", + description = CookieWithoutExpirationRule.MESSAGERULE, + priority = Priority.MINOR, + tags = {"smell"}) + +public class CookieWithoutExpirationRule extends IssuableSubscriptionVisitor { + + protected static final String MESSAGERULE = "Customer data must have end-of-life information, so cookies must have a maxAge"; + + + @Override + public List nodesToVisit() { + return Collections.singletonList(Tree.Kind.CLASS); + } + private final CookieWithoutExpirationRuleCheckVisitor visitorInFile = new CookieWithoutExpirationRuleCheckVisitor(); + + + @Override + public void visitNode(Tree tree) { + + tree.accept(visitorInFile); + //Class visitor + if (visitorInFile.hasANewCookieWithoutMaxDate()) + { + //if we found a cookie that maxDate is not initialized, we report issue + reportIssue(tree, "MaxAge must have a value"); + } + } + + private class CookieWithoutExpirationRuleCheckVisitor extends BaseTreeVisitor { + + + // storage of variable name for setMaxAge + private ArrayList hasSetMaxAgeForCookiesVariableName = new ArrayList<>(); + // storage of variable name for New Cookies + private ArrayList newCookieVariableName = new ArrayList<>(); + @Override + public void visitReturnStatement(ReturnStatementTree tree) { + this.scan(tree.expression()); + } + + @Override + public void visitVariable(VariableTree tree) { + //when we visit variable affectation + for (Tree children : ((VariableTreeImpl) tree).children()) + { + //if we found an affectation + if (children.is(Tree.Kind.NEW_CLASS) + && ((IdentifierTree)((NewClassTree)children).identifier()).toString().equals("Cookie")) + { + //if this is a New Cookie affectation, we store the name of the variable + this.newCookieVariableName.add(tree.simpleName().toString()); + } + else + super.visitVariable(tree); + } + } + + + public boolean hasANewCookieWithoutMaxDate() + { + //loop on variables on which a new Cookie was done + for (String variableName : newCookieVariableName ) + { + if (!hasSetMaxAgeForCookiesVariableName.contains(variableName)) + //no setMaxAge has been done + return true; + } + return false; + } + @Override + public void visitMethodInvocation(MethodInvocationTree tree) { + //Method visiting + if (tree.methodSelect().is(Kind.MEMBER_SELECT) && + (((MemberSelectExpressionTree)tree.methodSelect()).identifier().name().equals("setMaxAge")) + ) + { + //if visited methode is setMaxAge, then save the assigned variable + hasSetMaxAgeForCookiesVariableName.add(((MemberSelectExpressionTree)tree.methodSelect()).expression().toString()); + } + + } + + + } +} \ No newline at end of file diff --git a/java-plugin/src/test/files/CookieWithoutExpirationCheck.java b/java-plugin/src/test/files/CookieWithoutExpirationCheck.java new file mode 100644 index 00000000..46fb0857 --- /dev/null +++ b/java-plugin/src/test/files/CookieWithoutExpirationCheck.java @@ -0,0 +1,34 @@ +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; + +class TestClass {// Noncompliant {{MaxAge must have a value}} + + public void NOK_CookieCreation() { + // create objet cookie + Cookie A = new Cookie("id","674684641"); + } + + public Cookie NOK_ReturnCookieCreation() { + // create objet cookie + Cookie A = new Cookie("id","674684641"); + return A; + } + public void OK_CookieCreation() { + // create objet cookie + Cookie B = new Cookie("id","674684641"); + // set the validity + B.setMaxAge(24*3600); + + } + + public void OK_CookieCreation2() { + // create objet cookie + Cookie C; + C = new Cookie("id","674684641"); + // set the validity + C.setMaxAge(24*3600); + + } + +} \ No newline at end of file diff --git a/java-plugin/src/test/java/fr/greencodeinitiative/java/checks/CookieWithExpirationCheckTest.java b/java-plugin/src/test/java/fr/greencodeinitiative/java/checks/CookieWithExpirationCheckTest.java new file mode 100644 index 00000000..648f5927 --- /dev/null +++ b/java-plugin/src/test/java/fr/greencodeinitiative/java/checks/CookieWithExpirationCheckTest.java @@ -0,0 +1,20 @@ +package fr.greencodeinitiative.java.checks; + +import org.junit.jupiter.api.Test; +import org.sonar.java.checks.verifier.CheckVerifier; +import org.sonar.plugins.java.api.JavaFileScanner; + +class CookieWithExpirationCheckTest { + + /** + * @formatter:off + */ + @Test + void test() { + CheckVerifier.newVerifier() + .onFile("src/test/files/CookieWithoutExpirationCheck.java") + .withCheck(new CookieWithoutExpirationRule()) + .verifyIssues(); + } + +} \ No newline at end of file