mirror of
https://github.com/zitadel/zitadel.git
synced 2025-08-12 03:57:32 +00:00
feat: handle instance from context (#3382)
* commander * commander * selber! * move to packages * fix(errors): implement Is interface * test: command * test: commands * add init steps * setup tenant * add default step yaml * possibility to set password * merge v2 into v2-commander * fix: rename iam command side to instance * fix: rename iam command side to instance * fix: rename iam command side to instance * fix: rename iam command side to instance * fix: search query builder can filter events in memory * fix: filters for add member * fix(setup): add `ExternalSecure` to config * chore: name iam to instance * fix: matching * remove unsued func * base url * base url * test(command): filter funcs * test: commands * fix: rename orgiampolicy to domain policy * start from init * commands * config * fix indexes and add constraints * fixes * fix: merge conflicts * fix: protos * fix: md files * setup * add deprecated org iam policy again * typo * fix search query * fix filter * Apply suggestions from code review * remove custom org from org setup * add todos for verification * change apps creation * simplify package structure * fix error * move preparation helper for tests * fix unique constraints * fix config mapping in setup * fix error handling in encryption_keys.go * fix projection config * fix query from old views to projection * fix setup of mgmt api * set iam project and fix instance projection * fix tokens view * fix steps.yaml and defaults.yaml * fix projections * change instance context to interface * instance interceptors and additional events in setup * cleanup * tests for interceptors * fix label policy * add todo * single api endpoint in environment.json Co-authored-by: adlerhurst <silvan.reusser@gmail.com> Co-authored-by: fabi <fabienne.gerschwiler@gmail.com>
This commit is contained in:
@@ -44,6 +44,7 @@ func New(
|
||||
},
|
||||
authZ internal_authz.Config,
|
||||
externalSecure bool,
|
||||
http2HostName string,
|
||||
) *API {
|
||||
verifier := internal_authz.Start(repo)
|
||||
api := &API{
|
||||
@@ -53,7 +54,7 @@ func New(
|
||||
router: router,
|
||||
externalSecure: externalSecure,
|
||||
}
|
||||
api.grpcServer = server.CreateServer(api.verifier, authZ, repo.Queries)
|
||||
api.grpcServer = server.CreateServer(api.verifier, authZ, repo.Queries, http2HostName)
|
||||
api.routeGRPC()
|
||||
|
||||
api.RegisterHandler("/debug", api.healthHandler())
|
||||
|
@@ -31,10 +31,6 @@ func (ctxData CtxData) IsZero() bool {
|
||||
return ctxData.UserID == "" || ctxData.OrgID == ""
|
||||
}
|
||||
|
||||
type Instance struct {
|
||||
ID string
|
||||
}
|
||||
|
||||
type Grants []*Grant
|
||||
|
||||
type Grant struct {
|
||||
@@ -116,15 +112,6 @@ func GetCtxData(ctx context.Context) CtxData {
|
||||
return ctxData
|
||||
}
|
||||
|
||||
func GetInstance(ctx context.Context) Instance {
|
||||
instance, _ := ctx.Value(instanceKey).(Instance)
|
||||
return instance
|
||||
}
|
||||
|
||||
func WithInstance(ctx context.Context, instance Instance) context.Context {
|
||||
return context.WithValue(ctx, instanceKey, instance)
|
||||
}
|
||||
|
||||
func GetRequestPermissionsFromCtx(ctx context.Context) []string {
|
||||
ctxPermission, _ := ctx.Value(requestPermissionsKey).([]string)
|
||||
return ctxPermission
|
||||
|
51
internal/api/authz/instance.go
Normal file
51
internal/api/authz/instance.go
Normal file
@@ -0,0 +1,51 @@
|
||||
package authz
|
||||
|
||||
import (
|
||||
"context"
|
||||
)
|
||||
|
||||
var (
|
||||
emptyInstance = &instance{}
|
||||
)
|
||||
|
||||
type Instance interface {
|
||||
InstanceID() string
|
||||
ProjectID() string
|
||||
ConsoleClientID() string
|
||||
}
|
||||
|
||||
type InstanceVerifier interface {
|
||||
InstanceByHost(context.Context, string) (Instance, error)
|
||||
}
|
||||
|
||||
type instance struct {
|
||||
ID string
|
||||
}
|
||||
|
||||
func (i *instance) InstanceID() string {
|
||||
return i.ID
|
||||
}
|
||||
|
||||
func (i *instance) ProjectID() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (i *instance) ConsoleClientID() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func GetInstance(ctx context.Context) Instance {
|
||||
instance, ok := ctx.Value(instanceKey).(Instance)
|
||||
if !ok {
|
||||
return emptyInstance
|
||||
}
|
||||
return instance
|
||||
}
|
||||
|
||||
func WithInstance(ctx context.Context, instance Instance) context.Context {
|
||||
return context.WithValue(ctx, instanceKey, instance)
|
||||
}
|
||||
|
||||
func WithInstanceID(ctx context.Context, id string) context.Context {
|
||||
return context.WithValue(ctx, instanceKey, &instance{ID: id})
|
||||
}
|
80
internal/api/authz/instance_test.go
Normal file
80
internal/api/authz/instance_test.go
Normal file
@@ -0,0 +1,80 @@
|
||||
package authz
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func Test_Instance(t *testing.T) {
|
||||
type args struct {
|
||||
ctx context.Context
|
||||
}
|
||||
type res struct {
|
||||
instanceID string
|
||||
projectID string
|
||||
consoleID string
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
res res
|
||||
}{
|
||||
{
|
||||
"empty context",
|
||||
args{
|
||||
context.Background(),
|
||||
},
|
||||
res{
|
||||
instanceID: "",
|
||||
projectID: "",
|
||||
consoleID: "",
|
||||
},
|
||||
},
|
||||
{
|
||||
"WithInstanceID",
|
||||
args{
|
||||
WithInstanceID(context.Background(), "id"),
|
||||
},
|
||||
res{
|
||||
instanceID: "id",
|
||||
projectID: "",
|
||||
consoleID: "",
|
||||
},
|
||||
},
|
||||
{
|
||||
"WithInstance",
|
||||
args{
|
||||
WithInstance(context.Background(), &mockInstance{}),
|
||||
},
|
||||
res{
|
||||
instanceID: "instanceID",
|
||||
projectID: "projectID",
|
||||
consoleID: "consoleID",
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got := GetInstance(tt.args.ctx)
|
||||
assert.Equal(t, tt.res.instanceID, got.InstanceID())
|
||||
assert.Equal(t, tt.res.projectID, got.ProjectID())
|
||||
assert.Equal(t, tt.res.consoleID, got.ConsoleClientID())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
type mockInstance struct{}
|
||||
|
||||
func (m *mockInstance) InstanceID() string {
|
||||
return "instanceID"
|
||||
}
|
||||
|
||||
func (m *mockInstance) ProjectID() string {
|
||||
return "projectID"
|
||||
}
|
||||
|
||||
func (m *mockInstance) ConsoleClientID() string {
|
||||
return "consoleID"
|
||||
}
|
@@ -152,14 +152,10 @@ func (s *Server) ListMyProjectOrgs(ctx context.Context, req *auth_pb.ListMyProje
|
||||
return nil, err
|
||||
}
|
||||
|
||||
iam, err := s.query.Instance(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ctxData := authz.GetCtxData(ctx)
|
||||
|
||||
//client of user is not in project of ZITADEL
|
||||
if ctxData.ProjectID != iam.IAMProjectID {
|
||||
if ctxData.ProjectID != authz.GetInstance(ctx).ProjectID() {
|
||||
userGrantProjectID, err := query.NewUserGrantProjectIDSearchQuery(ctxData.ProjectID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
50
internal/api/grpc/server/middleware/instance_interceptor.go
Normal file
50
internal/api/grpc/server/middleware/instance_interceptor.go
Normal file
@@ -0,0 +1,50 @@
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/metadata"
|
||||
"google.golang.org/grpc/status"
|
||||
|
||||
"github.com/caos/zitadel/internal/api/authz"
|
||||
)
|
||||
|
||||
type InstanceVerifier interface {
|
||||
GetInstance(ctx context.Context)
|
||||
}
|
||||
|
||||
func InstanceInterceptor(verifier authz.InstanceVerifier, headerName string) grpc.UnaryServerInterceptor {
|
||||
return func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) {
|
||||
return setInstance(ctx, req, info, handler, verifier, headerName)
|
||||
}
|
||||
}
|
||||
|
||||
func setInstance(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler, verifier authz.InstanceVerifier, headerName string) (_ interface{}, err error) {
|
||||
host, err := hostNameFromContext(ctx, headerName)
|
||||
if err != nil {
|
||||
return nil, status.Error(codes.PermissionDenied, err.Error())
|
||||
}
|
||||
instance, err := verifier.InstanceByHost(ctx, host)
|
||||
if err != nil {
|
||||
return nil, status.Error(codes.PermissionDenied, err.Error())
|
||||
}
|
||||
return handler(authz.WithInstance(ctx, instance), req)
|
||||
}
|
||||
|
||||
func hostNameFromContext(ctx context.Context, headerName string) (string, error) {
|
||||
md, ok := metadata.FromIncomingContext(ctx)
|
||||
if !ok {
|
||||
return "", fmt.Errorf("cannot read metadata")
|
||||
}
|
||||
host, ok := md[headerName]
|
||||
if !ok {
|
||||
return "", fmt.Errorf("cannot find header: %v", headerName)
|
||||
}
|
||||
if len(host) != 1 {
|
||||
return "", fmt.Errorf("invalid host header: %v", host)
|
||||
}
|
||||
return host[0], nil
|
||||
}
|
174
internal/api/grpc/server/middleware/instance_interceptor_test.go
Normal file
174
internal/api/grpc/server/middleware/instance_interceptor_test.go
Normal file
@@ -0,0 +1,174 @@
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/metadata"
|
||||
|
||||
"github.com/caos/zitadel/internal/api/authz"
|
||||
)
|
||||
|
||||
func Test_hostNameFromContext(t *testing.T) {
|
||||
type args struct {
|
||||
ctx context.Context
|
||||
headerName string
|
||||
}
|
||||
type res struct {
|
||||
want string
|
||||
err bool
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
res res
|
||||
}{
|
||||
{
|
||||
"empty context, error",
|
||||
args{
|
||||
ctx: context.Background(),
|
||||
headerName: "header",
|
||||
},
|
||||
res{
|
||||
want: "",
|
||||
err: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
"header not found",
|
||||
args{
|
||||
ctx: metadata.NewIncomingContext(context.Background(), nil),
|
||||
headerName: "header",
|
||||
},
|
||||
res{
|
||||
want: "",
|
||||
err: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
"header not found",
|
||||
args{
|
||||
ctx: metadata.NewIncomingContext(context.Background(), metadata.Pairs("header", "value")),
|
||||
headerName: "header",
|
||||
},
|
||||
res{
|
||||
want: "value",
|
||||
err: false,
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got, err := hostNameFromContext(tt.args.ctx, tt.args.headerName)
|
||||
if (err != nil) != tt.res.err {
|
||||
t.Errorf("hostNameFromContext() error = %v, wantErr %v", err, tt.res.err)
|
||||
return
|
||||
}
|
||||
if got != tt.res.want {
|
||||
t.Errorf("hostNameFromContext() got = %v, want %v", got, tt.res.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_setInstance(t *testing.T) {
|
||||
type args struct {
|
||||
ctx context.Context
|
||||
req interface{}
|
||||
info *grpc.UnaryServerInfo
|
||||
handler grpc.UnaryHandler
|
||||
verifier authz.InstanceVerifier
|
||||
headerName string
|
||||
}
|
||||
type res struct {
|
||||
want interface{}
|
||||
err bool
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
res res
|
||||
}{
|
||||
{
|
||||
"hostname not found, error",
|
||||
args{
|
||||
ctx: context.Background(),
|
||||
},
|
||||
res{
|
||||
want: nil,
|
||||
err: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
"invalid host, error",
|
||||
args{
|
||||
ctx: metadata.NewIncomingContext(context.Background(), metadata.Pairs("header", "host2")),
|
||||
req: &mockRequest{},
|
||||
verifier: &mockInstanceVerifier{"host"},
|
||||
headerName: "header",
|
||||
},
|
||||
res{
|
||||
want: nil,
|
||||
err: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
"valid host",
|
||||
args{
|
||||
ctx: metadata.NewIncomingContext(context.Background(), metadata.Pairs("header", "host")),
|
||||
req: &mockRequest{},
|
||||
verifier: &mockInstanceVerifier{"host"},
|
||||
headerName: "header",
|
||||
handler: func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return req, nil
|
||||
},
|
||||
},
|
||||
res{
|
||||
want: &mockRequest{},
|
||||
err: false,
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got, err := setInstance(tt.args.ctx, tt.args.req, tt.args.info, tt.args.handler, tt.args.verifier, tt.args.headerName)
|
||||
if (err != nil) != tt.res.err {
|
||||
t.Errorf("setInstance() error = %v, wantErr %v", err, tt.res.err)
|
||||
return
|
||||
}
|
||||
if !reflect.DeepEqual(got, tt.res.want) {
|
||||
t.Errorf("setInstance() got = %v, want %v", got, tt.res.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
type mockRequest struct{}
|
||||
|
||||
type mockInstanceVerifier struct {
|
||||
host string
|
||||
}
|
||||
|
||||
func (m *mockInstanceVerifier) InstanceByHost(ctx context.Context, host string) (authz.Instance, error) {
|
||||
if host != m.host {
|
||||
return nil, fmt.Errorf("invalid host")
|
||||
}
|
||||
return &mockInstance{}, nil
|
||||
}
|
||||
|
||||
type mockInstance struct{}
|
||||
|
||||
func (m *mockInstance) InstanceID() string {
|
||||
return "instanceID"
|
||||
}
|
||||
|
||||
func (m *mockInstance) ProjectID() string {
|
||||
return "projectID"
|
||||
}
|
||||
|
||||
func (m *mockInstance) ConsoleClientID() string {
|
||||
return "consoleClientID"
|
||||
}
|
@@ -20,7 +20,7 @@ type Server interface {
|
||||
AuthMethods() authz.MethodMapping
|
||||
}
|
||||
|
||||
func CreateServer(verifier *authz.TokenVerifier, authConfig authz.Config, queries *query.Queries) *grpc.Server {
|
||||
func CreateServer(verifier *authz.TokenVerifier, authConfig authz.Config, queries *query.Queries, hostHeaderName string) *grpc.Server {
|
||||
metricTypes := []metrics.MetricType{metrics.MetricTypeTotalCount, metrics.MetricTypeRequestCount, metrics.MetricTypeStatusCode}
|
||||
return grpc.NewServer(
|
||||
grpc.UnaryInterceptor(
|
||||
@@ -30,6 +30,7 @@ func CreateServer(verifier *authz.TokenVerifier, authConfig authz.Config, querie
|
||||
middleware.SentryHandler(),
|
||||
middleware.NoCacheInterceptor(),
|
||||
middleware.ErrorHandler(),
|
||||
middleware.InstanceInterceptor(queries, hostHeaderName),
|
||||
middleware.AuthorizationInterceptor(verifier, authConfig),
|
||||
middleware.TranslationHandler(queries),
|
||||
middleware.ValidationHandler(),
|
||||
|
65
internal/api/http/middleware/instance_interceptor.go
Normal file
65
internal/api/http/middleware/instance_interceptor.go
Normal file
@@ -0,0 +1,65 @@
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"github.com/caos/zitadel/internal/api/authz"
|
||||
"github.com/caos/zitadel/internal/telemetry/tracing"
|
||||
)
|
||||
|
||||
type instanceInterceptor struct {
|
||||
verifier authz.InstanceVerifier
|
||||
headerName string
|
||||
}
|
||||
|
||||
func InstanceInterceptor(verifier authz.InstanceVerifier, headerName string) *instanceInterceptor {
|
||||
return &instanceInterceptor{
|
||||
verifier: verifier,
|
||||
headerName: headerName,
|
||||
}
|
||||
}
|
||||
|
||||
func (a *instanceInterceptor) Handler(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
ctx, err := setInstance(r, a.verifier, a.headerName)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusUnauthorized)
|
||||
return
|
||||
}
|
||||
r = r.WithContext(ctx)
|
||||
next.ServeHTTP(w, r)
|
||||
})
|
||||
}
|
||||
|
||||
func (a *instanceInterceptor) HandlerFunc(next http.HandlerFunc) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
ctx, err := setInstance(r, a.verifier, a.headerName)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
r = r.WithContext(ctx)
|
||||
next.ServeHTTP(w, r)
|
||||
}
|
||||
}
|
||||
|
||||
func setInstance(r *http.Request, verifier authz.InstanceVerifier, headerName string) (_ context.Context, err error) {
|
||||
ctx := r.Context()
|
||||
|
||||
authCtx, span := tracing.NewServerInterceptorSpan(ctx)
|
||||
defer func() { span.EndWithError(err) }()
|
||||
|
||||
host := r.Header.Get(headerName)
|
||||
if host == "" {
|
||||
return nil, fmt.Errorf("host header %s not found", headerName)
|
||||
}
|
||||
|
||||
instance, err := verifier.InstanceByHost(authCtx, host)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
span.End()
|
||||
return authz.WithInstance(ctx, instance), nil
|
||||
}
|
258
internal/api/http/middleware/instance_interceptor_test.go
Normal file
258
internal/api/http/middleware/instance_interceptor_test.go
Normal file
@@ -0,0 +1,258 @@
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/caos/zitadel/internal/api/authz"
|
||||
)
|
||||
|
||||
func Test_instanceInterceptor_Handler(t *testing.T) {
|
||||
type fields struct {
|
||||
verifier authz.InstanceVerifier
|
||||
headerName string
|
||||
}
|
||||
type args struct {
|
||||
request *http.Request
|
||||
}
|
||||
type res struct {
|
||||
statusCode int
|
||||
context context.Context
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
fields fields
|
||||
args args
|
||||
res res
|
||||
}{
|
||||
{
|
||||
"setInstance error",
|
||||
fields{
|
||||
verifier: &mockInstanceVerifier{},
|
||||
headerName: "header",
|
||||
},
|
||||
args{
|
||||
request: httptest.NewRequest("", "/url", nil),
|
||||
},
|
||||
res{
|
||||
statusCode: 403,
|
||||
context: nil,
|
||||
},
|
||||
},
|
||||
{
|
||||
"setInstance ok",
|
||||
fields{
|
||||
verifier: &mockInstanceVerifier{"host"},
|
||||
headerName: "header",
|
||||
},
|
||||
args{
|
||||
request: func() *http.Request {
|
||||
r := httptest.NewRequest("", "/url", nil)
|
||||
r.Header.Set("header", "host")
|
||||
return r
|
||||
}(),
|
||||
},
|
||||
res{
|
||||
statusCode: 200,
|
||||
context: authz.WithInstance(context.Background(), &mockInstance{}),
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
a := &instanceInterceptor{
|
||||
verifier: tt.fields.verifier,
|
||||
headerName: tt.fields.headerName,
|
||||
}
|
||||
next := &testHandler{}
|
||||
got := a.HandlerFunc(next.ServeHTTP)
|
||||
rr := httptest.NewRecorder()
|
||||
got.ServeHTTP(rr, tt.args.request)
|
||||
assert.Equal(t, tt.res.statusCode, rr.Code)
|
||||
assert.Equal(t, tt.res.context, next.context)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_instanceInterceptor_HandlerFunc(t *testing.T) {
|
||||
type fields struct {
|
||||
verifier authz.InstanceVerifier
|
||||
headerName string
|
||||
}
|
||||
type args struct {
|
||||
request *http.Request
|
||||
}
|
||||
type res struct {
|
||||
statusCode int
|
||||
context context.Context
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
fields fields
|
||||
args args
|
||||
res res
|
||||
}{
|
||||
{
|
||||
"setInstance error",
|
||||
fields{
|
||||
verifier: &mockInstanceVerifier{},
|
||||
headerName: "header",
|
||||
},
|
||||
args{
|
||||
request: httptest.NewRequest("", "/url", nil),
|
||||
},
|
||||
res{
|
||||
statusCode: 403,
|
||||
context: nil,
|
||||
},
|
||||
},
|
||||
{
|
||||
"setInstance ok",
|
||||
fields{
|
||||
verifier: &mockInstanceVerifier{"host"},
|
||||
headerName: "header",
|
||||
},
|
||||
args{
|
||||
request: func() *http.Request {
|
||||
r := httptest.NewRequest("", "/url", nil)
|
||||
r.Header.Set("header", "host")
|
||||
return r
|
||||
}(),
|
||||
},
|
||||
res{
|
||||
statusCode: 200,
|
||||
context: authz.WithInstance(context.Background(), &mockInstance{}),
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
a := &instanceInterceptor{
|
||||
verifier: tt.fields.verifier,
|
||||
headerName: tt.fields.headerName,
|
||||
}
|
||||
next := &testHandler{}
|
||||
got := a.HandlerFunc(next.ServeHTTP)
|
||||
rr := httptest.NewRecorder()
|
||||
got.ServeHTTP(rr, tt.args.request)
|
||||
assert.Equal(t, tt.res.statusCode, rr.Code)
|
||||
assert.Equal(t, tt.res.context, next.context)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_setInstance(t *testing.T) {
|
||||
type args struct {
|
||||
r *http.Request
|
||||
verifier authz.InstanceVerifier
|
||||
headerName string
|
||||
}
|
||||
type res struct {
|
||||
want context.Context
|
||||
err bool
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
res res
|
||||
}{
|
||||
{
|
||||
"hostname not found, error",
|
||||
args{
|
||||
r: func() *http.Request {
|
||||
r := httptest.NewRequest("", "/url", nil)
|
||||
return r
|
||||
}(),
|
||||
verifier: &mockInstanceVerifier{},
|
||||
headerName: "",
|
||||
},
|
||||
res{
|
||||
want: nil,
|
||||
err: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
"invalid host, error",
|
||||
args{
|
||||
r: func() *http.Request {
|
||||
r := httptest.NewRequest("", "/url", nil)
|
||||
r.Header.Set("header", "host2")
|
||||
return r
|
||||
}(),
|
||||
verifier: &mockInstanceVerifier{"host"},
|
||||
headerName: "header",
|
||||
},
|
||||
res{
|
||||
want: nil,
|
||||
err: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
"valid host",
|
||||
args{
|
||||
r: func() *http.Request {
|
||||
r := httptest.NewRequest("", "/url", nil)
|
||||
r.Header.Set("header", "host")
|
||||
return r
|
||||
}(),
|
||||
verifier: &mockInstanceVerifier{"host"},
|
||||
headerName: "header",
|
||||
},
|
||||
res{
|
||||
want: authz.WithInstance(context.Background(), &mockInstance{}),
|
||||
err: false,
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got, err := setInstance(tt.args.r, tt.args.verifier, tt.args.headerName)
|
||||
if (err != nil) != tt.res.err {
|
||||
t.Errorf("setInstance() error = %v, wantErr %v", err, tt.res.err)
|
||||
return
|
||||
}
|
||||
if !reflect.DeepEqual(got, tt.res.want) {
|
||||
t.Errorf("setInstance() got = %v, want %v", got, tt.res.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
type testHandler struct {
|
||||
context context.Context
|
||||
}
|
||||
|
||||
func (t *testHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
t.context = r.Context()
|
||||
}
|
||||
|
||||
type mockInstanceVerifier struct {
|
||||
host string
|
||||
}
|
||||
|
||||
func (m *mockInstanceVerifier) InstanceByHost(ctx context.Context, host string) (authz.Instance, error) {
|
||||
if host != m.host {
|
||||
return nil, fmt.Errorf("invalid host")
|
||||
}
|
||||
return &mockInstance{}, nil
|
||||
}
|
||||
|
||||
type mockInstance struct{}
|
||||
|
||||
func (m *mockInstance) InstanceID() string {
|
||||
return "instanceID"
|
||||
}
|
||||
|
||||
func (m *mockInstance) ProjectID() string {
|
||||
return "projectID"
|
||||
}
|
||||
|
||||
func (m *mockInstance) ConsoleClientID() string {
|
||||
return "consoleClientID"
|
||||
}
|
@@ -46,7 +46,7 @@ func (o *OPStorage) AuthRequestByID(ctx context.Context, id string) (_ op.AuthRe
|
||||
if !ok {
|
||||
return nil, errors.ThrowPreconditionFailed(nil, "OIDC-D3g21", "no user agent id")
|
||||
}
|
||||
instanceID := authz.GetInstance(ctx).ID
|
||||
instanceID := authz.GetInstance(ctx).InstanceID()
|
||||
resp, err := o.repo.AuthRequestByIDCheckLoggedIn(ctx, id, userAgentID, instanceID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -58,7 +58,7 @@ func (o *OPStorage) AuthRequestByCode(ctx context.Context, code string) (_ op.Au
|
||||
ctx, span := tracing.NewSpan(ctx)
|
||||
defer func() { span.EndWithError(err) }()
|
||||
|
||||
instanceID := authz.GetInstance(ctx).ID
|
||||
instanceID := authz.GetInstance(ctx).InstanceID()
|
||||
resp, err := o.repo.AuthRequestByCode(ctx, code, instanceID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -73,7 +73,7 @@ func (o *OPStorage) SaveAuthCode(ctx context.Context, id, code string) (err erro
|
||||
if !ok {
|
||||
return errors.ThrowPreconditionFailed(nil, "OIDC-Dgus2", "no user agent id")
|
||||
}
|
||||
instanceID := authz.GetInstance(ctx).ID
|
||||
instanceID := authz.GetInstance(ctx).InstanceID()
|
||||
return o.repo.SaveAuthCode(ctx, id, code, userAgentID, instanceID)
|
||||
}
|
||||
|
||||
@@ -81,7 +81,7 @@ func (o *OPStorage) DeleteAuthRequest(ctx context.Context, id string) (err error
|
||||
ctx, span := tracing.NewSpan(ctx)
|
||||
defer func() { span.EndWithError(err) }()
|
||||
|
||||
instanceID := authz.GetInstance(ctx).ID
|
||||
instanceID := authz.GetInstance(ctx).InstanceID()
|
||||
return o.repo.DeleteAuthRequest(ctx, id, instanceID)
|
||||
}
|
||||
|
||||
|
@@ -133,7 +133,7 @@ func CreateAuthRequestToBusiness(ctx context.Context, authReq *oidc.AuthRequest,
|
||||
SelectedIDPConfigID: GetSelectedIDPIDFromScopes(authReq.Scopes),
|
||||
MaxAuthAge: MaxAgeToBusiness(authReq.MaxAge),
|
||||
UserID: userID,
|
||||
InstanceID: authz.GetInstance(ctx).ID,
|
||||
InstanceID: authz.GetInstance(ctx).InstanceID(),
|
||||
Request: &domain.AuthRequestOIDC{
|
||||
Scopes: authReq.Scopes,
|
||||
ResponseType: ResponseTypeToBusiness(authReq.ResponseType),
|
||||
|
@@ -83,13 +83,13 @@ type OPStorage struct {
|
||||
assetAPIPrefix string
|
||||
}
|
||||
|
||||
func NewProvider(ctx context.Context, config Config, issuer, defaultLogoutRedirectURI string, command *command.Commands, query *query.Queries, repo repository.Repository, keyConfig systemdefaults.KeyConfig, encryptionAlg crypto.EncryptionAlgorithm, cryptoKey []byte, es *eventstore.Eventstore, projections *sql.DB, keyChan <-chan interface{}, userAgentCookie func(http.Handler) http.Handler) (op.OpenIDProvider, error) {
|
||||
func NewProvider(ctx context.Context, config Config, issuer, defaultLogoutRedirectURI string, command *command.Commands, query *query.Queries, repo repository.Repository, keyConfig systemdefaults.KeyConfig, encryptionAlg crypto.EncryptionAlgorithm, cryptoKey []byte, es *eventstore.Eventstore, projections *sql.DB, keyChan <-chan interface{}, userAgentCookie, instanceHandler func(http.Handler) http.Handler) (op.OpenIDProvider, error) {
|
||||
opConfig, err := createOPConfig(config, issuer, defaultLogoutRedirectURI, cryptoKey)
|
||||
if err != nil {
|
||||
return nil, caos_errs.ThrowInternal(err, "OIDC-EGrqd", "cannot create op config: %w")
|
||||
}
|
||||
storage := newStorage(config, command, query, repo, keyConfig, encryptionAlg, es, projections, keyChan)
|
||||
options, err := createOptions(config, userAgentCookie)
|
||||
options, err := createOptions(config, userAgentCookie, instanceHandler)
|
||||
if err != nil {
|
||||
return nil, caos_errs.ThrowInternal(err, "OIDC-D3gq1", "cannot create options: %w")
|
||||
}
|
||||
@@ -131,12 +131,13 @@ func createOPConfig(config Config, issuer, defaultLogoutRedirectURI string, cryp
|
||||
return opConfig, nil
|
||||
}
|
||||
|
||||
func createOptions(config Config, userAgentCookie func(http.Handler) http.Handler) ([]op.Option, error) {
|
||||
func createOptions(config Config, userAgentCookie, instanceHandler func(http.Handler) http.Handler) ([]op.Option, error) {
|
||||
metricTypes := []metrics.MetricType{metrics.MetricTypeRequestCount, metrics.MetricTypeStatusCode, metrics.MetricTypeTotalCount}
|
||||
interceptor := op.WithHttpInterceptors(
|
||||
middleware.MetricsHandler(metricTypes),
|
||||
middleware.TelemetryHandler(),
|
||||
middleware.NoCacheInterceptor,
|
||||
instanceHandler,
|
||||
userAgentCookie,
|
||||
http_utils.CopyHeadersToContext,
|
||||
)
|
||||
|
@@ -11,6 +11,8 @@ import (
|
||||
|
||||
"github.com/caos/logging"
|
||||
|
||||
"github.com/caos/zitadel/internal/api/authz"
|
||||
|
||||
"github.com/caos/zitadel/internal/api/http/middleware"
|
||||
)
|
||||
|
||||
@@ -51,12 +53,7 @@ func (i *spaHandler) Open(name string) (http.File, error) {
|
||||
return i.fileSystem.Open("/index.html")
|
||||
}
|
||||
|
||||
func Start(config Config, domain, url, issuer, clientID string) (http.Handler, error) {
|
||||
environmentJSON, err := createEnvironmentJSON(url, issuer, clientID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to marshal env for console: %w", err)
|
||||
}
|
||||
|
||||
func Start(config Config, domain, url, issuer string, instanceHandler func(http.Handler) http.Handler) (http.Handler, error) {
|
||||
consoleDir := consoleDefaultDir
|
||||
if config.ConsoleOverwriteDir != "" {
|
||||
consoleDir = config.ConsoleOverwriteDir
|
||||
@@ -73,10 +70,20 @@ func Start(config Config, domain, url, issuer, clientID string) (http.Handler, e
|
||||
|
||||
handler := &http.ServeMux{}
|
||||
handler.Handle("/", cache(security(http.FileServer(&spaHandler{consoleHTTPDir}))))
|
||||
handler.Handle(envRequestPath, cache(security(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
_, err := w.Write(environmentJSON)
|
||||
handler.Handle(envRequestPath, instanceHandler(cache(security(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
instance := authz.GetInstance(r.Context())
|
||||
if instance.InstanceID() == "" {
|
||||
http.Error(w, "empty instanceID", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
environmentJSON, err := createEnvironmentJSON(url, issuer, instance.ConsoleClientID())
|
||||
if err != nil {
|
||||
http.Error(w, fmt.Sprintf("unable to marshal env for console: %v", err), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
_, err = w.Write(environmentJSON)
|
||||
logging.OnError(err).Error("error serving environment.json")
|
||||
}))))
|
||||
})))))
|
||||
return handler, nil
|
||||
}
|
||||
|
||||
@@ -92,23 +99,15 @@ func csp(zitadelDomain string) *middleware.CSP {
|
||||
return &csp
|
||||
}
|
||||
|
||||
func createEnvironmentJSON(url, issuer, clientID string) ([]byte, error) {
|
||||
func createEnvironmentJSON(api, issuer, clientID string) ([]byte, error) {
|
||||
environment := struct {
|
||||
AuthServiceUrl string `json:"authServiceUrl,omitempty"`
|
||||
MgmtServiceUrl string `json:"mgmtServiceUrl,omitempty"`
|
||||
AdminServiceUrl string `json:"adminServiceUrl,omitempty"`
|
||||
SubscriptionServiceUrl string `json:"subscriptionServiceUrl,omitempty"`
|
||||
AssetServiceUrl string `json:"assetServiceUrl,omitempty"`
|
||||
Issuer string `json:"issuer,omitempty"`
|
||||
ClientID string `json:"clientid,omitempty"`
|
||||
API string `json:"api,omitempty"`
|
||||
Issuer string `json:"issuer,omitempty"`
|
||||
ClientID string `json:"clientid,omitempty"`
|
||||
}{
|
||||
AuthServiceUrl: url,
|
||||
MgmtServiceUrl: url,
|
||||
AdminServiceUrl: url,
|
||||
SubscriptionServiceUrl: url,
|
||||
AssetServiceUrl: url,
|
||||
Issuer: issuer,
|
||||
ClientID: clientID,
|
||||
API: api,
|
||||
Issuer: issuer,
|
||||
ClientID: clientID,
|
||||
}
|
||||
return json.Marshal(environment)
|
||||
}
|
||||
|
@@ -20,7 +20,7 @@ func (l *Login) getAuthRequest(r *http.Request) (*domain.AuthRequest, error) {
|
||||
return nil, nil
|
||||
}
|
||||
userAgentID, _ := http_mw.UserAgentIDFromCtx(r.Context())
|
||||
instanceID := authz.GetInstance(r.Context()).ID
|
||||
instanceID := authz.GetInstance(r.Context()).InstanceID()
|
||||
return l.authRepo.AuthRequestByID(r.Context(), authRequestID, userAgentID, instanceID)
|
||||
}
|
||||
|
||||
|
@@ -89,7 +89,7 @@ func (l *Login) handleIDP(w http.ResponseWriter, r *http.Request, authReq *domai
|
||||
return
|
||||
}
|
||||
userAgentID, _ := http_mw.UserAgentIDFromCtx(r.Context())
|
||||
instanceID := authz.GetInstance(r.Context()).ID
|
||||
instanceID := authz.GetInstance(r.Context()).InstanceID()
|
||||
err = l.authRepo.SelectExternalIDP(r.Context(), authReq.ID, idpConfig.IDPConfigID, userAgentID, instanceID)
|
||||
if err != nil {
|
||||
l.renderLogin(w, r, authReq, err)
|
||||
@@ -142,7 +142,7 @@ func (l *Login) handleExternalLoginCallback(w http.ResponseWriter, r *http.Reque
|
||||
return
|
||||
}
|
||||
userAgentID, _ := http_mw.UserAgentIDFromCtx(r.Context())
|
||||
instanceID := authz.GetInstance(r.Context()).ID
|
||||
instanceID := authz.GetInstance(r.Context()).InstanceID()
|
||||
authReq, err := l.authRepo.AuthRequestByID(r.Context(), data.State, userAgentID, instanceID)
|
||||
if err != nil {
|
||||
l.renderError(w, r, authReq, err)
|
||||
@@ -202,7 +202,7 @@ func (l *Login) handleExternalUserAuthenticated(w http.ResponseWriter, r *http.R
|
||||
return
|
||||
}
|
||||
|
||||
instanceID := authz.GetInstance(r.Context()).ID
|
||||
instanceID := authz.GetInstance(r.Context()).InstanceID()
|
||||
err = l.authRepo.CheckExternalUserLogin(setContext(r.Context(), ""), authReq.ID, userAgentID, instanceID, externalUser, domain.BrowserInfoFromRequest(r))
|
||||
if err != nil {
|
||||
if errors.IsNotFound(err) {
|
||||
@@ -329,7 +329,7 @@ func (l *Login) handleExternalNotFoundOptionCheck(w http.ResponseWriter, r *http
|
||||
return
|
||||
} else if data.ResetLinking {
|
||||
userAgentID, _ := http_mw.UserAgentIDFromCtx(r.Context())
|
||||
instanceID := authz.GetInstance(r.Context()).ID
|
||||
instanceID := authz.GetInstance(r.Context()).InstanceID()
|
||||
err = l.authRepo.ResetLinkingUsers(r.Context(), authReq.ID, userAgentID, instanceID)
|
||||
if err != nil {
|
||||
l.renderExternalNotFoundOption(w, r, authReq, nil, nil, nil, nil, err)
|
||||
@@ -368,7 +368,7 @@ func (l *Login) handleAutoRegister(w http.ResponseWriter, r *http.Request, authR
|
||||
}
|
||||
|
||||
userAgentID, _ := http_mw.UserAgentIDFromCtx(r.Context())
|
||||
instanceID := authz.GetInstance(r.Context()).ID
|
||||
instanceID := authz.GetInstance(r.Context()).InstanceID()
|
||||
if len(authReq.LinkingUsers) == 0 {
|
||||
l.renderError(w, r, authReq, caos_errors.ThrowPreconditionFailed(nil, "LOGIN-asfg3", "Errors.ExternalIDP.NoExternalUserData"))
|
||||
return
|
||||
|
@@ -68,7 +68,7 @@ func (l *Login) handleExternalRegister(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
userAgentID, _ := http_mw.UserAgentIDFromCtx(r.Context())
|
||||
instanceID := authz.GetInstance(r.Context()).ID
|
||||
instanceID := authz.GetInstance(r.Context()).InstanceID()
|
||||
err = l.authRepo.SelectExternalIDP(r.Context(), authReq.ID, idpConfig.IDPConfigID, userAgentID, instanceID)
|
||||
if err != nil {
|
||||
l.renderLogin(w, r, authReq, err)
|
||||
@@ -89,7 +89,7 @@ func (l *Login) handleExternalRegisterCallback(w http.ResponseWriter, r *http.Re
|
||||
return
|
||||
}
|
||||
userAgentID, _ := http_mw.UserAgentIDFromCtx(r.Context())
|
||||
instanceID := authz.GetInstance(r.Context()).ID
|
||||
instanceID := authz.GetInstance(r.Context()).InstanceID()
|
||||
authReq, err := l.authRepo.AuthRequestByID(r.Context(), data.State, userAgentID, instanceID)
|
||||
if err != nil {
|
||||
l.renderError(w, r, authReq, err)
|
||||
|
@@ -45,7 +45,7 @@ func (l *Login) handleJWTRequest(w http.ResponseWriter, r *http.Request) {
|
||||
l.renderError(w, r, nil, err)
|
||||
return
|
||||
}
|
||||
instanceID := authz.GetInstance(r.Context()).ID
|
||||
instanceID := authz.GetInstance(r.Context()).InstanceID()
|
||||
authReq, err := l.authRepo.AuthRequestByID(r.Context(), data.AuthRequestID, userAgentID, instanceID)
|
||||
if err != nil {
|
||||
l.renderError(w, r, authReq, err)
|
||||
@@ -209,7 +209,7 @@ func (l *Login) handleJWTCallback(w http.ResponseWriter, r *http.Request) {
|
||||
l.renderError(w, r, nil, err)
|
||||
return
|
||||
}
|
||||
instanceID := authz.GetInstance(r.Context()).ID
|
||||
instanceID := authz.GetInstance(r.Context()).InstanceID()
|
||||
authReq, err := l.authRepo.AuthRequestByID(r.Context(), data.AuthRequestID, userAgentID, instanceID)
|
||||
if err != nil {
|
||||
l.renderError(w, r, authReq, err)
|
||||
|
@@ -14,7 +14,7 @@ const (
|
||||
|
||||
func (l *Login) linkUsers(w http.ResponseWriter, r *http.Request, authReq *domain.AuthRequest, err error) {
|
||||
userAgentID, _ := http_mw.UserAgentIDFromCtx(r.Context())
|
||||
instanceID := authz.GetInstance(r.Context()).ID
|
||||
instanceID := authz.GetInstance(r.Context()).InstanceID()
|
||||
err = l.authRepo.LinkExternalUsers(setContext(r.Context(), authReq.UserOrgID), authReq.ID, userAgentID, instanceID, domain.BrowserInfoFromRequest(r))
|
||||
l.renderLinkUsersDone(w, r, authReq, err)
|
||||
}
|
||||
|
@@ -66,7 +66,8 @@ func CreateLogin(config Config,
|
||||
baseURL,
|
||||
oidcAuthCallbackURL string,
|
||||
externalSecure bool,
|
||||
userAgentCookie mux.MiddlewareFunc,
|
||||
userAgentCookie,
|
||||
instanceHandler mux.MiddlewareFunc,
|
||||
userCodeAlg crypto.EncryptionAlgorithm,
|
||||
idpConfigAlg crypto.EncryptionAlgorithm,
|
||||
csrfCookieKey []byte,
|
||||
@@ -104,7 +105,7 @@ func CreateLogin(config Config,
|
||||
return nil, fmt.Errorf("unable to create cacheInterceptor: %w", err)
|
||||
}
|
||||
security := middleware.SecurityHeaders(csp(), login.cspErrorHandler)
|
||||
login.router = CreateRouter(login, statikFS, csrfInterceptor, cacheInterceptor, security, userAgentCookie, middleware.TelemetryHandler(EndpointResources))
|
||||
login.router = CreateRouter(login, statikFS, instanceHandler, csrfInterceptor, cacheInterceptor, security, userAgentCookie, middleware.TelemetryHandler(EndpointResources))
|
||||
login.renderer = CreateRenderer(HandlerPrefix, statikFS, staticStorage, config.LanguageCookieName, systemDefaults.DefaultLanguage)
|
||||
login.parser = form.NewParser()
|
||||
return login, nil
|
||||
|
@@ -60,7 +60,7 @@ func (l *Login) handleLoginNameCheck(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
userAgentID, _ := http_mw.UserAgentIDFromCtx(r.Context())
|
||||
instanceID := authz.GetInstance(r.Context()).ID
|
||||
instanceID := authz.GetInstance(r.Context()).InstanceID()
|
||||
loginName := data.LoginName
|
||||
err = l.authRepo.CheckLoginName(r.Context(), authReq.ID, loginName, userAgentID, instanceID)
|
||||
if err != nil {
|
||||
|
@@ -36,7 +36,7 @@ func (l *Login) handleMFAVerify(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
if data.MFAType == domain.MFATypeOTP {
|
||||
userAgentID, _ := http_mw.UserAgentIDFromCtx(r.Context())
|
||||
instanceID := authz.GetInstance(r.Context()).ID
|
||||
instanceID := authz.GetInstance(r.Context()).InstanceID()
|
||||
err = l.authRepo.VerifyMFAOTP(setContext(r.Context(), authReq.UserOrgID), authReq.ID, authReq.UserID, authReq.UserOrgID, data.Code, userAgentID, instanceID, domain.BrowserInfoFromRequest(r))
|
||||
if err != nil {
|
||||
l.renderMFAVerifySelected(w, r, authReq, step, domain.MFATypeOTP, err)
|
||||
|
@@ -30,7 +30,7 @@ func (l *Login) renderU2FVerification(w http.ResponseWriter, r *http.Request, au
|
||||
var webAuthNLogin *domain.WebAuthNLogin
|
||||
if err == nil {
|
||||
userAgentID, _ := http_mw.UserAgentIDFromCtx(r.Context())
|
||||
instanceID := authz.GetInstance(r.Context()).ID
|
||||
instanceID := authz.GetInstance(r.Context()).InstanceID()
|
||||
webAuthNLogin, err = l.authRepo.BeginMFAU2FLogin(setContext(r.Context(), authReq.UserOrgID), authReq.UserID, authReq.UserOrgID, authReq.ID, userAgentID, instanceID)
|
||||
}
|
||||
if err != nil {
|
||||
@@ -72,7 +72,7 @@ func (l *Login) handleU2FVerification(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
userAgentID, _ := http_mw.UserAgentIDFromCtx(r.Context())
|
||||
instanceID := authz.GetInstance(r.Context()).ID
|
||||
instanceID := authz.GetInstance(r.Context()).InstanceID()
|
||||
err = l.authRepo.VerifyMFAU2F(setContext(r.Context(), authReq.UserOrgID), authReq.UserID, authReq.UserOrgID, authReq.ID, userAgentID, instanceID, credData, domain.BrowserInfoFromRequest(r))
|
||||
if err != nil {
|
||||
l.renderU2FVerification(w, r, authReq, step.MFAProviders, err)
|
||||
|
@@ -95,7 +95,7 @@ func (l *Login) handleRegisterCheck(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
userAgentID, _ := http_mw.UserAgentIDFromCtx(r.Context())
|
||||
instanceID := authz.GetInstance(r.Context()).ID
|
||||
instanceID := authz.GetInstance(r.Context()).InstanceID()
|
||||
err = l.authRepo.SelectUser(r.Context(), authRequest.ID, user.AggregateID, userAgentID, instanceID)
|
||||
if err != nil {
|
||||
l.renderRegister(w, r, authRequest, data, err)
|
||||
|
@@ -39,7 +39,7 @@ func (l *Login) handleSelectUser(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
userAgentID, _ := http_mw.UserAgentIDFromCtx(r.Context())
|
||||
instanceID := authz.GetInstance(r.Context()).ID
|
||||
instanceID := authz.GetInstance(r.Context()).InstanceID()
|
||||
err = l.authRepo.SelectUser(r.Context(), authSession.ID, data.UserID, userAgentID, instanceID)
|
||||
if err != nil {
|
||||
l.renderError(w, r, authSession, err)
|
||||
|
Reference in New Issue
Block a user