Phase 3: OpenSubsonic core (response envelope, error codes 42-44, getOpenSubsonicExtensions) and apiKeyAuthentication extension with tokenInfo, web API key management
This commit is contained in:
@@ -22,9 +22,22 @@ import (
|
||||
// surface never reintroduces MD5 or plaintext as VibeSonic's own storage
|
||||
// format, it only speaks it on the wire where the protocol requires it.
|
||||
func authenticate(db *sql.DB, encryptionKey []byte, p params) (*database.User, *apiError) {
|
||||
username, aerr := p.Required("u")
|
||||
if aerr != nil {
|
||||
return nil, aerr
|
||||
apiKey := p.Get("apiKey")
|
||||
username := p.Get("u")
|
||||
|
||||
if apiKey != "" {
|
||||
// The apiKeyAuthentication extension requires a client not send
|
||||
// 'u' alongside 'apiKey' — accepting both would leave it
|
||||
// ambiguous which identity the caller actually intended, so this
|
||||
// is rejected outright rather than silently preferring one.
|
||||
if username != "" {
|
||||
return nil, errConflictingAuth
|
||||
}
|
||||
return authenticateAPIKey(db, apiKey)
|
||||
}
|
||||
|
||||
if username == "" {
|
||||
return nil, errMissingParameter("u")
|
||||
}
|
||||
|
||||
user, err := database.GetUserByUsername(db, username)
|
||||
@@ -75,6 +88,24 @@ func authenticate(db *sql.DB, encryptionKey []byte, p params) (*database.User, *
|
||||
return user, nil
|
||||
}
|
||||
|
||||
// authenticateAPIKey implements the OpenSubsonic apiKeyAuthentication
|
||||
// extension: the key is hashed the same way as VibeSonic's own web
|
||||
// settings API keys (they are exactly the same keys — one system, not a
|
||||
// parallel one) and looked up by hash, never by scanning stored keys in
|
||||
// plaintext.
|
||||
func authenticateAPIKey(db *sql.DB, rawKey string) (*database.User, *apiError) {
|
||||
key, err := database.GetAPIKeyByHash(db, vsauth.HashAPIKey(rawKey))
|
||||
if err != nil {
|
||||
return nil, errInvalidAPIKey
|
||||
}
|
||||
user, err := database.GetUserByID(db, key.UserID)
|
||||
if err != nil || user.Disabled {
|
||||
return nil, errInvalidAPIKey
|
||||
}
|
||||
_ = database.TouchAPIKey(db, key.ID)
|
||||
return user, nil
|
||||
}
|
||||
|
||||
// checkVersion rejects clients whose declared protocol version is newer
|
||||
// than what this server implements. A missing or unparsable v is
|
||||
// tolerated (treated as compatible) rather than rejected outright, to
|
||||
|
||||
Reference in New Issue
Block a user