mirror of
https://github.com/opencloud-eu/opencloud.git
synced 2026-01-05 19:59:37 -06:00
106 lines
3.1 KiB
Go
106 lines
3.1 KiB
Go
package middleware
|
|
|
|
import (
|
|
"github.com/owncloud/ocis/proxy/pkg/user/backend"
|
|
"net/http"
|
|
|
|
tokenPkg "github.com/cs3org/reva/pkg/token"
|
|
"github.com/cs3org/reva/pkg/token/manager/jwt"
|
|
revauser "github.com/cs3org/reva/pkg/user"
|
|
"github.com/owncloud/ocis/ocis-pkg/log"
|
|
"github.com/owncloud/ocis/ocis-pkg/oidc"
|
|
)
|
|
|
|
// AccountResolver provides a middleware which mints a jwt and adds it to the proxied request based
|
|
// on the oidc-claims
|
|
func AccountResolver(optionSetters ...Option) func(next http.Handler) http.Handler {
|
|
options := newOptions(optionSetters...)
|
|
logger := options.Logger
|
|
|
|
return func(next http.Handler) http.Handler {
|
|
tokenManager, err := jwt.New(map[string]interface{}{
|
|
"secret": options.TokenManagerConfig.JWTSecret,
|
|
"expires": int64(60),
|
|
})
|
|
if err != nil {
|
|
logger.Fatal().Err(err).Msgf("Could not initialize token-manager")
|
|
}
|
|
|
|
return &accountResolver{
|
|
next: next,
|
|
logger: logger,
|
|
tokenManager: tokenManager,
|
|
userProvider: options.UserProvider,
|
|
autoProvisionAccounts: options.AutoprovisionAccounts,
|
|
}
|
|
}
|
|
}
|
|
|
|
type accountResolver struct {
|
|
next http.Handler
|
|
logger log.Logger
|
|
tokenManager tokenPkg.Manager
|
|
userProvider backend.UserBackend
|
|
autoProvisionAccounts bool
|
|
}
|
|
|
|
func (m accountResolver) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
|
claims := oidc.FromContext(req.Context())
|
|
u, ok := revauser.ContextGetUser(req.Context())
|
|
|
|
if claims == nil && !ok {
|
|
m.next.ServeHTTP(w, req)
|
|
return
|
|
}
|
|
|
|
if u == nil && claims != nil {
|
|
var claim, value string
|
|
switch {
|
|
case claims.Email != "":
|
|
claim, value = "mail", claims.Email
|
|
case claims.PreferredUsername != "":
|
|
claim, value = "username", claims.PreferredUsername
|
|
case claims.OcisID != "":
|
|
//claim, value = "id", claims.OcisID
|
|
default:
|
|
// TODO allow lookup by custom claim, eg an id ... or sub
|
|
m.logger.Error().Msg("Could not lookup account, no mail or preferred_username claim set")
|
|
w.WriteHeader(http.StatusInternalServerError)
|
|
}
|
|
|
|
var err error
|
|
u, err = m.userProvider.GetUserByClaims(req.Context(), claim, value, true)
|
|
|
|
if m.autoProvisionAccounts && err == backend.ErrAccountNotFound {
|
|
m.logger.Debug().Interface("claims", claims).Interface("user", u).Msgf("User by claim not found... autoprovisioning.")
|
|
u, err = m.userProvider.CreateUserFromClaims(req.Context(), claims)
|
|
}
|
|
|
|
if err == backend.ErrAccountNotFound || err == backend.ErrAccountDisabled {
|
|
m.logger.Debug().Interface("claims", claims).Interface("user", u).Msgf("Unautorized")
|
|
w.WriteHeader(http.StatusUnauthorized)
|
|
return
|
|
}
|
|
|
|
if err != nil {
|
|
m.logger.Error().Err(err).Msg("Could not get user by claim")
|
|
w.WriteHeader(http.StatusInternalServerError)
|
|
return
|
|
}
|
|
|
|
m.logger.Debug().Interface("claims", claims).Interface("user", u).Msgf("associated claims with uuid")
|
|
}
|
|
|
|
token, err := m.tokenManager.MintToken(req.Context(), u)
|
|
|
|
if err != nil {
|
|
m.logger.Error().Err(err).Msgf("could not mint token")
|
|
w.WriteHeader(http.StatusInternalServerError)
|
|
return
|
|
}
|
|
|
|
req.Header.Set(tokenPkg.TokenHeader, token)
|
|
|
|
m.next.ServeHTTP(w, req)
|
|
}
|