1
0
mirror of https://github.com/owncloud/ocis.git synced 2026-10-23 23:29:02 +03:00
Files
ocis/services/proxy/pkg/middleware/basic_auth.go
Roman Perekhod 2e377bde67 fix: [OCISDEV-1476] fix AuthApp requests failing with a custom PROXY_… (#13078) (#13107)
* fix: [OCISDEV-1476] fix AuthApp requests failing with a custom PROXY_USER_OIDC_CLAIM

* fix: [OCISDEV-1476] map ErrAccountNotFound to 401 in verifyUser

AccountResolver.verifyUser only mapped ErrAccountDisabled to 401 before
falling through to a generic 500. The identity backend excludes disabled
accounts from by-username lookups and returns ErrAccountNotFound instead,
so a disabled user authenticating via AppAuth or basic auth got a 500
instead of a 401, caught by the acceptance test suite.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
2026-10-09 13:37:34 +00:00

71 lines
2.4 KiB
Go

package middleware
import (
"net/http"
"github.com/owncloud/ocis/v2/ocis-pkg/log"
"github.com/owncloud/ocis/v2/services/proxy/pkg/user/backend"
"github.com/owncloud/ocis/v2/services/proxy/pkg/userroles"
revactx "github.com/owncloud/reva/v2/pkg/ctx"
)
// BasicAuthenticator is the authenticator responsible for HTTP Basic authentication.
type BasicAuthenticator struct {
Logger log.Logger
UserProvider backend.UserBackend
UserRoleAssigner userroles.UserRoleAssigner
MultiInstanceEnabled bool
}
// Authenticate implements the authenticator interface to authenticate requests via basic auth.
func (m BasicAuthenticator) Authenticate(r *http.Request) (*http.Request, error) {
if isPublicPath(r.URL.Path) && isPublicWithShareToken(r) {
// The authentication of public path requests is handled by another authenticator.
// Since we can't guarantee the order of execution of the authenticators, we better
// implement an early return here for paths we can't authenticate in this authenticator.
return nil, ErrAuthenticationFailed
}
if m.MultiInstanceEnabled {
// Basic auth credentials carry no OIDC claims, so there is no way to
// verify tenant membership (OCIS_MULTI_INSTANCE_MEMBER_CLAIM/GUEST_CLAIM)
// for them. Reject rather than let the request bypass the tenant
// check in services/proxy/pkg/middleware/account_resolver.go's
// resolveUserType.
return nil, ErrAuthenticationFailed
}
login, password, ok := r.BasicAuth()
if !ok {
return nil, ErrAuthenticationFailed
}
user, _, err := m.UserProvider.Authenticate(r.Context(), login, password)
if err != nil {
m.Logger.Error().
Err(err).
Str("authenticator", "basic").
Str("path", r.URL.Path).
Msg("failed to authenticate request")
return nil, ErrAuthenticationFailed
}
user, err = m.UserRoleAssigner.ApplyUserRole(r.Context(), user)
if err != nil {
m.Logger.Error().
Err(err).
Str("authenticator", "basic").
Str("path", r.URL.Path).
Msg("could not apply user role")
return nil, ErrAuthenticationFailed
}
m.Logger.Debug().
Str("authenticator", "basic").
Str("path", r.URL.Path).
Msg("successfully authenticated request")
// the user is already authenticated, put it into the context directly
// instead of faking oidc claims for the account resolver to re-resolve.
return r.WithContext(revactx.ContextSetUser(r.Context(), user)), nil
}