diff --git a/data/device_database.go b/data/device_database.go new file mode 100644 index 0000000..fa7b737 --- /dev/null +++ b/data/device_database.go @@ -0,0 +1,135 @@ +package data + +import ( + "database/sql" + "fmt" + "path/filepath" + "time" + + "github.com/google/uuid" + _ "github.com/mattn/go-sqlite3" +) + +type DeviceDatabase struct { + Connection *sql.DB + databaseDirectory string +} + +func (db *DeviceDatabase) Initialize() error { + connection, error := sql.Open("sqlite3", filepath.Join(db.databaseDirectory, "devices.db")) + if error != nil { + return error + } + db.Connection = connection + + _, error = db.Connection.Exec(`CREATE TABLE IF NOT EXISTS devices ( + id TEXT PRIMARY KEY, + device_name TEXT UNIQUE, + description TEXT, + )`) + if error != nil { + return fmt.Errorf("error creating devices table: %s", error) + } + + _, error = db.Connection.Exec(`CREATE TABLE IF NOT EXISTS sessions ( + token TEXT PRIMARY KEY, + device_id INTEGER, + expiry_date TIMESTAMP, + FOREIGN KEY (device_id) REFERENCES devices(id) + )`) + if error != nil { + return fmt.Errorf("error creating device sessions table: %s", error) + } + return nil +} + +func (db *DeviceDatabase) Close() error { + return db.Connection.Close() +} +func (db *DeviceDatabase) CreateDevice(device_name string, description string) (string, error) { + deviceID := uuid.New() + _, err := db.Connection.Exec("INSERT INTO devices (id, device_name, description) VALUES (?, ?, ?)", deviceID.String(), device_name, description) + return deviceID.String(), err +} + +func (db *DeviceDatabase) CreateSession(deviceID string, expiryDate time.Time) (string, error) { + sessionToken := uuid.New() + _, err := db.Connection.Exec("INSERT INTO sessions (device_id, token, expiry_date) VALUES (?, ?, ?)", deviceID, sessionToken.String(), expiryDate) + if err != nil { + return "", err + } + return sessionToken.String(), nil +} + +func (db *DeviceDatabase) GetDeviceById(id string) (*PlaybackDevice, error) { + var device PlaybackDevice + err := db.Connection.QueryRow("SELECT id, device_name, description FROM devices WHERE id = ?", id).Scan(&device.ID, &device.Name, &device.Description) + if err != nil { + return nil, err + } + return &device, nil +} + +func (db *DeviceDatabase) DeviceIdExists(id string) (bool, error) { + var exists bool + err := db.Connection.QueryRow("SELECT EXISTS(SELECT 1 FROM devices WHERE id = ?)", id).Scan(&exists) + if err != nil { + return false, err + } + return exists, nil +} + +func (db *DeviceDatabase) UpdateDevice(device *PlaybackDevice) error { + _, err := db.Connection.Exec("UPDATE devices SET name = ?, description = ? WHERE id = ?", device.Name, device.Description, device.ID) + return err +} + +func (db *DeviceDatabase) GetSession(sessionToken string) (*DeviceSession, error) { + var session DeviceSession + row := db.Connection.QueryRow("SELECT token, device_id, expiry_date FROM sessions WHERE token = ?", sessionToken) + err := row.Scan(&session.Token, &session.DeviceID, &session.ExpiryDate) + if err != nil { + if err == sql.ErrNoRows { + return nil, nil + } + return nil, err + } + return &session, nil +} + +func (db *DeviceDatabase) DeleteSessionByToken(token string) error { + _, err := db.Connection.Exec("DELETE FROM sessions WHERE token = ?", token) + return err +} + +func (db *DeviceDatabase) GetDevices() (*[]PlaybackDevice, error) { + var devices []PlaybackDevice + + rows, err := db.Connection.Query("SELECT id, device_name, description FROM devices") + if err != nil { + return nil, err + } + defer rows.Close() + + for rows.Next() { + var device PlaybackDevice + err := rows.Scan(&device.ID, &device.Name, &device.Description) + if err != nil { + if err == sql.ErrNoRows { + return nil, nil + } + return nil, err + } + devices = append(devices, device) + } + return &devices, nil +} + +func (db *DeviceDatabase) DeleteDevice(ID string) error { + _, err := db.Connection.Exec("DELETE FROM devices WHERE id = ?", ID) + return err +} + +func (db *DeviceDatabase) SetDirectory(directory string) { + db.databaseDirectory = directory +} diff --git a/data/device_session.go b/data/device_session.go new file mode 100644 index 0000000..2f55a33 --- /dev/null +++ b/data/device_session.go @@ -0,0 +1,9 @@ +package data + +import "time" + +type DeviceSession struct { + DeviceID string + Token string + ExpiryDate time.Time +} diff --git a/data/playback_device.go b/data/playback_device.go new file mode 100644 index 0000000..0d86353 --- /dev/null +++ b/data/playback_device.go @@ -0,0 +1,7 @@ +package data + +type PlaybackDevice struct { + ID string `json:"id"` + Name string `json:"name"` + Description string `json:"description"` +} diff --git a/data/user_database.go b/data/user_database.go index 4cd52ac..b326614 100644 --- a/data/user_database.go +++ b/data/user_database.go @@ -136,8 +136,8 @@ func (db *UserDatabase) CheckCredentials(username, password string) (bool, error return true, nil } -func (db *UserDatabase) GetSession(sessionToken string) (*Session, error) { - var session Session +func (db *UserDatabase) GetSession(sessionToken string) (*UserSession, error) { + var session UserSession row := db.Connection.QueryRow("SELECT token, user_id, expiry_date FROM sessions WHERE token = ?", sessionToken) err := row.Scan(&session.Token, &session.UserID, &session.ExpiryDate) if err != nil { diff --git a/data/session.go b/data/user_session.go similarity index 77% rename from data/session.go rename to data/user_session.go index c776617..352b73e 100644 --- a/data/session.go +++ b/data/user_session.go @@ -2,7 +2,7 @@ package data import "time" -type Session struct { +type UserSession struct { UserID string Token string ExpiryDate time.Time diff --git a/management/user_manager.go b/management/user_manager.go index 134b7ac..2c0f171 100644 --- a/management/user_manager.go +++ b/management/user_manager.go @@ -110,7 +110,7 @@ func (um *UserManager) Login(username, password string) (string, error) { return token, nil } -func (um *UserManager) GetSession(sessionToken string) (*d.Session, error) { +func (um *UserManager) GetSession(sessionToken string) (*d.UserSession, error) { session, error := um.userDatabase.GetSession(sessionToken) if error != nil { return nil, error diff --git a/server/authenticator.go b/server/authenticator.go index ca13ee5..a1bec72 100644 --- a/server/authenticator.go +++ b/server/authenticator.go @@ -13,7 +13,7 @@ import ( type AuthContext struct { echo.Context User *d.User - Session *d.Session + Session *d.UserSession } type Authenticator struct {