Files
ocis/ocis-pkg/mfa/mfa.go
Julian Koberg 824a71dbe2 feat: clean up mfa middleware
Signed-off-by: Julian Koberg <julian.koberg@kiteworks.com>
2025-09-17 15:56:04 +02:00

63 lines
1.6 KiB
Go

// Package mfa provides functionality for multi-factor authentication (MFA).
package mfa
import (
"context"
"net/http"
)
// MFAHeader is the header to be used across grpc and http services
// to forward the access token.
const MFAHeader = "X-Multi-Factor-Authentication"
// MFARequiredHeader is the header returned by the server if step-up authentication is required.
const MFARequiredHeader = "X-Ocis-Mfa-Required"
type mfaKeyType struct{}
var mfaKey = mfaKeyType{}
// FromRequest extracts the mfa status from the request headers
func FromRequest(ctx context.Context, req *http.Request) context.Context {
return Set(ctx, req.Header.Get(MFAHeader) == "true")
}
// Accepted checks if the context has MFA authentication. If not, it sets the required header and status code.
func Accepted(ctx context.Context, w http.ResponseWriter) bool {
hasMFA := Has(ctx)
if !hasMFA {
SetRequiredHeader(w)
}
return hasMFA
}
// Has returns true if the user is MFA authenticated.
func Has(ctx context.Context) bool {
mfa, ok := ctx.Value(mfaKey).(bool)
if !ok {
return false
}
return mfa
}
// Set stores the mfa status in the context.
func Set(ctx context.Context, mfa bool) context.Context {
return context.WithValue(ctx, mfaKey, mfa)
}
// SetHeader sets the MFA header.
func SetHeader(r *http.Request, mfa bool) {
if mfa {
r.Header.Set(MFAHeader, "true")
return
}
r.Header.Set(MFAHeader, "false")
}
// SetRequiredHeader sets the MFA required header and the statuscode to 403
func SetRequiredHeader(w http.ResponseWriter) {
w.Header().Set(MFARequiredHeader, "true")
w.WriteHeader(http.StatusForbidden)
}