Skip to content
Merged
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
59 changes: 59 additions & 0 deletions src/main/java/us/kbase/auth2/lib/token/MFAStatus.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package us.kbase.auth2.lib.token;

import java.util.HashMap;
import java.util.Map;

/** An enumeration representing the multi-factor authentication status of a user's login. */
public enum MFAStatus {

/* first arg is ID, second arg is description. ID CANNOT change
* since that field is stored in the DB.
*/
/** User authenticated with MFA during token creation. */
USED ("Used", "MFA used"),
/** User explicitly chose not to use MFA when available. */
NOT_USED ("NotUsed", "MFA not used"),
/** MFA status unknown or not applicable to authentication method. */
UNKNOWN ("Unknown", "MFA status unknown");

private static final Map<String, MFAStatus> STATUS_MAP = new HashMap<>();
static {
for (final MFAStatus status: MFAStatus.values()) {
STATUS_MAP.put(status.getID(), status);
}
}

private final String id;
private final String description;

private MFAStatus(final String id, final String description) {
this.id = id;
this.description = description;
}

/** Get the ID of this MFA status.
* @return the ID.
*/
public String getID() {
return id;
}

/** Get the description of this MFA status.
* @return the description.
*/
public String getDescription() {
return description;
}

/** Get an MFA status from its ID.
* @param id the ID of the MFA status.
* @return the MFA status.
* @throws IllegalArgumentException if there is no MFA status matching the ID.
*/
public static MFAStatus fromID(final String id) {
if (!STATUS_MAP.containsKey(id)) {
throw new IllegalArgumentException("Invalid MFA status: " + id);
}
return STATUS_MAP.get(id);
}
}
64 changes: 64 additions & 0 deletions src/test/java/us/kbase/test/auth2/lib/token/MFAStatusTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package us.kbase.test.auth2.lib.token;

import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.fail;

import org.junit.Test;

import us.kbase.auth2.lib.token.MFAStatus;

public class MFAStatusTest {

@Test
public void testValues() {
final MFAStatus[] expected = {MFAStatus.USED, MFAStatus.NOT_USED, MFAStatus.UNKNOWN};
assertThat("incorrect values", MFAStatus.values(), is(expected));
}

@Test
public void testMFAStatusGetDescription() throws Exception {
assertThat("incorrect Used description", MFAStatus.USED.getDescription(),
is("MFA used"));
assertThat("incorrect NotUsed description", MFAStatus.NOT_USED.getDescription(),
is("MFA not used"));
assertThat("incorrect Unknown description", MFAStatus.UNKNOWN.getDescription(),
is("MFA status unknown"));
}

@Test
public void testMFAStatusIDsAreStableForSerialization() throws Exception {
// These IDs are persisted to database via JSON serialization and must never change.
// Changing these values would break backwards compatibility with existing tokens
// and user data stored in MongoDB.
assertThat("USED ID must be stable", MFAStatus.USED.getID(), is("Used"));
assertThat("NOT_USED ID must be stable", MFAStatus.NOT_USED.getID(), is("NotUsed"));
assertThat("UNKNOWN ID must be stable", MFAStatus.UNKNOWN.getID(), is("Unknown"));
}

@Test
public void testMFAStatusFromIDValidValues() throws Exception {
assertThat("incorrect fromID for Used", MFAStatus.fromID("Used"), is(MFAStatus.USED));
assertThat("incorrect fromID for NotUsed", MFAStatus.fromID("NotUsed"),
is(MFAStatus.NOT_USED));
assertThat("incorrect fromID for Unknown", MFAStatus.fromID("Unknown"),
is(MFAStatus.UNKNOWN));
}

@Test
public void testFromIDFail() throws Exception {
failFromId(null, "Invalid MFA status: null");
failFromId(" \t ", "Invalid MFA status: \t ");
failFromId("INVALID", "Invalid MFA status: INVALID");
failFromId("used", "Invalid MFA status: used");
}

private void failFromId(final String id, final String exception) {
try {
MFAStatus.fromID(id);
fail("expected exception");
} catch (IllegalArgumentException e) {
assertThat("correct exception message", e.getMessage(), is(exception));
}
}
}
Loading