1
\$\begingroup\$

Introduction

At this moment in time, I'm in the process of creating some fluent interface, as a result, I've created a DSL style solution for authentication & authorisation.

As a result, the consuming code-base may look something along the lines of this:

public class Demo {

    public String login() throws IllegalStateException {
        JWTState jwt = beginAuth()
                        .authentication()
                        .username("JoeBloggs")
                        .password("Secure_Pa$$w0rD!-#0962")
                        .authenticate()
                        .whenAuthenticationFails(e -> log.error("Authentication failure", e))
                    .then()
                        .authorisation()
                        .adGroup("Basic")
                        .authorise()
                        .whenAuthorisationFails(e -> log.error("Authorisation failure", e))
                    .then()
                        .jwt()
                        .generateJwt()
                        .whenJwtFails(e -> log.error("Unable to generate JWT", e))
                        .getJwt();

        // Safety net, rather than return null or an empty string, throw this exception
        return Optional.of(jwt.isValid())
                .filter(Boolean::valueOf)
                .map(x -> jwt.token())
                .orElseThrow(() -> new IllegalStateException("Unable to generate JWT"));
    }
}

Defensive Example

Since I've gone with a defensive approach, the consuming code-base does not need to worry about exceptions that are thrown, since they're handled internally. Although, these exceptions can be visible to the consuming code upon request, as you can see with the 'whenXFails' methods. Internally, there's a lot of logic going on, an example being one of the guard clauses, an example being this snippet from the password guard clause:

// Start of class....

@Override
public void validate(String password) throws IllegalArgumentException {
    argument(password).
            regex(VALID_PASSWORD_REGEX).
            message("Supplied password is null").whenNull().
            message("Supplied password is empty").whenEmpty().
            message("Supplied password is too short").whenLessThan(MINIMUM_PASSWORD_LENGTH).
            message("Supplied password is too long").whenGreaterThan(MAXIMUM_PASSWORD_LENGTH).
            message("Supplied password does not match the valid password regex").whenNoRegexMatch();
}

// End of class....

To ensure that there's a good ability to log errors & debug this code-base, I've tried to handle nearly every scenario I can think of, expected & unexpected. In which case, you can see above that there are many specific cases where the password validation will fail, but from the consumer's perspective this isn't necessarily visible.

In the event that the consuming code-base wishes to proceed through this unit of work, it will merely alter the current state. Referring back to the Demo class, in the event of some failure, the getJwt() method will return some JWTState such as InvalidJWTState, this is to ensure that something is always returned to the consumer, meaning that the consumer need not check for null values. I've also taken the time to apply the null object design pattern to improve the defensiveness of this code.


Conclusion

Before I ramble on & on, I'd just like to cut to the chase, first off, in this instance, am I applying good practices? If not can anyone make any recommendations on how I could improve the overall quality of this code-base? Secondly, are there better methods that I'm merely not aware of?

\$\endgroup\$
4
  • 2
    \$\begingroup\$ This statement As a result, the consuming code-base may look something along the lines of this: indicates that the code is not concrete from a working project. That makes this question off-topic for code review. \$\endgroup\$
    – pacmaninbw
    Commented Mar 19, 2020 at 17:02
  • \$\begingroup\$ @pacmaninbw This code is in a prototype phase, I just wanted to get an idea of what other developers thought about the approach, etc. It will however be used in several working projects as a part of a very large & on-going migration project. \$\endgroup\$ Commented Mar 20, 2020 at 7:43
  • \$\begingroup\$ Well, I understand your sentiment, but Code Review is for specific code from a specific project. So it sounds like you're simply at the wrong place until you have one of those projects close-to-finished (to the point where you can say whether that piece of the code works or not). \$\endgroup\$
    – Mast
    Commented Mar 20, 2020 at 8:58
  • \$\begingroup\$ this is no valid piece of code to review, just some snippets and ideas - it's not possible to review this question (-1) \$\endgroup\$ Commented Mar 20, 2020 at 9:00

0

Browse other questions tagged or ask your own question.