package jwt import ( "fmt" "github.com/pkg/errors" ) // revoke is an internal method that adds a token to the blacklist database. // Once revoked, the token will fail validation checks even if it hasn't expired. // This operation must be performed within a database transaction. func (gen *TokenGenerator) revoke(tx DBTransaction, t Token) error { if gen.beginTx == nil { return errors.New("No DB provided, unable to use this function") } tableName := gen.tableConfig.TableName jti := t.GetJTI() exp := t.GetEXP() sub := t.GetSUB() query := fmt.Sprintf("INSERT INTO %s (jti, exp, sub) VALUES (?, ?, ?)", tableName) _, err := tx.Exec(query, jti.String(), exp, sub) if err != nil { return errors.Wrap(err, "tx.ExecContext") } return nil } // checkNotRevoked is an internal method that queries the blacklist to verify // a token hasn't been revoked. Returns true if the token is valid (not blacklisted), // false if it has been revoked. This operation must be performed within a database transaction. func (gen *TokenGenerator) checkNotRevoked(tx DBTransaction, t Token) (bool, error) { if gen.beginTx == nil { return false, errors.New("No DB provided, unable to use this function") } tableName := gen.tableConfig.TableName jti := t.GetJTI() query := fmt.Sprintf("SELECT 1 FROM %s WHERE jti = ? LIMIT 1", tableName) rows, err := tx.Query(query, jti.String()) if err != nil { return false, errors.Wrap(err, "tx.QueryContext") } defer rows.Close() exists := rows.Next() if err := rows.Err(); err != nil { return false, errors.Wrap(err, "rows iteration") } return !exists, nil }