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:
2026-08-23 08:04:01 -05:00
parent 3b4883780b
commit e38d31d384
17 changed files with 763 additions and 37 deletions
+23 -10
View File
@@ -1,16 +1,20 @@
package subsonic
// Error codes from the Subsonic REST API specification.
// Error codes from the Subsonic REST API specification, plus the
// OpenSubsonic apiKeyAuthentication extension's additions (42, 43, 44).
const (
ErrGeneric = 0
ErrMissingParameter = 10
ErrClientMustUpgrade = 20 // client's protocol version is newer than this server supports
ErrServerMustUpgrade = 30 // server requires a newer client
ErrWrongCredentials = 40
ErrTokenAuthNotSupported = 41 // e.g. LDAP-backed accounts with no local password
ErrUnauthorized = 50 // authenticated, but not permitted to perform this action
ErrTrialExpired = 60 // VibeSonic never returns this: no license is required
ErrNotFound = 70
ErrGeneric = 0
ErrMissingParameter = 10
ErrClientMustUpgrade = 20 // client's protocol version is newer than this server supports
ErrServerMustUpgrade = 30 // server requires a newer client
ErrWrongCredentials = 40
ErrTokenAuthNotSupported = 41 // e.g. LDAP-backed accounts with no local password
ErrAuthMechanismUnsupported = 42 // provided authentication mechanism not supported
ErrConflictingAuth = 43 // multiple conflicting authentication mechanisms provided
ErrInvalidAPIKey = 44
ErrUnauthorized = 50 // authenticated, but not permitted to perform this action
ErrTrialExpired = 60 // VibeSonic never returns this: no license is required
ErrNotFound = 70
)
// apiError is a Subsonic protocol error carrying an HTTP-agnostic code
@@ -21,6 +25,7 @@ const (
type apiError struct {
Code int
Message string
HelpURL string
}
func (e *apiError) Error() string { return e.Message }
@@ -29,6 +34,10 @@ func newError(code int, message string) *apiError {
return &apiError{Code: code, Message: message}
}
func newErrorWithHelp(code int, message, helpURL string) *apiError {
return &apiError{Code: code, Message: message, HelpURL: helpURL}
}
func errMissingParameter(name string) *apiError {
return newError(ErrMissingParameter, "Required parameter '"+name+"' is missing")
}
@@ -41,8 +50,12 @@ func errUnauthorized(action string) *apiError {
return newError(ErrUnauthorized, "User is not authorized for the requested "+action)
}
const apiKeyHelpURL = "/settings#api-keys"
var (
errWrongCredentials = newError(ErrWrongCredentials, "Wrong username or password")
errClientMustUpgrade = newError(ErrClientMustUpgrade, "Incompatible Subsonic REST protocol version. Client must upgrade.")
errTokenAuthNotSupported = newError(ErrTokenAuthNotSupported, "Token authentication is not supported for this account; use password authentication")
errConflictingAuth = newErrorWithHelp(ErrConflictingAuth, "Provide either 'u' (with 'p' or 't'/'s') or 'apiKey', not both", apiKeyHelpURL)
errInvalidAPIKey = newErrorWithHelp(ErrInvalidAPIKey, "Invalid API key", apiKeyHelpURL)
)