feat(api): add apikey support (#408)

* feat(api): add apikey support

* feat(web): api settings crud
This commit is contained in:
ze0s 2022-08-15 11:58:13 +02:00 committed by GitHub
parent 9c036033e9
commit fa20978d58
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
31 changed files with 834 additions and 70 deletions

114
internal/database/api.go Normal file
View file

@ -0,0 +1,114 @@
package database
import (
"context"
"database/sql"
"time"
"github.com/autobrr/autobrr/internal/domain"
"github.com/autobrr/autobrr/internal/logger"
"github.com/autobrr/autobrr/pkg/errors"
"github.com/lib/pq"
"github.com/rs/zerolog"
)
func NewAPIRepo(log logger.Logger, db *DB) domain.APIRepo {
return &APIRepo{
log: log.With().Str("repo", "api").Logger(),
db: db,
}
}
type APIRepo struct {
log zerolog.Logger
db *DB
cache map[string]domain.APIKey
}
func (r *APIRepo) Store(ctx context.Context, key *domain.APIKey) error {
queryBuilder := r.db.squirrel.
Insert("api_key").
Columns(
"name",
"key",
"scopes",
).
Values(
key.Name,
key.Key,
pq.Array(key.Scopes),
).
Suffix("RETURNING created_at").RunWith(r.db.handler)
var createdAt time.Time
if err := queryBuilder.QueryRowContext(ctx).Scan(&createdAt); err != nil {
return errors.Wrap(err, "error executing query")
}
key.CreatedAt = createdAt
return nil
}
func (r *APIRepo) Delete(ctx context.Context, key string) error {
queryBuilder := r.db.squirrel.
Delete("api_key").
Where("key = ?", key)
query, args, err := queryBuilder.ToSql()
if err != nil {
return errors.Wrap(err, "error building query")
}
_, err = r.db.handler.ExecContext(ctx, query, args...)
if err != nil {
return errors.Wrap(err, "error executing query")
}
r.log.Debug().Msgf("successfully deleted: %v", key)
return nil
}
func (r *APIRepo) GetKeys(ctx context.Context) ([]domain.APIKey, error) {
queryBuilder := r.db.squirrel.
Select(
"name",
"key",
"scopes",
"created_at",
).
From("api_key")
query, args, err := queryBuilder.ToSql()
if err != nil {
return nil, errors.Wrap(err, "error building query")
}
rows, err := r.db.handler.QueryContext(ctx, query, args...)
if err != nil {
return nil, errors.Wrap(err, "error executing query")
}
defer rows.Close()
keys := make([]domain.APIKey, 0)
for rows.Next() {
var a domain.APIKey
var name sql.NullString
if err := rows.Scan(&name, &a.Key, pq.Array(&a.Scopes), &a.CreatedAt); err != nil {
return nil, errors.Wrap(err, "error scanning row")
}
a.Name = name.String
keys = append(keys, a)
}
return keys, nil
}

View file

@ -315,6 +315,14 @@ CREATE TABLE feed_cache
value TEXT,
ttl TIMESTAMP
);
CREATE TABLE api_key
(
name TEXT,
key TEXT PRIMARY KEY,
scopes TEXT [] DEFAULT '{}' NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
`
var postgresMigrations = []string{
@ -541,4 +549,12 @@ CREATE INDEX indexer_identifier_index
ALTER TABLE filter
ADD COLUMN except_origins TEXT [] DEFAULT '{}';
`,
`CREATE TABLE api_key
(
name TEXT,
key TEXT PRIMARY KEY,
scopes TEXT [] DEFAULT '{}' NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
`,
}

View file

@ -298,6 +298,14 @@ CREATE TABLE feed_cache
value TEXT,
ttl TIMESTAMP
);
CREATE TABLE api_key
(
name TEXT,
key TEXT PRIMARY KEY,
scopes TEXT [] DEFAULT '{}' NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
`
var sqliteMigrations = []string{
@ -861,4 +869,12 @@ CREATE INDEX indexer_identifier_index
ALTER TABLE filter
ADD COLUMN except_origins TEXT [] DEFAULT '{}';
`,
`CREATE TABLE api_key
(
name TEXT,
key TEXT PRIMARY KEY,
scopes TEXT [] DEFAULT '{}' NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
`,
}