From 28cc6136481c556243b7f499dd1e27b37a737f8d Mon Sep 17 00:00:00 2001
From: ale <ale@incal.net>
Date: Mon, 17 Oct 2022 16:53:06 +0100
Subject: [PATCH] Store login authenticator IDs in lastlogin table

---
 protocol.go         |  8 +++++---
 server/lastlogin.go | 25 ++++++++++++++-----------
 server/sql.go       |  9 +++++++++
 3 files changed, 28 insertions(+), 14 deletions(-)

diff --git a/protocol.go b/protocol.go
index 37bf082..6d302e8 100644
--- a/protocol.go
+++ b/protocol.go
@@ -127,9 +127,11 @@ type GetUserLogsResponse struct {
 }
 
 type LastLoginEntry struct {
-	Timestamp time.Time `json:"timestamp"`
-	Username  string    `json:"username"`
-	Service   string    `json:"service"`
+	Timestamp            time.Time `json:"timestamp"`
+	Username             string    `json:"username"`
+	Service              string    `json:"service"`
+	LoginMethod          string    `json:"login_method,omitempty"`
+	LoginAuthenticatorID string    `json:"login_authenticator_id,omitempty"`
 }
 
 func (e *LastLoginEntry) Validate() error {
diff --git a/server/lastlogin.go b/server/lastlogin.go
index c1fce41..181c0d6 100644
--- a/server/lastlogin.go
+++ b/server/lastlogin.go
@@ -15,20 +15,20 @@ import (
 var lastloginDBStatements = map[string]string{
 	"insert_or_replace_last_login": `
 		INSERT OR REPLACE INTO lastlogin (
-			username, service, timestamp
+			username, service, timestamp, login_method, login_authenticator_id
 		) VALUES (
-			?, ?, ?
+			?, ?, ?, ?, ?
 		)`,
 	"get_service_last_login": `
 		SELECT
-			username, service, timestamp
+			username, service, timestamp, login_method, login_authenticator_id
 		FROM
 			lastlogin
 		WHERE
 			username = ? AND service = ?`,
 	"get_last_login": `
 		SELECT
-			username, service, timestamp
+			username, service, timestamp, login_method, login_authenticator_id
 		FROM
 			lastlogin
 		WHERE
@@ -58,14 +58,15 @@ func (l *lastloginDB) AddLastLogin(ctx context.Context, entry *usermetadb.LastLo
 		return err
 	}
 
-	args := []interface{}{
-		entry.Username,
-		entry.Service,
-		roundTimestamp(entry.Timestamp),
-	}
-
 	return sqlutil.WithTx(ctx, l.db, func(tx *sql.Tx) error {
-		_, err := tx.Exec(lastloginDBStatements["insert_or_replace_last_login"], args...)
+		_, err := tx.Exec(
+			lastloginDBStatements["insert_or_replace_last_login"],
+			entry.Username,
+			entry.Service,
+			roundTimestamp(entry.Timestamp),
+			entry.LoginMethod,
+			entry.LoginAuthenticatorID,
+		)
 		return err
 	})
 }
@@ -100,6 +101,8 @@ func (l *lastloginDB) GetLastLogin(ctx context.Context, username string, service
 				&e.Username,
 				&e.Service,
 				&e.Timestamp,
+				&e.LoginMethod,
+				&e.LoginAuthenticatorID,
 			); err != nil {
 				return err
 			}
diff --git a/server/sql.go b/server/sql.go
index 1c7b3da..9fdb5ef 100644
--- a/server/sql.go
+++ b/server/sql.go
@@ -88,6 +88,15 @@ PRAGMA foreign_keys=on;
 `),
 	sqlutil.Statement(`
 ALTER TABLE userlog ADD COLUMN login_authenticator_id TEXT;
+`),
+	sqlutil.Statement(`
+ALTER TABLE lastlogin ADD COLUMN login_method TEXT;
+`, `
+ALTER TABLE lastlogin ADD COLUMN login_authenticator_id TEXT;
+`, `
+DROP INDEX idx_lastlogin_username_service;
+`, `
+CREATE UNIQUE INDEX idx_lastlogin_username_service_method_authenticator_id ON lastlogin (username, service, login_method, login_authenticator_id);
 `),
 }
 
-- 
GitLab