mirror of
https://github.com/zitadel/zitadel.git
synced 2024-12-12 02:54:20 +00:00
feat: add get my password policy (#346)
* feat: add get my password policy * fix: failed merges
This commit is contained in:
parent
5251fc712c
commit
645c4597e8
18
internal/auth/repository/eventsourcing/eventstore/policy.go
Normal file
18
internal/auth/repository/eventsourcing/eventstore/policy.go
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
package eventstore
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/caos/zitadel/internal/api/auth"
|
||||||
|
pol_model "github.com/caos/zitadel/internal/policy/model"
|
||||||
|
pol_event "github.com/caos/zitadel/internal/policy/repository/eventsourcing"
|
||||||
|
)
|
||||||
|
|
||||||
|
type PolicyRepo struct {
|
||||||
|
PolicyEvents *pol_event.PolicyEventstore
|
||||||
|
}
|
||||||
|
|
||||||
|
func (repo *PolicyRepo) GetMyPasswordComplexityPolicy(ctx context.Context) (*pol_model.PasswordComplexityPolicy, error) {
|
||||||
|
ctxData := auth.GetCtxData(ctx)
|
||||||
|
return repo.PolicyEvents.GetPasswordComplexityPolicy(ctx, ctxData.OrgID)
|
||||||
|
}
|
@ -44,6 +44,7 @@ type EsRepository struct {
|
|||||||
eventstore.UserGrantRepo
|
eventstore.UserGrantRepo
|
||||||
eventstore.OrgRepository
|
eventstore.OrgRepository
|
||||||
eventstore.IamRepository
|
eventstore.IamRepository
|
||||||
|
eventstore.PolicyRepo
|
||||||
}
|
}
|
||||||
|
|
||||||
func Start(conf Config, authZ auth.Config, systemDefaults sd.SystemDefaults, authZRepo *authz_repo.EsRepository) (*EsRepository, error) {
|
func Start(conf Config, authZ auth.Config, systemDefaults sd.SystemDefaults, authZRepo *authz_repo.EsRepository) (*EsRepository, error) {
|
||||||
@ -173,6 +174,9 @@ func Start(conf Config, authZ auth.Config, systemDefaults sd.SystemDefaults, aut
|
|||||||
IamEvents: iam,
|
IamEvents: iam,
|
||||||
IamID: systemDefaults.IamID,
|
IamID: systemDefaults.IamID,
|
||||||
},
|
},
|
||||||
|
eventstore.PolicyRepo{
|
||||||
|
PolicyEvents: policy,
|
||||||
|
},
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
10
internal/auth/repository/policy.go
Normal file
10
internal/auth/repository/policy.go
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
package repository
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"github.com/caos/zitadel/internal/policy/model"
|
||||||
|
)
|
||||||
|
|
||||||
|
type PolicyRepository interface {
|
||||||
|
GetMyPasswordComplexityPolicy(ctx context.Context) (*model.PasswordComplexityPolicy, error)
|
||||||
|
}
|
@ -13,4 +13,5 @@ type Repository interface {
|
|||||||
KeyRepository
|
KeyRepository
|
||||||
UserSessionRepository
|
UserSessionRepository
|
||||||
UserGrantRepository
|
UserGrantRepository
|
||||||
|
PolicyRepository
|
||||||
}
|
}
|
||||||
|
@ -100,6 +100,11 @@ var AuthService_AuthMethods = utils_auth.MethodMapping{
|
|||||||
CheckParam: "",
|
CheckParam: "",
|
||||||
},
|
},
|
||||||
|
|
||||||
|
"/caos.zitadel.auth.api.v1.AuthService/GetMyPasswordComplexityPolicy": utils_auth.Option{
|
||||||
|
Permission: "authenticated",
|
||||||
|
CheckParam: "",
|
||||||
|
},
|
||||||
|
|
||||||
"/caos.zitadel.auth.api.v1.AuthService/AddMfaOTP": utils_auth.Option{
|
"/caos.zitadel.auth.api.v1.AuthService/AddMfaOTP": utils_auth.Option{
|
||||||
Permission: "authenticated",
|
Permission: "authenticated",
|
||||||
CheckParam: "",
|
CheckParam: "",
|
||||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -112,6 +112,22 @@
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"/policies/passwords/complexity": {
|
||||||
|
"get": {
|
||||||
|
"operationId": "GetMyPasswordComplexityPolicy",
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "A successful response.",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/v1PasswordComplexityPolicy"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"tags": [
|
||||||
|
"AuthService"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
"/ready": {
|
"/ready": {
|
||||||
"get": {
|
"get": {
|
||||||
"operationId": "Ready",
|
"operationId": "Ready",
|
||||||
@ -591,7 +607,7 @@
|
|||||||
"200": {
|
"200": {
|
||||||
"description": "A successful response.",
|
"description": "A successful response.",
|
||||||
"schema": {
|
"schema": {
|
||||||
"type": "object"
|
"$ref": "#/definitions/protobufStruct"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -602,6 +618,19 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"definitions": {
|
"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": {
|
"protobufNullValue": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": [
|
"enum": [
|
||||||
@ -610,6 +639,51 @@
|
|||||||
"default": "NULL_VALUE",
|
"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."
|
"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."
|
||||||
|
},
|
||||||
"v1Change": {
|
"v1Change": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
@ -631,7 +705,7 @@
|
|||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
"data": {
|
"data": {
|
||||||
"type": "object"
|
"$ref": "#/definitions/protobufStruct"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -823,6 +897,53 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"v1PasswordComplexityPolicy": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"id": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"description": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"creation_date": {
|
||||||
|
"type": "string",
|
||||||
|
"format": "date-time"
|
||||||
|
},
|
||||||
|
"change_date": {
|
||||||
|
"type": "string",
|
||||||
|
"format": "date-time"
|
||||||
|
},
|
||||||
|
"min_length": {
|
||||||
|
"type": "string",
|
||||||
|
"format": "uint64"
|
||||||
|
},
|
||||||
|
"has_lowercase": {
|
||||||
|
"type": "boolean",
|
||||||
|
"format": "boolean"
|
||||||
|
},
|
||||||
|
"has_uppercase": {
|
||||||
|
"type": "boolean",
|
||||||
|
"format": "boolean"
|
||||||
|
},
|
||||||
|
"has_number": {
|
||||||
|
"type": "boolean",
|
||||||
|
"format": "boolean"
|
||||||
|
},
|
||||||
|
"has_symbol": {
|
||||||
|
"type": "boolean",
|
||||||
|
"format": "boolean"
|
||||||
|
},
|
||||||
|
"sequence": {
|
||||||
|
"type": "string",
|
||||||
|
"format": "uint64"
|
||||||
|
},
|
||||||
|
"is_default": {
|
||||||
|
"type": "boolean",
|
||||||
|
"format": "boolean"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"v1SearchMethod": {
|
"v1SearchMethod": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": [
|
"enum": [
|
||||||
|
29
pkg/auth/api/grpc/policy_complexity_converter.go
Normal file
29
pkg/auth/api/grpc/policy_complexity_converter.go
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
package grpc
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/caos/logging"
|
||||||
|
"github.com/caos/zitadel/internal/policy/model"
|
||||||
|
"github.com/golang/protobuf/ptypes"
|
||||||
|
)
|
||||||
|
|
||||||
|
func passwordComplexityPolicyFromModel(policy *model.PasswordComplexityPolicy) *PasswordComplexityPolicy {
|
||||||
|
creationDate, err := ptypes.TimestampProto(policy.CreationDate)
|
||||||
|
logging.Log("GRPC-Lsi3d").OnError(err).Debug("unable to parse timestamp")
|
||||||
|
|
||||||
|
changeDate, err := ptypes.TimestampProto(policy.ChangeDate)
|
||||||
|
logging.Log("GRPC-P0wr4").OnError(err).Debug("unable to parse timestamp")
|
||||||
|
|
||||||
|
return &PasswordComplexityPolicy{
|
||||||
|
Id: policy.AggregateID,
|
||||||
|
CreationDate: creationDate,
|
||||||
|
ChangeDate: changeDate,
|
||||||
|
Description: policy.Description,
|
||||||
|
Sequence: policy.Sequence,
|
||||||
|
MinLength: policy.MinLength,
|
||||||
|
HasLowercase: policy.HasLowercase,
|
||||||
|
HasUppercase: policy.HasUppercase,
|
||||||
|
HasNumber: policy.HasNumber,
|
||||||
|
HasSymbol: policy.HasSymbol,
|
||||||
|
IsDefault: policy.AggregateID == "",
|
||||||
|
}
|
||||||
|
}
|
@ -111,6 +111,14 @@ func (s *Server) ChangeMyPassword(ctx context.Context, request *PasswordChange)
|
|||||||
return &empty.Empty{}, err
|
return &empty.Empty{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *Server) GetMyPasswordComplexityPolicy(ctx context.Context, _ *empty.Empty) (*PasswordComplexityPolicy, error) {
|
||||||
|
policy, err := s.repo.GetMyPasswordComplexityPolicy(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return passwordComplexityPolicyFromModel(policy), nil
|
||||||
|
}
|
||||||
|
|
||||||
func (s *Server) AddMfaOTP(ctx context.Context, _ *empty.Empty) (_ *MfaOtpResponse, err error) {
|
func (s *Server) AddMfaOTP(ctx context.Context, _ *empty.Empty) (_ *MfaOtpResponse, err error) {
|
||||||
otp, err := s.repo.AddMyMfaOTP(ctx)
|
otp, err := s.repo.AddMyMfaOTP(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -231,6 +231,16 @@ service AuthService {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rpc GetMyPasswordComplexityPolicy(google.protobuf.Empty) returns (PasswordComplexityPolicy) {
|
||||||
|
option (google.api.http) = {
|
||||||
|
get: "/policies/passwords/complexity"
|
||||||
|
};
|
||||||
|
|
||||||
|
option (caos.zitadel.utils.v1.auth_option) = {
|
||||||
|
permission: "authenticated"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
// MFA
|
// MFA
|
||||||
rpc AddMfaOTP(google.protobuf.Empty) returns (MfaOtpResponse) {
|
rpc AddMfaOTP(google.protobuf.Empty) returns (MfaOtpResponse) {
|
||||||
option (google.api.http) = {
|
option (google.api.http) = {
|
||||||
@ -653,4 +663,18 @@ message Change {
|
|||||||
string editor_id = 4;
|
string editor_id = 4;
|
||||||
string editor = 5;
|
string editor = 5;
|
||||||
google.protobuf.Struct data = 6;
|
google.protobuf.Struct data = 6;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
message PasswordComplexityPolicy {
|
||||||
|
string id = 1;
|
||||||
|
string description = 2;
|
||||||
|
google.protobuf.Timestamp creation_date = 3;
|
||||||
|
google.protobuf.Timestamp change_date = 4;
|
||||||
|
uint64 min_length = 5;
|
||||||
|
bool has_lowercase = 6;
|
||||||
|
bool has_uppercase = 7;
|
||||||
|
bool has_number = 8;
|
||||||
|
bool has_symbol = 9;
|
||||||
|
uint64 sequence = 10;
|
||||||
|
bool is_default = 11;
|
||||||
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -3548,7 +3548,7 @@
|
|||||||
"200": {
|
"200": {
|
||||||
"description": "A successful response.",
|
"description": "A successful response.",
|
||||||
"schema": {
|
"schema": {
|
||||||
"type": "object"
|
"$ref": "#/definitions/protobufStruct"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -3559,6 +3559,19 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"definitions": {
|
"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": {
|
"protobufNullValue": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": [
|
"enum": [
|
||||||
@ -3567,6 +3580,51 @@
|
|||||||
"default": "NULL_VALUE",
|
"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."
|
"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."
|
||||||
|
},
|
||||||
"v1AddOrgDomainRequest": {
|
"v1AddOrgDomainRequest": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
@ -3769,7 +3827,7 @@
|
|||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
"data": {
|
"data": {
|
||||||
"type": "object"
|
"$ref": "#/definitions/protobufStruct"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
Loading…
Reference in New Issue
Block a user