owncast/auth/persistence.go
Gabe Kangas a082cf3a77
Fediverse-based authentication (#1846)
* Able to authenticate user against IndieAuth. For #1273

* WIP server indieauth endpoint. For https://github.com/owncast/owncast/issues/1272

* Add migration to remove access tokens from user

* Add authenticated bool to user for display purposes

* Add indieauth modal and auth flair to display names. For #1273

* Validate URLs and display errors

* Renames, cleanups

* Handle relative auth endpoint paths. Add error handling for missing redirects.

* Disallow using display names in use by registered users. Closes #1810

* Verify code verifier via code challenge on callback

* Use relative path to authorization_endpoint

* Post-rebase fixes

* Use a timestamp instead of a bool for authenticated

* Propertly handle and display error in modal

* Use auth'ed timestamp to derive authenticated flag to display in chat

* Fediverse chat auth via OTP

* Increase validity time just in case

* Add fediverse auth into auth modal

* Text, validation, cleanup updates for fedi auth

* Fix typo

* Remove unused images

* Remove unused file

* Add chat display name to auth modal text
2022-04-22 17:23:14 -07:00

79 lines
1.9 KiB
Go

package auth
import (
"context"
"strings"
"github.com/owncast/owncast/core/data"
"github.com/owncast/owncast/core/user"
log "github.com/sirupsen/logrus"
"github.com/owncast/owncast/db"
)
var _datastore *data.Datastore
// Setup will initialize auth persistence.
func Setup(db *data.Datastore) {
_datastore = db
createTableSQL := `CREATE TABLE IF NOT EXISTS auth (
"id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
"user_id" TEXT NOT NULL,
"token" TEXT NOT NULL,
"type" TEXT NOT NULL,
"timestamp" DATE DEFAULT CURRENT_TIMESTAMP NOT NULL,
FOREIGN KEY(user_id) REFERENCES users(id)
);CREATE INDEX auth_token ON auth (token);`
stmt, err := db.DB.Prepare(createTableSQL)
if err != nil {
log.Fatal(err)
}
defer stmt.Close()
_, err = stmt.Exec()
if err != nil {
log.Fatalln(err)
}
}
// AddAuth will add an external authentication token and type for a user.
func AddAuth(userID, authToken string, authType Type) error {
return _datastore.GetQueries().AddAuthForUser(context.Background(), db.AddAuthForUserParams{
UserID: userID,
Token: authToken,
Type: string(authType),
})
}
// GetUserByAuth will return an existing user given auth details if a user
// has previously authenticated with that method.
func GetUserByAuth(authToken string, authType Type) *user.User {
u, err := _datastore.GetQueries().GetUserByAuth(context.Background(), db.GetUserByAuthParams{
Token: authToken,
Type: string(authType),
})
if err != nil {
log.Errorln(err)
return nil
}
var scopes []string
if u.Scopes.Valid {
scopes = strings.Split(u.Scopes.String, ",")
}
return &user.User{
ID: u.ID,
DisplayName: u.DisplayName,
DisplayColor: int(u.DisplayColor),
CreatedAt: u.CreatedAt.Time,
DisabledAt: &u.DisabledAt.Time,
PreviousNames: strings.Split(u.PreviousNames.String, ","),
NameChangedAt: &u.NamechangedAt.Time,
AuthenticatedAt: &u.AuthenticatedAt.Time,
Scopes: scopes,
}
}