fix: improvements for login and oidc (#227)

* add csrf

* caching

* caching

* caching

* caching

* security headers

* csp and security headers

* error handler csp

* select user with display name

* csp

* user selection styling

* username to loginname

* regenerate grpc

* regenerate

* change to login name
This commit is contained in:
Livio Amstutz
2020-06-17 08:06:40 +02:00
committed by GitHub
parent dfe6d0deb4
commit 1c59d18fee
108 changed files with 19226 additions and 19220 deletions
+1885 -3474
View File
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+1 -62
View File
@@ -520,7 +520,7 @@
"200": {
"description": "A successful response.",
"schema": {
"$ref": "#/definitions/protobufStruct"
"type": "object"
}
}
},
@@ -531,19 +531,6 @@
}
},
"definitions": {
"protobufListValue": {
"type": "object",
"properties": {
"values": {
"type": "array",
"items": {
"$ref": "#/definitions/protobufValue"
},
"description": "Repeated field of dynamically typed values."
}
},
"description": "`ListValue` is a wrapper around a repeated field of values.\n\nThe JSON representation for `ListValue` is JSON array."
},
"protobufNullValue": {
"type": "string",
"enum": [
@@ -552,51 +539,6 @@
"default": "NULL_VALUE",
"description": "`NullValue` is a singleton enumeration to represent the null value for the\n`Value` type union.\n\n The JSON representation for `NullValue` is JSON `null`.\n\n - NULL_VALUE: Null value."
},
"protobufStruct": {
"type": "object",
"properties": {
"fields": {
"type": "object",
"additionalProperties": {
"$ref": "#/definitions/protobufValue"
},
"description": "Unordered map of dynamically typed values."
}
},
"description": "`Struct` represents a structured data value, consisting of fields\nwhich map to dynamically typed values. In some languages, `Struct`\nmight be supported by a native representation. For example, in\nscripting languages like JS a struct is represented as an\nobject. The details of that representation are described together\nwith the proto support for the language.\n\nThe JSON representation for `Struct` is JSON object."
},
"protobufValue": {
"type": "object",
"properties": {
"null_value": {
"$ref": "#/definitions/protobufNullValue",
"description": "Represents a null value."
},
"number_value": {
"type": "number",
"format": "double",
"description": "Represents a double value."
},
"string_value": {
"type": "string",
"description": "Represents a string value."
},
"bool_value": {
"type": "boolean",
"format": "boolean",
"description": "Represents a boolean value."
},
"struct_value": {
"$ref": "#/definitions/protobufStruct",
"description": "Represents a structured value."
},
"list_value": {
"$ref": "#/definitions/protobufListValue",
"description": "Represents a repeated `Value`."
}
},
"description": "`Value` represents a dynamically typed value which can be either\nnull, a number, a string, a boolean, a recursive struct value, or a\nlist of values. A producer of value is expected to set one of that\nvariants, absence of any variant indicates an error.\n\nThe JSON representation for `Value` is JSON value."
},
"v1Gender": {
"type": "string",
"enum": [
@@ -826,9 +768,6 @@
"nick_name": {
"type": "string"
},
"display_name": {
"type": "string"
},
"preferred_language": {
"type": "string"
},
+8 -8
View File
@@ -138,14 +138,14 @@ func (mr *MockAuthServiceClientMockRecorder) GetMyMfas(arg0, arg1 interface{}, a
}
// GetMyUserAddress mocks base method
func (m *MockAuthServiceClient) GetMyUserAddress(arg0 context.Context, arg1 *emptypb.Empty, arg2 ...grpc0.CallOption) (*grpc.UserAddress, error) {
func (m *MockAuthServiceClient) GetMyUserAddress(arg0 context.Context, arg1 *emptypb.Empty, arg2 ...grpc0.CallOption) (*grpc.UserAddressView, error) {
m.ctrl.T.Helper()
varargs := []interface{}{arg0, arg1}
for _, a := range arg2 {
varargs = append(varargs, a)
}
ret := m.ctrl.Call(m, "GetMyUserAddress", varargs...)
ret0, _ := ret[0].(*grpc.UserAddress)
ret0, _ := ret[0].(*grpc.UserAddressView)
ret1, _ := ret[1].(error)
return ret0, ret1
}
@@ -158,14 +158,14 @@ func (mr *MockAuthServiceClientMockRecorder) GetMyUserAddress(arg0, arg1 interfa
}
// GetMyUserEmail mocks base method
func (m *MockAuthServiceClient) GetMyUserEmail(arg0 context.Context, arg1 *emptypb.Empty, arg2 ...grpc0.CallOption) (*grpc.UserEmail, error) {
func (m *MockAuthServiceClient) GetMyUserEmail(arg0 context.Context, arg1 *emptypb.Empty, arg2 ...grpc0.CallOption) (*grpc.UserEmailView, error) {
m.ctrl.T.Helper()
varargs := []interface{}{arg0, arg1}
for _, a := range arg2 {
varargs = append(varargs, a)
}
ret := m.ctrl.Call(m, "GetMyUserEmail", varargs...)
ret0, _ := ret[0].(*grpc.UserEmail)
ret0, _ := ret[0].(*grpc.UserEmailView)
ret1, _ := ret[1].(error)
return ret0, ret1
}
@@ -178,14 +178,14 @@ func (mr *MockAuthServiceClientMockRecorder) GetMyUserEmail(arg0, arg1 interface
}
// GetMyUserPhone mocks base method
func (m *MockAuthServiceClient) GetMyUserPhone(arg0 context.Context, arg1 *emptypb.Empty, arg2 ...grpc0.CallOption) (*grpc.UserPhone, error) {
func (m *MockAuthServiceClient) GetMyUserPhone(arg0 context.Context, arg1 *emptypb.Empty, arg2 ...grpc0.CallOption) (*grpc.UserPhoneView, error) {
m.ctrl.T.Helper()
varargs := []interface{}{arg0, arg1}
for _, a := range arg2 {
varargs = append(varargs, a)
}
ret := m.ctrl.Call(m, "GetMyUserPhone", varargs...)
ret0, _ := ret[0].(*grpc.UserPhone)
ret0, _ := ret[0].(*grpc.UserPhoneView)
ret1, _ := ret[1].(error)
return ret0, ret1
}
@@ -198,14 +198,14 @@ func (mr *MockAuthServiceClientMockRecorder) GetMyUserPhone(arg0, arg1 interface
}
// GetMyUserProfile mocks base method
func (m *MockAuthServiceClient) GetMyUserProfile(arg0 context.Context, arg1 *emptypb.Empty, arg2 ...grpc0.CallOption) (*grpc.UserProfile, error) {
func (m *MockAuthServiceClient) GetMyUserProfile(arg0 context.Context, arg1 *emptypb.Empty, arg2 ...grpc0.CallOption) (*grpc.UserProfileView, error) {
m.ctrl.T.Helper()
varargs := []interface{}{arg0, arg1}
for _, a := range arg2 {
varargs = append(varargs, a)
}
ret := m.ctrl.Call(m, "GetMyUserProfile", varargs...)
ret0, _ := ret[0].(*grpc.UserProfile)
ret0, _ := ret[0].(*grpc.UserProfileView)
ret1, _ := ret[1].(error)
return ret0, ret1
}
-1
View File
@@ -66,7 +66,6 @@ func updateProfileToModel(ctx context.Context, u *UpdateUserProfileRequest) *usr
FirstName: u.FirstName,
LastName: u.LastName,
NickName: u.NickName,
DisplayName: u.DisplayName,
PreferredLanguage: preferredLanguage,
Gender: genderToModel(u.Gender),
}
+1 -1
View File
@@ -55,7 +55,7 @@ func (o *OPStorage) GetUserinfoFromScopes(ctx context.Context, userID string, sc
userInfo.FamilyName = user.LastName
userInfo.GivenName = user.FirstName
userInfo.Nickname = user.NickName
userInfo.PreferredUsername = user.UserName
userInfo.PreferredUsername = user.PreferredLoginName
userInfo.UpdatedAt = user.ChangeDate
userInfo.Gender = oidc.Gender(getGender(user.Gender))
case scopePhone:
+10 -1
View File
@@ -2,12 +2,14 @@ package oidc
import (
"context"
"net/http"
"time"
"github.com/caos/logging"
"github.com/caos/oidc/pkg/op"
http_utils "github.com/caos/zitadel/internal/api/http"
"github.com/caos/zitadel/internal/api/http/middleware"
"github.com/caos/zitadel/internal/auth/repository"
"github.com/caos/zitadel/internal/config/types"
"github.com/caos/zitadel/internal/id"
@@ -17,6 +19,7 @@ type OPHandlerConfig struct {
OPConfig *op.Config
StorageConfig StorageConfig
UserAgentCookieConfig *http_utils.UserAgentCookieConfig
Cache *middleware.CacheConfig
Endpoints *EndpointConfig
}
@@ -51,6 +54,12 @@ type OPStorage struct {
func NewProvider(ctx context.Context, config OPHandlerConfig, repo repository.Repository) op.OpenIDProvider {
cookieHandler, err := http_utils.NewUserAgentHandler(config.UserAgentCookieConfig, id.SonyFlakeGenerator)
logging.Log("OIDC-sd4fd").OnError(err).Panic("cannot user agent handler")
cache, err := middleware.DefaultCacheInterceptor(config.Endpoints.Keys.Path, config.Cache.MaxAge.Duration, config.Cache.SharedMaxAge.Duration)
nextHandler := func(handlerFunc http.HandlerFunc) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
cache(http_utils.CopyHeadersToContext(handlerFunc))
}
}
provider, err := op.NewDefaultOP(
ctx,
config.OPConfig,
@@ -58,7 +67,7 @@ func NewProvider(ctx context.Context, config OPHandlerConfig, repo repository.Re
op.WithHttpInterceptor(
UserAgentCookieHandler(
cookieHandler,
http_utils.CopyHeadersToContext,
nextHandler,
),
),
op.WithCustomAuthEndpoint(op.NewEndpointWithURL(config.Endpoints.Auth.Path, config.Endpoints.Auth.URL)),
+2 -3
View File
@@ -381,9 +381,8 @@ message UpdateUserProfileRequest {
string first_name = 1 [(validate.rules).string = {min_len: 1, max_len: 200}];
string last_name = 2 [(validate.rules).string = {min_len: 1, max_len: 200}];
string nick_name = 3 [(validate.rules).string = {min_len: 1, max_len: 200}];
string display_name = 4 [(validate.rules).string = {min_len: 1, max_len: 200}];
string preferred_language = 5 [(validate.rules).string = {min_len: 1, max_len: 200}];
Gender gender = 6;
string preferred_language = 4 [(validate.rules).string = {min_len: 1, max_len: 200}];
Gender gender = 5;
}
message UserEmail {