2020-06-03 14:51:02 +01:00
|
|
|
// Copyright (C) 2020 Storj Labs, Inc.
|
|
|
|
// See LICENSE for copying information.
|
|
|
|
|
|
|
|
package satellitedb
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"fmt"
|
|
|
|
|
|
|
|
"github.com/zeebo/errs"
|
|
|
|
|
2021-08-12 17:26:43 +01:00
|
|
|
"storj.io/common/lrucache"
|
2020-06-03 14:51:02 +01:00
|
|
|
"storj.io/storj/satellite/satellitedb/dbx"
|
|
|
|
)
|
|
|
|
|
|
|
|
type revocationDB struct {
|
|
|
|
db *satelliteDB
|
2021-04-23 13:59:10 +01:00
|
|
|
lru *lrucache.ExpiringLRU
|
2020-06-03 14:51:02 +01:00
|
|
|
methods dbx.Methods
|
|
|
|
}
|
|
|
|
|
2020-07-16 15:18:02 +01:00
|
|
|
// Revoke will revoke the supplied tail.
|
2020-06-03 14:51:02 +01:00
|
|
|
func (db *revocationDB) Revoke(ctx context.Context, tail []byte, apiKeyID []byte) error {
|
|
|
|
return errs.Wrap(db.methods.CreateNoReturn_Revocation(ctx, dbx.Revocation_Revoked(tail), dbx.Revocation_ApiKeyId(apiKeyID)))
|
|
|
|
}
|
|
|
|
|
2020-07-16 15:18:02 +01:00
|
|
|
// Check will check whether any of the supplied tails have been revoked.
|
2020-06-03 14:51:02 +01:00
|
|
|
func (db *revocationDB) Check(ctx context.Context, tails [][]byte) (bool, error) {
|
|
|
|
numTails := len(tails)
|
|
|
|
if numTails == 0 {
|
|
|
|
return false, errs.New("Empty list of tails")
|
|
|
|
}
|
|
|
|
|
2020-06-22 21:14:23 +01:00
|
|
|
// The finalTail is the last tail provided in the macaroon. We cache the
|
|
|
|
// revocation status of this final tail so that, if this macaroon is used
|
|
|
|
// again before the cache key expires, we do not have to check the database
|
|
|
|
// again.
|
2020-06-03 14:51:02 +01:00
|
|
|
finalTail := tails[numTails-1]
|
|
|
|
|
|
|
|
val, err := db.lru.Get(string(finalTail), func() (interface{}, error) {
|
2022-02-22 14:41:20 +00:00
|
|
|
const query = "SELECT EXISTS(SELECT 1 FROM revocations WHERE revoked IN (%s))"
|
2020-06-03 14:51:02 +01:00
|
|
|
|
|
|
|
var (
|
|
|
|
tailQuery, comma string
|
|
|
|
tailsForQuery = make([]interface{}, numTails)
|
|
|
|
revoked bool
|
|
|
|
)
|
|
|
|
|
|
|
|
for i, tail := range tails {
|
|
|
|
if i == 1 {
|
|
|
|
comma = ","
|
|
|
|
}
|
|
|
|
tailQuery += fmt.Sprintf("%s$%d", comma, i+1)
|
|
|
|
tailsForQuery[i] = tail
|
|
|
|
}
|
|
|
|
|
|
|
|
row := db.db.QueryRowContext(ctx, fmt.Sprintf(query, tailQuery), tailsForQuery...)
|
|
|
|
err := row.Scan(&revoked)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return revoked, nil
|
|
|
|
})
|
|
|
|
if err != nil {
|
|
|
|
return false, errs.Wrap(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
revoked, ok := val.(bool)
|
|
|
|
if !ok {
|
|
|
|
return false, errs.New("Revoked not a bool")
|
|
|
|
}
|
|
|
|
|
|
|
|
return revoked, nil
|
|
|
|
}
|