Use pattern match on instanceof
[aaa.git] / aaa-shiro / impl / src / main / java / org / opendaylight / aaa / shiro / filters / AuthenticationTokenUtils.java
1 /*
2  * Copyright (c) 2016 - 2017 Brocade Communications Systems, Inc. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8 package org.opendaylight.aaa.shiro.filters;
9
10 import static java.util.Objects.requireNonNull;
11
12 import org.apache.shiro.authc.AuthenticationToken;
13 import org.apache.shiro.authc.UsernamePasswordToken;
14
15 /**
16  * Utility methods for forming audit trail output based on an <code>AuthenticationToken</code>.
17  */
18 public final class AuthenticationTokenUtils {
19
20     /**
21      * default value used in messaging when the "user" field is unparsable from the HTTP REST request.
22      */
23     static final String DEFAULT_USERNAME = "an unknown user";
24
25     /**
26      * default value used in messaging when the "user" field is not present in the HTTP REST request, implying
27      * a different implementation of <code>AuthenticationToken</code> such as <code>CasToken</code>.
28      */
29     static final String DEFAULT_TOKEN = "an un-parsable token type";
30
31     /**
32      * default value used in messaging when the "host" field cannot be determined.
33      */
34     static final String DEFAULT_HOSTNAME = "an unknown host";
35
36     private AuthenticationTokenUtils() {
37         // private to prevent instantiation
38     }
39
40     /**
41      * Determines whether the supplied <code>Token</code> is a <code>UsernamePasswordToken</code>.
42      *
43      * @param token A generic <code>Token</code>, which might be a <code>UsernamePasswordToken</code>
44      * @return Whether the supplied <code>Token</code> is a <code>UsernamePasswordToken</code>
45      */
46     public static boolean isUsernamePasswordToken(final AuthenticationToken token) {
47         return token instanceof UsernamePasswordToken;
48     }
49
50     /**
51      * Extracts the username if possible.  If the supplied token is a <code>UsernamePasswordToken</code>
52      * and the username field is not set, <code>DEFAULT_USERNAME</code> is returned.  If the supplied
53      * token is not a <code>UsernamePasswordToken</code> (i.e., a <code>CasToken</code> or other
54      * implementation of <code>AuthenticationToken</code>), then <code>DEFAULT_TOKEN</code> is
55      * returned.
56      *
57      * @param token An <code>AuthenticationToken</code>, possibly a <code>UsernamePasswordToken</code>
58      * @return the username, <code>DEFAULT_USERNAME</code> or <code>DEFAULT_TOKEN</code> depending on input
59      */
60     public static String extractUsername(final AuthenticationToken token) {
61         if (token instanceof UsernamePasswordToken upt) {
62             return extractField(upt.getUsername(), DEFAULT_USERNAME);
63         }
64         return DEFAULT_TOKEN;
65     }
66
67     /**
68      * Extracts the hostname if possible.  If the supplied token is a <code>UsernamePasswordToken</code>
69      * and the hostname field is not set, <code>DEFAULT_HOSTNAME</code> is returned.  If the supplied
70      * token is not a <code>UsernamePasswordToken</code> (i.e., a <code>CasToken</code> or other
71      * implementation of <code>AuthenticationToken</code>), then <code>DEFAULT_HOSTNAME</code> is
72      * returned.
73      *
74      * @param token An <code>AuthenticationToken</code>, possibly a <code>UsernamePasswordToken</code>
75      * @return the hostname, or <code>DEFAULT_USERNAME</code> depending on input
76      */
77     public static String extractHostname(final AuthenticationToken token) {
78         if (token instanceof UsernamePasswordToken upt) {
79             return extractField(upt.getHost(), DEFAULT_HOSTNAME);
80         }
81         return DEFAULT_HOSTNAME;
82     }
83
84     /**
85      * Utility method to generate a generic message indicating Authentication was unsuccessful.
86      *
87      * @param token An <code>AuthenticationToken</code>, possibly a <code>UsernamePasswordToken</code>
88      * @return A message indicating authentication was unsuccessful
89      */
90     public static String generateUnsuccessfulAuthenticationMessage(final AuthenticationToken token) {
91         final String username = extractUsername(token);
92         final String remoteHostname = extractHostname(token);
93         return String.format("Unsuccessful authentication attempt by %s from %s", username, remoteHostname);
94     }
95
96     /**
97      * Utility method to generate a generic message indicating Authentication was successful.
98      *
99      * @param token An <code>AuthenticationToken</code>, possibly a <code>UsernamePasswordToken</code>
100      * @return A message indicating authentication was successful
101      */
102     public static String generateSuccessfulAuthenticationMessage(final AuthenticationToken token) {
103         final String username = extractUsername(token);
104         final String remoteHostname = extractHostname(token);
105         return String.format("Successful authentication attempt by %s from %s", username, remoteHostname);
106     }
107
108     /**
109      * Utility method that returns <code>field</code>, or <code>defaultValue</code> if <code>field</code> is null.
110      *
111      * @param field A generic string, which is possibly null.
112      * @param defaultValue A non-null value returned if <code>field</code> is null
113      * @return <code>field</code> or <code>defaultValue</code> if field is null
114      * @throws NullPointerException If <code>defaultValue</code> is null
115      */
116     private static String extractField(final String field, final String defaultValue) {
117         final String def = requireNonNull(defaultValue, "defaultValue can't be null");
118         return field != null ? field : def;
119     }
120 }