Skip to content

Commit 0e252d5

Browse files
committed
Add other auth commands
1 parent 191e171 commit 0e252d5

2 files changed

Lines changed: 111 additions & 27 deletions

File tree

backend/command/auth.go

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
package command
2+
3+
import (
4+
"errors"
5+
"log/slog"
6+
"time"
7+
8+
"github.com/theandrew168/bloggulus/backend/model"
9+
"github.com/theandrew168/bloggulus/backend/postgres"
10+
"github.com/theandrew168/bloggulus/backend/repository"
11+
"github.com/theandrew168/bloggulus/backend/timeutil"
12+
"github.com/theandrew168/bloggulus/backend/web/util"
13+
)
14+
15+
var ErrSessionNotFound = errors.New("session not found")
16+
17+
func (cmd *Command) SignIn(username string) (string, error) {
18+
// NOTE: Handling state outside the transaciton is the exception, not the rule.
19+
// This is a special case where a command needs to return a value (the session ID).
20+
var sessionID string
21+
err := cmd.repo.WithTransaction(func(tx *repository.Repository) error {
22+
account, err := tx.Account().ReadByUsername(username)
23+
if err != nil {
24+
if !errors.Is(err, postgres.ErrNotFound) {
25+
return err
26+
}
27+
28+
// We need to create a new account at this point.
29+
account, err = model.NewAccount(username)
30+
if err != nil {
31+
return err
32+
}
33+
34+
err = tx.Account().Create(account)
35+
if err != nil {
36+
return err
37+
}
38+
39+
slog.Info("account created",
40+
"account_id", account.ID(),
41+
)
42+
}
43+
44+
// Create a new session for the account.
45+
var session *model.Session
46+
session, sessionID, err = model.NewSession(account, util.SessionCookieTTL)
47+
if err != nil {
48+
return err
49+
}
50+
51+
err = tx.Session().Create(session)
52+
if err != nil {
53+
return err
54+
}
55+
56+
slog.Info("account signed in",
57+
"account_id", account.ID(),
58+
"session_id", session.ID(),
59+
)
60+
61+
return nil
62+
})
63+
64+
return sessionID, err
65+
}
66+
67+
func (cmd *Command) SignOut(sessionID string) error {
68+
return cmd.repo.WithTransaction(func(tx *repository.Repository) error {
69+
session, err := tx.Session().ReadBySessionID(sessionID)
70+
if err != nil {
71+
if !errors.Is(err, postgres.ErrNotFound) {
72+
return err
73+
}
74+
75+
return ErrSessionNotFound
76+
}
77+
78+
err = tx.Session().Delete(session)
79+
if err != nil {
80+
if !errors.Is(err, postgres.ErrNotFound) {
81+
return err
82+
}
83+
84+
return ErrSessionNotFound
85+
}
86+
87+
return nil
88+
})
89+
}
90+
91+
func (cmd *Command) DeleteExpiredSessions(now time.Time) error {
92+
return cmd.repo.WithTransaction(func(tx *repository.Repository) error {
93+
now := timeutil.Now()
94+
expiredSessions, err := tx.Session().ListExpired(now)
95+
if err != nil {
96+
return err
97+
}
98+
99+
for _, session := range expiredSessions {
100+
err := tx.Session().Delete(session)
101+
if err != nil {
102+
// Ignore any "not found" errors here.
103+
if !errors.Is(err, postgres.ErrNotFound) {
104+
return err
105+
}
106+
}
107+
}
108+
109+
return nil
110+
})
111+
}

backend/command/session.go

Lines changed: 0 additions & 27 deletions
This file was deleted.

0 commit comments

Comments
 (0)