Class PasskeyStore

java.lang.Object
com.iizix.server.user.passkey.PasskeyStore

public final class PasskeyStore extends Object
The passkeys in the server database (CC-LOGIN-L8-PASSKEYS): the tables IZS.USER_HANDLES and IZS.USER_CREDENTIALS of createPasskeyTables.sql beside this class, created here at the first use on a database of any age - the server's createBaseTables.sql runs on an empty database only (the model is the load balancer's DBLoadBalancer.createTables).

The column recovery of IZS.USER_CREDENTIALS came after the table (CC-LOGIN-PASSKEY-SECOND-FACTOR, T1-039): a table that was created without it gains it here, by ALTER TABLE ... ADD COLUMN, nullable, so that the passkeys already stored keep NULL in it, which is read as no (the model is the Push engine's SubscriptionStore.ensureSchema).

Every method takes a pooled connection of its own, commits what it wrote, and returns the connection. A row of a user goes with the user: the foreign keys delete it.

Author:
Christopher Mindus
  • Field Summary

    Fields
    Modifier and Type
    Field
    Description
    static final String
    The schema and the table probed to tell whether the script ran: the LAST table it creates.
    static final String
    The schema and the table probed to tell whether the script ran: the LAST table it creates.
    static final String
    The name of the SQL script beside this class.
  • Method Summary

    Modifier and Type
    Method
    Description
    static boolean
    Creates the passkey tables if required, on the connection given, which is committed when they are created.
    find(byte[] credentialId)
    Finds a passkey by its credential ID.
    static long
    findUser(byte[] handle)
    Finds the user of a user handle.
    static String
    Gets the class-loader resource name of the SQL script.
    static byte[]
    getUserHandle(long userID)
    Gets the WebAuthn user handle of a user, made when the user has none: 64 random bytes.
    static boolean
    Stores a new passkey.
    list(long userID, String rpId)
    Lists the passkeys of a user for a relying party, the newest first.
    static boolean
    recordUse(StoredPasskey passkey, long signCount, boolean backedUp, long now)
    Records a use of a passkey: the signature counter, the backup state and the time.
    static boolean
    remove(long userID, String key)
    Removes a passkey of a user.
    static int
    removeAll(Connection conn, long userID)
    Removes every passkey of a user inside the caller's transaction, whatever the relying party: the development reset of the administrator (DevelopmentAdminReset).
    static boolean
    rename(long userID, String key, String nickname)
    Renames a passkey of a user.
    static void
    Forgets that the tables exist: the next use probes the database again.
  • Field Details

    • SCHEMA

      public static final String SCHEMA
      The schema and the table probed to tell whether the script ran: the LAST table it creates.
      See Also:
    • PROBE_TABLE

      public static final String PROBE_TABLE
      The schema and the table probed to tell whether the script ran: the LAST table it creates.
      See Also:
    • SCRIPT

      public static final String SCRIPT
      The name of the SQL script beside this class.
      See Also:
  • Method Details

    • getScriptResource

      public static String getScriptResource()
      Gets the class-loader resource name of the SQL script.
      Returns:
      The resource name, com/iizix/server/user/passkey/createPasskeyTables.sql.
    • createTables

      public static boolean createTables(Connection conn) throws SQLException
      Creates the passkey tables if required, on the connection given, which is committed when they are created. Two servers on one database may both try: the one that finds a table made in the meantime by the other probes again and goes on. A table of passkeys that was created without the column recovery gains it.
      Parameters:
      conn - The connection.
      Returns:
      true if they were created here, false when they existed.
      Throws:
      SQLException - For SQL errors.
    • reset

      public static void reset()
      Forgets that the tables exist: the next use probes the database again. For a server whose connection pool was replaced, and for tests.
    • getUserHandle

      public static byte[] getUserHandle(long userID) throws SQLException
      Gets the WebAuthn user handle of a user, made when the user has none: 64 random bytes.
      Parameters:
      userID - The user ID.
      Returns:
      The user handle.
      Throws:
      SQLException - For SQL errors, among them a user that does not exist.
    • findUser

      public static long findUser(byte[] handle) throws SQLException
      Finds the user of a user handle.
      Parameters:
      handle - The user handle.
      Returns:
      The user ID, -1 when no user has the handle.
      Throws:
      NullPointerException - If handle is null.
      SQLException - For SQL errors.
    • find

      public static StoredPasskey find(byte[] credentialId) throws SQLException
      Finds a passkey by its credential ID.
      Parameters:
      credentialId - The credential ID.
      Returns:
      The passkey, null when there is none.
      Throws:
      NullPointerException - If credentialId is null.
      SQLException - For SQL errors.
    • list

      public static List<StoredPasskey> list(long userID, String rpId) throws SQLException
      Lists the passkeys of a user for a relying party, the newest first.
      Parameters:
      userID - The user ID.
      rpId - The relying party ID.
      Returns:
      The passkeys, empty when the user has none.
      Throws:
      SQLException - For SQL errors.
    • insert

      public static boolean insert(StoredPasskey passkey) throws SQLException
      Stores a new passkey.
      Parameters:
      passkey - The passkey.
      Returns:
      true when it is stored, false when a passkey with its credential ID exists - for this user or for any other.
      Throws:
      NullPointerException - If passkey is null.
      SQLException - For SQL errors.
    • recordUse

      public static boolean recordUse(StoredPasskey passkey, long signCount, boolean backedUp, long now) throws SQLException
      Records a use of a passkey: the signature counter, the backup state and the time. The counter is written only when it is the stored one still, so that of two uses of one counter value the second is refused.
      Parameters:
      passkey - The passkey as it was read.
      signCount - The signature counter of the assertion.
      backedUp - The backup state of the assertion.
      now - The time of the use, epoch milliseconds.
      Returns:
      true when the use is recorded, false when the passkey is gone or its counter moved since it was read.
      Throws:
      NullPointerException - If passkey is null.
      SQLException - For SQL errors.
    • rename

      public static boolean rename(long userID, String key, String nickname) throws SQLException
      Renames a passkey of a user.
      Parameters:
      userID - The user ID.
      key - The key of the passkey, StoredPasskey.key.
      nickname - The new name.
      Returns:
      true when it is renamed, false when the user has no such passkey.
      Throws:
      SQLException - For SQL errors.
    • remove

      public static boolean remove(long userID, String key) throws SQLException
      Removes a passkey of a user.
      Parameters:
      userID - The user ID.
      key - The key of the passkey, StoredPasskey.key.
      Returns:
      true when it is removed, false when the user has no such passkey.
      Throws:
      SQLException - For SQL errors.
    • removeAll

      public static int removeAll(Connection conn, long userID) throws SQLException
      Removes every passkey of a user inside the caller's transaction, whatever the relying party: the development reset of the administrator (DevelopmentAdminReset). Nothing is committed here. A database without the table has no passkey to remove: the table is looked for, never created, and its absence is not an error. The user handle stays.
      Parameters:
      conn - The connection of the caller's transaction.
      userID - The user ID.
      Returns:
      The number of passkeys removed.
      Throws:
      SQLException - For SQL errors.