mirror of
https://github.com/jech/galene.git
synced 2024-11-22 08:35:57 +01:00
Reliably return an error from token.Parse.
We would sometimes return nil cast to an interface with no error, which would cause the server to crash with a null dereference.
This commit is contained in:
parent
dc8a78be32
commit
3c0dbf5e9b
4 changed files with 55 additions and 6 deletions
|
@ -120,7 +120,7 @@ func toStringArray(a []interface{}) ([]string, bool) {
|
||||||
return b, true
|
return b, true
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseJWT(token string, keys []map[string]interface{}) (Token, error) {
|
func parseJWT(token string, keys []map[string]interface{}) (*JWT, error) {
|
||||||
t, err := jwt.Parse(token, func(t *jwt.Token) (interface{}, error) {
|
t, err := jwt.Parse(token, func(t *jwt.Token) (interface{}, error) {
|
||||||
return getKey(t.Header, keys)
|
return getKey(t.Header, keys)
|
||||||
})
|
})
|
||||||
|
|
|
@ -55,11 +55,14 @@ func SetStatefulFilename(filename string) {
|
||||||
tokens.modTime = time.Time{}
|
tokens.modTime = time.Time{}
|
||||||
}
|
}
|
||||||
|
|
||||||
func getStateful(token string) (Token, error) {
|
func getStateful(token string) (*Stateful, error) {
|
||||||
tokens.mu.Lock()
|
tokens.mu.Lock()
|
||||||
defer tokens.mu.Unlock()
|
defer tokens.mu.Unlock()
|
||||||
err := tokens.load()
|
err := tokens.load()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
if os.IsNotExist(err) {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if tokens.tokens == nil {
|
if tokens.tokens == nil {
|
||||||
|
|
|
@ -2,6 +2,7 @@ package token
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
"os"
|
||||||
)
|
)
|
||||||
|
|
||||||
var ErrUsernameRequired = errors.New("username required")
|
var ErrUsernameRequired = errors.New("username required")
|
||||||
|
@ -11,9 +12,23 @@ type Token interface {
|
||||||
}
|
}
|
||||||
|
|
||||||
func Parse(token string, keys []map[string]interface{}) (Token, error) {
|
func Parse(token string, keys []map[string]interface{}) (Token, error) {
|
||||||
t, err := getStateful(token)
|
// both getStateful and parseJWT may return nil, which we
|
||||||
if err == nil && t != nil {
|
// shouldn't cast into an interface. Be very careful.
|
||||||
return t, nil
|
s, err1 := getStateful(token)
|
||||||
|
if err1 == nil && s != nil {
|
||||||
|
return s, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
jwt, err2 := parseJWT(token, keys)
|
||||||
|
if err2 == nil && jwt != nil {
|
||||||
|
return jwt, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if err1 != nil {
|
||||||
|
return nil, err1
|
||||||
|
} else if err2 != nil {
|
||||||
|
return nil, err2
|
||||||
|
} else {
|
||||||
|
return nil, os.ErrNotExist
|
||||||
}
|
}
|
||||||
return parseJWT(token, keys)
|
|
||||||
}
|
}
|
||||||
|
|
31
token/token_test.go
Normal file
31
token/token_test.go
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
package token
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
"path/filepath"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestBad(t *testing.T) {
|
||||||
|
d := t.TempDir()
|
||||||
|
tokens = state{
|
||||||
|
filename: filepath.Join(d, "test.jsonl"),
|
||||||
|
}
|
||||||
|
f, err := os.OpenFile(tokens.filename,
|
||||||
|
os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0600,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Create: %v", err)
|
||||||
|
}
|
||||||
|
defer f.Close()
|
||||||
|
|
||||||
|
token, err := Parse("foo", nil)
|
||||||
|
if err == nil {
|
||||||
|
t.Errorf("Expected error, got %v", token)
|
||||||
|
}
|
||||||
|
|
||||||
|
token, err = Parse("foo", []map[string]interface{}{})
|
||||||
|
if err == nil {
|
||||||
|
t.Errorf("Expected error, got %v", token)
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue