mirror of
https://github.com/usememos/memos.git
synced 2024-09-11 03:55:30 +03:00
chore: migrate idp service
This commit is contained in:
parent
a77703260f
commit
c373131b89
@ -12,21 +12,21 @@ import (
|
||||
"golang.org/x/oauth2"
|
||||
|
||||
"github.com/usememos/memos/plugin/idp"
|
||||
"github.com/usememos/memos/store"
|
||||
storepb "github.com/usememos/memos/proto/gen/store"
|
||||
)
|
||||
|
||||
// IdentityProvider represents an OAuth2 Identity Provider.
|
||||
type IdentityProvider struct {
|
||||
config *store.IdentityProviderOAuth2Config
|
||||
config *storepb.OAuth2Config
|
||||
}
|
||||
|
||||
// NewIdentityProvider initializes a new OAuth2 Identity Provider with the given configuration.
|
||||
func NewIdentityProvider(config *store.IdentityProviderOAuth2Config) (*IdentityProvider, error) {
|
||||
func NewIdentityProvider(config *storepb.OAuth2Config) (*IdentityProvider, error) {
|
||||
for v, field := range map[string]string{
|
||||
config.ClientID: "clientId",
|
||||
config.ClientId: "clientId",
|
||||
config.ClientSecret: "clientSecret",
|
||||
config.TokenURL: "tokenUrl",
|
||||
config.UserInfoURL: "userInfoUrl",
|
||||
config.TokenUrl: "tokenUrl",
|
||||
config.UserInfoUrl: "userInfoUrl",
|
||||
config.FieldMapping.Identifier: "fieldMapping.identifier",
|
||||
} {
|
||||
if v == "" {
|
||||
@ -42,13 +42,13 @@ func NewIdentityProvider(config *store.IdentityProviderOAuth2Config) (*IdentityP
|
||||
// ExchangeToken returns the exchanged OAuth2 token using the given authorization code.
|
||||
func (p *IdentityProvider) ExchangeToken(ctx context.Context, redirectURL, code string) (string, error) {
|
||||
conf := &oauth2.Config{
|
||||
ClientID: p.config.ClientID,
|
||||
ClientID: p.config.ClientId,
|
||||
ClientSecret: p.config.ClientSecret,
|
||||
RedirectURL: redirectURL,
|
||||
Scopes: p.config.Scopes,
|
||||
Endpoint: oauth2.Endpoint{
|
||||
AuthURL: p.config.AuthURL,
|
||||
TokenURL: p.config.TokenURL,
|
||||
AuthURL: p.config.AuthUrl,
|
||||
TokenURL: p.config.TokenUrl,
|
||||
AuthStyle: oauth2.AuthStyleInParams,
|
||||
},
|
||||
}
|
||||
@ -69,7 +69,7 @@ func (p *IdentityProvider) ExchangeToken(ctx context.Context, redirectURL, code
|
||||
// UserInfo returns the parsed user information using the given OAuth2 token.
|
||||
func (p *IdentityProvider) UserInfo(token string) (*idp.IdentityProviderUserInfo, error) {
|
||||
client := &http.Client{}
|
||||
req, err := http.NewRequest(http.MethodGet, p.config.UserInfoURL, nil)
|
||||
req, err := http.NewRequest(http.MethodGet, p.config.UserInfoUrl, nil)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to new http request")
|
||||
}
|
||||
|
@ -14,24 +14,24 @@ import (
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/usememos/memos/plugin/idp"
|
||||
"github.com/usememos/memos/store"
|
||||
storepb "github.com/usememos/memos/proto/gen/store"
|
||||
)
|
||||
|
||||
func TestNewIdentityProvider(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
config *store.IdentityProviderOAuth2Config
|
||||
config *storepb.OAuth2Config
|
||||
containsErr string
|
||||
}{
|
||||
{
|
||||
name: "no tokenUrl",
|
||||
config: &store.IdentityProviderOAuth2Config{
|
||||
ClientID: "test-client-id",
|
||||
config: &storepb.OAuth2Config{
|
||||
ClientId: "test-client-id",
|
||||
ClientSecret: "test-client-secret",
|
||||
AuthURL: "",
|
||||
TokenURL: "",
|
||||
UserInfoURL: "https://example.com/api/user",
|
||||
FieldMapping: &store.FieldMapping{
|
||||
AuthUrl: "",
|
||||
TokenUrl: "",
|
||||
UserInfoUrl: "https://example.com/api/user",
|
||||
FieldMapping: &storepb.FieldMapping{
|
||||
Identifier: "login",
|
||||
},
|
||||
},
|
||||
@ -39,13 +39,13 @@ func TestNewIdentityProvider(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "no userInfoUrl",
|
||||
config: &store.IdentityProviderOAuth2Config{
|
||||
ClientID: "test-client-id",
|
||||
config: &storepb.OAuth2Config{
|
||||
ClientId: "test-client-id",
|
||||
ClientSecret: "test-client-secret",
|
||||
AuthURL: "",
|
||||
TokenURL: "https://example.com/token",
|
||||
UserInfoURL: "",
|
||||
FieldMapping: &store.FieldMapping{
|
||||
AuthUrl: "",
|
||||
TokenUrl: "https://example.com/token",
|
||||
UserInfoUrl: "",
|
||||
FieldMapping: &storepb.FieldMapping{
|
||||
Identifier: "login",
|
||||
},
|
||||
},
|
||||
@ -53,13 +53,13 @@ func TestNewIdentityProvider(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "no field mapping identifier",
|
||||
config: &store.IdentityProviderOAuth2Config{
|
||||
ClientID: "test-client-id",
|
||||
config: &storepb.OAuth2Config{
|
||||
ClientId: "test-client-id",
|
||||
ClientSecret: "test-client-secret",
|
||||
AuthURL: "",
|
||||
TokenURL: "https://example.com/token",
|
||||
UserInfoURL: "https://example.com/api/user",
|
||||
FieldMapping: &store.FieldMapping{
|
||||
AuthUrl: "",
|
||||
TokenUrl: "https://example.com/token",
|
||||
UserInfoUrl: "https://example.com/api/user",
|
||||
FieldMapping: &storepb.FieldMapping{
|
||||
Identifier: "",
|
||||
},
|
||||
},
|
||||
@ -113,7 +113,7 @@ func TestIdentityProvider(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
|
||||
const (
|
||||
testClientID = "test-client-id"
|
||||
testClientId = "test-client-id"
|
||||
testCode = "test-code"
|
||||
testAccessToken = "test-access-token"
|
||||
testSubject = "123456789"
|
||||
@ -132,12 +132,12 @@ func TestIdentityProvider(t *testing.T) {
|
||||
s := newMockServer(t, testCode, testAccessToken, userInfo)
|
||||
|
||||
oauth2, err := NewIdentityProvider(
|
||||
&store.IdentityProviderOAuth2Config{
|
||||
ClientID: testClientID,
|
||||
&storepb.OAuth2Config{
|
||||
ClientId: testClientId,
|
||||
ClientSecret: "test-client-secret",
|
||||
TokenURL: fmt.Sprintf("%s/oauth2/token", s.URL),
|
||||
UserInfoURL: fmt.Sprintf("%s/oauth2/userinfo", s.URL),
|
||||
FieldMapping: &store.FieldMapping{
|
||||
TokenUrl: fmt.Sprintf("%s/oauth2/token", s.URL),
|
||||
UserInfoUrl: fmt.Sprintf("%s/oauth2/userinfo", s.URL),
|
||||
FieldMapping: &storepb.FieldMapping{
|
||||
Identifier: "sub",
|
||||
DisplayName: "name",
|
||||
Email: "email",
|
||||
|
@ -54,7 +54,7 @@ message IdentityProvider {
|
||||
|
||||
message IdentityProviderConfig {
|
||||
oneof config {
|
||||
OAuth2Config oauth2 = 1;
|
||||
OAuth2Config oauth2_config = 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -53,7 +53,7 @@ message Storage {
|
||||
}
|
||||
|
||||
message StorageConfig {
|
||||
oneof storage_config {
|
||||
oneof config {
|
||||
S3Config s3_config = 1;
|
||||
}
|
||||
}
|
||||
|
@ -1160,7 +1160,7 @@ Used internally for obfuscating the page token.
|
||||
|
||||
| Field | Type | Label | Description |
|
||||
| ----- | ---- | ----- | ----------- |
|
||||
| oauth2 | [OAuth2Config](#memos-api-v2-OAuth2Config) | | |
|
||||
| oauth2_config | [OAuth2Config](#memos-api-v2-OAuth2Config) | | |
|
||||
|
||||
|
||||
|
||||
|
@ -156,7 +156,7 @@ type IdentityProviderConfig struct {
|
||||
|
||||
// Types that are assignable to Config:
|
||||
//
|
||||
// *IdentityProviderConfig_Oauth2
|
||||
// *IdentityProviderConfig_Oauth2Config
|
||||
Config isIdentityProviderConfig_Config `protobuf_oneof:"config"`
|
||||
}
|
||||
|
||||
@ -199,9 +199,9 @@ func (m *IdentityProviderConfig) GetConfig() isIdentityProviderConfig_Config {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *IdentityProviderConfig) GetOauth2() *OAuth2Config {
|
||||
if x, ok := x.GetConfig().(*IdentityProviderConfig_Oauth2); ok {
|
||||
return x.Oauth2
|
||||
func (x *IdentityProviderConfig) GetOauth2Config() *OAuth2Config {
|
||||
if x, ok := x.GetConfig().(*IdentityProviderConfig_Oauth2Config); ok {
|
||||
return x.Oauth2Config
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@ -210,11 +210,11 @@ type isIdentityProviderConfig_Config interface {
|
||||
isIdentityProviderConfig_Config()
|
||||
}
|
||||
|
||||
type IdentityProviderConfig_Oauth2 struct {
|
||||
Oauth2 *OAuth2Config `protobuf:"bytes,1,opt,name=oauth2,proto3,oneof"`
|
||||
type IdentityProviderConfig_Oauth2Config struct {
|
||||
Oauth2Config *OAuth2Config `protobuf:"bytes,1,opt,name=oauth2_config,json=oauth2Config,proto3,oneof"`
|
||||
}
|
||||
|
||||
func (*IdentityProviderConfig_Oauth2) isIdentityProviderConfig_Config() {}
|
||||
func (*IdentityProviderConfig_Oauth2Config) isIdentityProviderConfig_Config() {}
|
||||
|
||||
type FieldMapping struct {
|
||||
state protoimpl.MessageState
|
||||
@ -872,159 +872,159 @@ var file_api_v2_idp_service_proto_rawDesc = []byte{
|
||||
0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x06, 0x63, 0x6f,
|
||||
0x6e, 0x66, 0x69, 0x67, 0x22, 0x28, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x14, 0x0a, 0x10,
|
||||
0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44,
|
||||
0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x4f, 0x41, 0x55, 0x54, 0x48, 0x32, 0x10, 0x01, 0x22, 0x58,
|
||||
0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x4f, 0x41, 0x55, 0x54, 0x48, 0x32, 0x10, 0x01, 0x22, 0x65,
|
||||
0x0a, 0x16, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64,
|
||||
0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x34, 0x0a, 0x06, 0x6f, 0x61, 0x75, 0x74,
|
||||
0x68, 0x32, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73,
|
||||
0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x4f, 0x41, 0x75, 0x74, 0x68, 0x32, 0x43, 0x6f,
|
||||
0x6e, 0x66, 0x69, 0x67, 0x48, 0x00, 0x52, 0x06, 0x6f, 0x61, 0x75, 0x74, 0x68, 0x32, 0x42, 0x08,
|
||||
0x0a, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x22, 0x67, 0x0a, 0x0c, 0x46, 0x69, 0x65, 0x6c,
|
||||
0x64, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x12, 0x1e, 0x0a, 0x0a, 0x69, 0x64, 0x65, 0x6e,
|
||||
0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x69, 0x64,
|
||||
0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x12, 0x21, 0x0a, 0x0c, 0x64, 0x69, 0x73, 0x70,
|
||||
0x6c, 0x61, 0x79, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b,
|
||||
0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x65,
|
||||
0x6d, 0x61, 0x69, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x6d, 0x61, 0x69,
|
||||
0x6c, 0x22, 0x85, 0x02, 0x0a, 0x0c, 0x4f, 0x41, 0x75, 0x74, 0x68, 0x32, 0x43, 0x6f, 0x6e, 0x66,
|
||||
0x69, 0x67, 0x12, 0x1b, 0x0a, 0x09, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18,
|
||||
0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x12,
|
||||
0x23, 0x0a, 0x0d, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74,
|
||||
0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x53, 0x65,
|
||||
0x63, 0x72, 0x65, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x61, 0x75, 0x74, 0x68, 0x5f, 0x75, 0x72, 0x6c,
|
||||
0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x75, 0x74, 0x68, 0x55, 0x72, 0x6c, 0x12,
|
||||
0x1b, 0x0a, 0x09, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x04, 0x20, 0x01,
|
||||
0x28, 0x09, 0x52, 0x08, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x55, 0x72, 0x6c, 0x12, 0x22, 0x0a, 0x0d,
|
||||
0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x05, 0x20,
|
||||
0x01, 0x28, 0x09, 0x52, 0x0b, 0x75, 0x73, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x55, 0x72, 0x6c,
|
||||
0x12, 0x16, 0x0a, 0x06, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x09,
|
||||
0x52, 0x06, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x73, 0x12, 0x3f, 0x0a, 0x0d, 0x66, 0x69, 0x65, 0x6c,
|
||||
0x64, 0x5f, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32,
|
||||
0x1a, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x46,
|
||||
0x69, 0x65, 0x6c, 0x64, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x52, 0x0c, 0x66, 0x69, 0x65,
|
||||
0x6c, 0x64, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x22, 0x1e, 0x0a, 0x1c, 0x4c, 0x69, 0x73,
|
||||
0x74, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65,
|
||||
0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x6e, 0x0a, 0x1d, 0x4c, 0x69, 0x73,
|
||||
0x74, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65,
|
||||
0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4d, 0x0a, 0x12, 0x69, 0x64,
|
||||
0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x5f, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x73,
|
||||
0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61,
|
||||
0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x50, 0x72,
|
||||
0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x52, 0x11, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79,
|
||||
0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x73, 0x22, 0x30, 0x0a, 0x1a, 0x47, 0x65, 0x74,
|
||||
0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72,
|
||||
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18,
|
||||
0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x6a, 0x0a, 0x1b, 0x47,
|
||||
0x65, 0x74, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64,
|
||||
0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4b, 0x0a, 0x11, 0x69, 0x64,
|
||||
0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x5f, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x18,
|
||||
0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70,
|
||||
0x69, 0x2e, 0x76, 0x32, 0x2e, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f,
|
||||
0x76, 0x69, 0x64, 0x65, 0x72, 0x52, 0x10, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x50,
|
||||
0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x22, 0x6c, 0x0a, 0x1d, 0x43, 0x72, 0x65, 0x61, 0x74,
|
||||
0x65, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65,
|
||||
0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x4b, 0x0a, 0x11, 0x69, 0x64, 0x65, 0x6e,
|
||||
0x74, 0x69, 0x74, 0x79, 0x5f, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x18, 0x01, 0x20,
|
||||
0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e,
|
||||
0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x41, 0x0a, 0x0d, 0x6f, 0x61, 0x75, 0x74,
|
||||
0x68, 0x32, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32,
|
||||
0x1a, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x4f,
|
||||
0x41, 0x75, 0x74, 0x68, 0x32, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x48, 0x00, 0x52, 0x0c, 0x6f,
|
||||
0x61, 0x75, 0x74, 0x68, 0x32, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x42, 0x08, 0x0a, 0x06, 0x63,
|
||||
0x6f, 0x6e, 0x66, 0x69, 0x67, 0x22, 0x67, 0x0a, 0x0c, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x4d, 0x61,
|
||||
0x70, 0x70, 0x69, 0x6e, 0x67, 0x12, 0x1e, 0x0a, 0x0a, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66,
|
||||
0x69, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x69, 0x64, 0x65, 0x6e, 0x74,
|
||||
0x69, 0x66, 0x69, 0x65, 0x72, 0x12, 0x21, 0x0a, 0x0c, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79,
|
||||
0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x69, 0x73,
|
||||
0x70, 0x6c, 0x61, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69,
|
||||
0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x22, 0x85,
|
||||
0x02, 0x0a, 0x0c, 0x4f, 0x41, 0x75, 0x74, 0x68, 0x32, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12,
|
||||
0x1b, 0x0a, 0x09, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01,
|
||||
0x28, 0x09, 0x52, 0x08, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x23, 0x0a, 0x0d,
|
||||
0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x18, 0x02, 0x20,
|
||||
0x01, 0x28, 0x09, 0x52, 0x0c, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x53, 0x65, 0x63, 0x72, 0x65,
|
||||
0x74, 0x12, 0x19, 0x0a, 0x08, 0x61, 0x75, 0x74, 0x68, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x03, 0x20,
|
||||
0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x75, 0x74, 0x68, 0x55, 0x72, 0x6c, 0x12, 0x1b, 0x0a, 0x09,
|
||||
0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52,
|
||||
0x08, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x55, 0x72, 0x6c, 0x12, 0x22, 0x0a, 0x0d, 0x75, 0x73, 0x65,
|
||||
0x72, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09,
|
||||
0x52, 0x0b, 0x75, 0x73, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x55, 0x72, 0x6c, 0x12, 0x16, 0x0a,
|
||||
0x06, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x73,
|
||||
0x63, 0x6f, 0x70, 0x65, 0x73, 0x12, 0x3f, 0x0a, 0x0d, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x5f, 0x6d,
|
||||
0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x6d,
|
||||
0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x46, 0x69, 0x65, 0x6c,
|
||||
0x64, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x52, 0x0c, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x4d,
|
||||
0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x22, 0x1e, 0x0a, 0x1c, 0x4c, 0x69, 0x73, 0x74, 0x49, 0x64,
|
||||
0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x73, 0x52,
|
||||
0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x6e, 0x0a, 0x1d, 0x4c, 0x69, 0x73, 0x74, 0x49, 0x64,
|
||||
0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x73, 0x52,
|
||||
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4d, 0x0a, 0x12, 0x69, 0x64, 0x65, 0x6e, 0x74,
|
||||
0x69, 0x74, 0x79, 0x5f, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20,
|
||||
0x03, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e,
|
||||
0x76, 0x32, 0x2e, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, 0x76, 0x69,
|
||||
0x64, 0x65, 0x72, 0x52, 0x10, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f,
|
||||
0x76, 0x69, 0x64, 0x65, 0x72, 0x22, 0x6d, 0x0a, 0x1e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x49,
|
||||
0x64, 0x65, 0x72, 0x52, 0x11, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f,
|
||||
0x76, 0x69, 0x64, 0x65, 0x72, 0x73, 0x22, 0x30, 0x0a, 0x1a, 0x47, 0x65, 0x74, 0x49, 0x64, 0x65,
|
||||
0x6e, 0x74, 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x52, 0x65, 0x71,
|
||||
0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01,
|
||||
0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x6a, 0x0a, 0x1b, 0x47, 0x65, 0x74, 0x49,
|
||||
0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x52,
|
||||
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4b, 0x0a, 0x11, 0x69, 0x64, 0x65, 0x6e, 0x74,
|
||||
0x69, 0x74, 0x79, 0x5f, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01,
|
||||
0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76,
|
||||
0x32, 0x2e, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64,
|
||||
0x65, 0x72, 0x52, 0x10, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, 0x76,
|
||||
0x69, 0x64, 0x65, 0x72, 0x22, 0xa9, 0x01, 0x0a, 0x1d, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x49,
|
||||
0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x52,
|
||||
0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x4b, 0x0a, 0x11, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69,
|
||||
0x74, 0x79, 0x5f, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28,
|
||||
0x0b, 0x32, 0x1e, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32,
|
||||
0x2e, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65,
|
||||
0x72, 0x52, 0x10, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, 0x76, 0x69,
|
||||
0x64, 0x65, 0x72, 0x12, 0x3b, 0x0a, 0x0b, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x6d, 0x61,
|
||||
0x73, 0x6b, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c,
|
||||
0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64,
|
||||
0x4d, 0x61, 0x73, 0x6b, 0x52, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x61, 0x73, 0x6b,
|
||||
0x22, 0x6d, 0x0a, 0x1e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69,
|
||||
0x74, 0x79, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
|
||||
0x73, 0x65, 0x12, 0x4b, 0x0a, 0x11, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x5f, 0x70,
|
||||
0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e,
|
||||
0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x49, 0x64, 0x65,
|
||||
0x6e, 0x74, 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x52, 0x10, 0x69,
|
||||
0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x22,
|
||||
0x33, 0x0a, 0x1d, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74,
|
||||
0x79, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
|
||||
0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04,
|
||||
0x6e, 0x61, 0x6d, 0x65, 0x22, 0x20, 0x0a, 0x1e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x49, 0x64,
|
||||
0x69, 0x64, 0x65, 0x72, 0x22, 0x6c, 0x0a, 0x1d, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x49, 0x64,
|
||||
0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x52, 0x65,
|
||||
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, 0xf8, 0x06, 0x0a, 0x17, 0x49, 0x64, 0x65, 0x6e, 0x74,
|
||||
0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x53, 0x65, 0x72, 0x76, 0x69,
|
||||
0x63, 0x65, 0x12, 0x93, 0x01, 0x0a, 0x15, 0x4c, 0x69, 0x73, 0x74, 0x49, 0x64, 0x65, 0x6e, 0x74,
|
||||
0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x73, 0x12, 0x2a, 0x2e, 0x6d,
|
||||
0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x4c, 0x69, 0x73, 0x74,
|
||||
0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x4b, 0x0a, 0x11, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74,
|
||||
0x79, 0x5f, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b,
|
||||
0x32, 0x1e, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e,
|
||||
0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72,
|
||||
0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73,
|
||||
0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x49, 0x64, 0x65, 0x6e,
|
||||
0x74, 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73,
|
||||
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x21, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1b, 0x12, 0x19, 0x2f,
|
||||
0x61, 0x70, 0x69, 0x2f, 0x76, 0x32, 0x2f, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x50,
|
||||
0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x73, 0x12, 0x9d, 0x01, 0x0a, 0x13, 0x47, 0x65, 0x74,
|
||||
0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72,
|
||||
0x12, 0x28, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e,
|
||||
0x47, 0x65, 0x74, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, 0x76, 0x69,
|
||||
0x64, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x29, 0x2e, 0x6d, 0x65, 0x6d,
|
||||
0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x47, 0x65, 0x74, 0x49, 0x64, 0x65,
|
||||
0x6e, 0x74, 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x52, 0x65, 0x73,
|
||||
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x31, 0xda, 0x41, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x82, 0xd3,
|
||||
0xe4, 0x93, 0x02, 0x24, 0x12, 0x22, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32, 0x2f, 0x7b, 0x6e,
|
||||
0x61, 0x6d, 0x65, 0x3d, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, 0x76,
|
||||
0x69, 0x64, 0x65, 0x72, 0x73, 0x2f, 0x2a, 0x7d, 0x12, 0x96, 0x01, 0x0a, 0x16, 0x43, 0x72, 0x65,
|
||||
0x61, 0x74, 0x65, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, 0x76, 0x69,
|
||||
0x64, 0x65, 0x72, 0x12, 0x2b, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e,
|
||||
0x76, 0x32, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74,
|
||||
0x79, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
|
||||
0x1a, 0x2c, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e,
|
||||
0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x50, 0x72,
|
||||
0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x21,
|
||||
0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1b, 0x22, 0x19, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32, 0x2f,
|
||||
0x52, 0x10, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64,
|
||||
0x65, 0x72, 0x22, 0x6d, 0x0a, 0x1e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x49, 0x64, 0x65, 0x6e,
|
||||
0x74, 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70,
|
||||
0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4b, 0x0a, 0x11, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79,
|
||||
0x5f, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32,
|
||||
0x1e, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x49,
|
||||
0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x52,
|
||||
0x10, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65,
|
||||
0x72, 0x22, 0xa9, 0x01, 0x0a, 0x1d, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x49, 0x64, 0x65, 0x6e,
|
||||
0x74, 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75,
|
||||
0x65, 0x73, 0x74, 0x12, 0x4b, 0x0a, 0x11, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x5f,
|
||||
0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e,
|
||||
0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x49, 0x64,
|
||||
0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x52, 0x10,
|
||||
0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72,
|
||||
0x73, 0x12, 0xe4, 0x01, 0x0a, 0x16, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x49, 0x64, 0x65, 0x6e,
|
||||
0x74, 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x12, 0x2b, 0x2e, 0x6d,
|
||||
0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x55, 0x70, 0x64, 0x61,
|
||||
0x74, 0x65, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64,
|
||||
0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x6d, 0x65, 0x6d, 0x6f,
|
||||
0x12, 0x3b, 0x0a, 0x0b, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x6d, 0x61, 0x73, 0x6b, 0x18,
|
||||
0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70,
|
||||
0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x4d, 0x61, 0x73,
|
||||
0x6b, 0x52, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x61, 0x73, 0x6b, 0x22, 0x6d, 0x0a,
|
||||
0x1e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x50,
|
||||
0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12,
|
||||
0x4b, 0x0a, 0x11, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x5f, 0x70, 0x72, 0x6f, 0x76,
|
||||
0x69, 0x64, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x6d, 0x65, 0x6d,
|
||||
0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69,
|
||||
0x74, 0x79, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x52, 0x10, 0x69, 0x64, 0x65, 0x6e,
|
||||
0x74, 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x22, 0x33, 0x0a, 0x1d,
|
||||
0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x50, 0x72,
|
||||
0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a,
|
||||
0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d,
|
||||
0x65, 0x22, 0x20, 0x0a, 0x1e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x49, 0x64, 0x65, 0x6e, 0x74,
|
||||
0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f,
|
||||
0x6e, 0x73, 0x65, 0x32, 0xf8, 0x06, 0x0a, 0x17, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79,
|
||||
0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12,
|
||||
0x93, 0x01, 0x0a, 0x15, 0x4c, 0x69, 0x73, 0x74, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79,
|
||||
0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x73, 0x12, 0x2a, 0x2e, 0x6d, 0x65, 0x6d, 0x6f,
|
||||
0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x49, 0x64, 0x65,
|
||||
0x6e, 0x74, 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x73, 0x52, 0x65,
|
||||
0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70,
|
||||
0x69, 0x2e, 0x76, 0x32, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74,
|
||||
0x79, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
|
||||
0x73, 0x65, 0x22, 0x21, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1b, 0x12, 0x19, 0x2f, 0x61, 0x70, 0x69,
|
||||
0x2f, 0x76, 0x32, 0x2f, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, 0x76,
|
||||
0x69, 0x64, 0x65, 0x72, 0x73, 0x12, 0x9d, 0x01, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x49, 0x64, 0x65,
|
||||
0x6e, 0x74, 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x12, 0x28, 0x2e,
|
||||
0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x47, 0x65, 0x74,
|
||||
0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72,
|
||||
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x29, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e,
|
||||
0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x47, 0x65, 0x74, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69,
|
||||
0x74, 0x79, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
|
||||
0x73, 0x65, 0x22, 0x31, 0xda, 0x41, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x82, 0xd3, 0xe4, 0x93, 0x02,
|
||||
0x24, 0x12, 0x22, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32, 0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65,
|
||||
0x3d, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65,
|
||||
0x72, 0x73, 0x2f, 0x2a, 0x7d, 0x12, 0x96, 0x01, 0x0a, 0x16, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65,
|
||||
0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72,
|
||||
0x12, 0x2b, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e,
|
||||
0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x50, 0x72,
|
||||
0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e,
|
||||
0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x43, 0x72, 0x65,
|
||||
0x61, 0x74, 0x65, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, 0x76, 0x69,
|
||||
0x64, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x21, 0x82, 0xd3, 0xe4,
|
||||
0x93, 0x02, 0x1b, 0x22, 0x19, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32, 0x2f, 0x69, 0x64, 0x65,
|
||||
0x6e, 0x74, 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x73, 0x12, 0xe4,
|
||||
0x01, 0x0a, 0x16, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74,
|
||||
0x79, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x12, 0x2b, 0x2e, 0x6d, 0x65, 0x6d, 0x6f,
|
||||
0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x49,
|
||||
0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x52,
|
||||
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x6f, 0xda, 0x41, 0x1d, 0x69, 0x64, 0x65, 0x6e,
|
||||
0x74, 0x69, 0x74, 0x79, 0x5f, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2c, 0x75, 0x70,
|
||||
0x64, 0x61, 0x74, 0x65, 0x5f, 0x6d, 0x61, 0x73, 0x6b, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x49, 0x3a,
|
||||
0x11, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x5f, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64,
|
||||
0x65, 0x72, 0x32, 0x34, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32, 0x2f, 0x7b, 0x69, 0x64, 0x65,
|
||||
0x6e, 0x74, 0x69, 0x74, 0x79, 0x5f, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, 0x6e,
|
||||
0x61, 0x6d, 0x65, 0x3d, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, 0x76,
|
||||
0x69, 0x64, 0x65, 0x72, 0x73, 0x2f, 0x2a, 0x7d, 0x12, 0xa6, 0x01, 0x0a, 0x16, 0x44, 0x65, 0x6c,
|
||||
0x65, 0x74, 0x65, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, 0x76, 0x69,
|
||||
0x64, 0x65, 0x72, 0x12, 0x2b, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e,
|
||||
0x76, 0x32, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74,
|
||||
0x79, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
|
||||
0x1a, 0x2c, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e,
|
||||
0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61,
|
||||
0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x49, 0x64, 0x65, 0x6e,
|
||||
0x74, 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70,
|
||||
0x6f, 0x6e, 0x73, 0x65, 0x22, 0x6f, 0xda, 0x41, 0x1d, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74,
|
||||
0x79, 0x5f, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2c, 0x75, 0x70, 0x64, 0x61, 0x74,
|
||||
0x65, 0x5f, 0x6d, 0x61, 0x73, 0x6b, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x49, 0x3a, 0x11, 0x69, 0x64,
|
||||
0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x5f, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x32,
|
||||
0x34, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32, 0x2f, 0x7b, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69,
|
||||
0x74, 0x79, 0x5f, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, 0x6e, 0x61, 0x6d, 0x65,
|
||||
0x3d, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65,
|
||||
0x72, 0x73, 0x2f, 0x2a, 0x7d, 0x12, 0xa6, 0x01, 0x0a, 0x16, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65,
|
||||
0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72,
|
||||
0x12, 0x2b, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e,
|
||||
0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x50, 0x72,
|
||||
0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x31,
|
||||
0xda, 0x41, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x24, 0x2a, 0x22, 0x2f,
|
||||
0x61, 0x70, 0x69, 0x2f, 0x76, 0x32, 0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x69, 0x64, 0x65,
|
||||
0x6e, 0x74, 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x73, 0x2f, 0x2a,
|
||||
0x7d, 0x42, 0xa7, 0x01, 0x0a, 0x10, 0x63, 0x6f, 0x6d, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e,
|
||||
0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x42, 0x0f, 0x49, 0x64, 0x70, 0x53, 0x65, 0x72, 0x76, 0x69,
|
||||
0x63, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x30, 0x67, 0x69, 0x74, 0x68, 0x75,
|
||||
0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x75, 0x73, 0x65, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2f, 0x6d,
|
||||
0x65, 0x6d, 0x6f, 0x73, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x61,
|
||||
0x70, 0x69, 0x2f, 0x76, 0x32, 0x3b, 0x61, 0x70, 0x69, 0x76, 0x32, 0xa2, 0x02, 0x03, 0x4d, 0x41,
|
||||
0x58, 0xaa, 0x02, 0x0c, 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x41, 0x70, 0x69, 0x2e, 0x56, 0x32,
|
||||
0xca, 0x02, 0x0c, 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x5c, 0x41, 0x70, 0x69, 0x5c, 0x56, 0x32, 0xe2,
|
||||
0x02, 0x18, 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x5c, 0x41, 0x70, 0x69, 0x5c, 0x56, 0x32, 0x5c, 0x47,
|
||||
0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x0e, 0x4d, 0x65, 0x6d,
|
||||
0x6f, 0x73, 0x3a, 0x3a, 0x41, 0x70, 0x69, 0x3a, 0x3a, 0x56, 0x32, 0x62, 0x06, 0x70, 0x72, 0x6f,
|
||||
0x74, 0x6f, 0x33,
|
||||
0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e,
|
||||
0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x44, 0x65, 0x6c,
|
||||
0x65, 0x74, 0x65, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, 0x76, 0x69,
|
||||
0x64, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x31, 0xda, 0x41, 0x04,
|
||||
0x6e, 0x61, 0x6d, 0x65, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x24, 0x2a, 0x22, 0x2f, 0x61, 0x70, 0x69,
|
||||
0x2f, 0x76, 0x32, 0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69,
|
||||
0x74, 0x79, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x73, 0x2f, 0x2a, 0x7d, 0x42, 0xa7,
|
||||
0x01, 0x0a, 0x10, 0x63, 0x6f, 0x6d, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69,
|
||||
0x2e, 0x76, 0x32, 0x42, 0x0f, 0x49, 0x64, 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x50,
|
||||
0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x30, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63,
|
||||
0x6f, 0x6d, 0x2f, 0x75, 0x73, 0x65, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2f, 0x6d, 0x65, 0x6d, 0x6f,
|
||||
0x73, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x61, 0x70, 0x69, 0x2f,
|
||||
0x76, 0x32, 0x3b, 0x61, 0x70, 0x69, 0x76, 0x32, 0xa2, 0x02, 0x03, 0x4d, 0x41, 0x58, 0xaa, 0x02,
|
||||
0x0c, 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x41, 0x70, 0x69, 0x2e, 0x56, 0x32, 0xca, 0x02, 0x0c,
|
||||
0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x5c, 0x41, 0x70, 0x69, 0x5c, 0x56, 0x32, 0xe2, 0x02, 0x18, 0x4d,
|
||||
0x65, 0x6d, 0x6f, 0x73, 0x5c, 0x41, 0x70, 0x69, 0x5c, 0x56, 0x32, 0x5c, 0x47, 0x50, 0x42, 0x4d,
|
||||
0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x0e, 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x3a,
|
||||
0x3a, 0x41, 0x70, 0x69, 0x3a, 0x3a, 0x56, 0x32, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
@ -1062,7 +1062,7 @@ var file_api_v2_idp_service_proto_goTypes = []interface{}{
|
||||
var file_api_v2_idp_service_proto_depIdxs = []int32{
|
||||
0, // 0: memos.api.v2.IdentityProvider.type:type_name -> memos.api.v2.IdentityProvider.Type
|
||||
2, // 1: memos.api.v2.IdentityProvider.config:type_name -> memos.api.v2.IdentityProviderConfig
|
||||
4, // 2: memos.api.v2.IdentityProviderConfig.oauth2:type_name -> memos.api.v2.OAuth2Config
|
||||
4, // 2: memos.api.v2.IdentityProviderConfig.oauth2_config:type_name -> memos.api.v2.OAuth2Config
|
||||
3, // 3: memos.api.v2.OAuth2Config.field_mapping:type_name -> memos.api.v2.FieldMapping
|
||||
1, // 4: memos.api.v2.ListIdentityProvidersResponse.identity_providers:type_name -> memos.api.v2.IdentityProvider
|
||||
1, // 5: memos.api.v2.GetIdentityProviderResponse.identity_provider:type_name -> memos.api.v2.IdentityProvider
|
||||
@ -1264,7 +1264,7 @@ func file_api_v2_idp_service_proto_init() {
|
||||
}
|
||||
}
|
||||
file_api_v2_idp_service_proto_msgTypes[1].OneofWrappers = []interface{}{
|
||||
(*IdentityProviderConfig_Oauth2)(nil),
|
||||
(*IdentityProviderConfig_Oauth2Config)(nil),
|
||||
}
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
|
@ -144,10 +144,10 @@ type StorageConfig struct {
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
// Types that are assignable to StorageConfig:
|
||||
// Types that are assignable to Config:
|
||||
//
|
||||
// *StorageConfig_S3Config
|
||||
StorageConfig isStorageConfig_StorageConfig `protobuf_oneof:"storage_config"`
|
||||
Config isStorageConfig_Config `protobuf_oneof:"config"`
|
||||
}
|
||||
|
||||
func (x *StorageConfig) Reset() {
|
||||
@ -182,29 +182,29 @@ func (*StorageConfig) Descriptor() ([]byte, []int) {
|
||||
return file_api_v2_storage_service_proto_rawDescGZIP(), []int{1}
|
||||
}
|
||||
|
||||
func (m *StorageConfig) GetStorageConfig() isStorageConfig_StorageConfig {
|
||||
func (m *StorageConfig) GetConfig() isStorageConfig_Config {
|
||||
if m != nil {
|
||||
return m.StorageConfig
|
||||
return m.Config
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *StorageConfig) GetS3Config() *S3Config {
|
||||
if x, ok := x.GetStorageConfig().(*StorageConfig_S3Config); ok {
|
||||
if x, ok := x.GetConfig().(*StorageConfig_S3Config); ok {
|
||||
return x.S3Config
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type isStorageConfig_StorageConfig interface {
|
||||
isStorageConfig_StorageConfig()
|
||||
type isStorageConfig_Config interface {
|
||||
isStorageConfig_Config()
|
||||
}
|
||||
|
||||
type StorageConfig_S3Config struct {
|
||||
S3Config *S3Config `protobuf:"bytes,1,opt,name=s3_config,json=s3Config,proto3,oneof"`
|
||||
}
|
||||
|
||||
func (*StorageConfig_S3Config) isStorageConfig_StorageConfig() {}
|
||||
func (*StorageConfig_S3Config) isStorageConfig_Config() {}
|
||||
|
||||
type S3Config struct {
|
||||
state protoimpl.MessageState
|
||||
@ -800,120 +800,120 @@ var file_api_v2_storage_service_proto_rawDesc = []byte{
|
||||
0x6e, 0x66, 0x69, 0x67, 0x52, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x22, 0x24, 0x0a, 0x04,
|
||||
0x54, 0x79, 0x70, 0x65, 0x12, 0x14, 0x0a, 0x10, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x53,
|
||||
0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x06, 0x0a, 0x02, 0x53, 0x33,
|
||||
0x10, 0x01, 0x22, 0x58, 0x0a, 0x0d, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x43, 0x6f, 0x6e,
|
||||
0x10, 0x01, 0x22, 0x50, 0x0a, 0x0d, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x43, 0x6f, 0x6e,
|
||||
0x66, 0x69, 0x67, 0x12, 0x35, 0x0a, 0x09, 0x73, 0x33, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67,
|
||||
0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61,
|
||||
0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x33, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x48, 0x00,
|
||||
0x52, 0x08, 0x73, 0x33, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x42, 0x10, 0x0a, 0x0e, 0x73, 0x74,
|
||||
0x6f, 0x72, 0x61, 0x67, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x22, 0x82, 0x02, 0x0a,
|
||||
0x08, 0x53, 0x33, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x1b, 0x0a, 0x09, 0x65, 0x6e, 0x64,
|
||||
0x5f, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x65, 0x6e,
|
||||
0x64, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x02,
|
||||
0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65,
|
||||
0x67, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, 0x65, 0x67, 0x69,
|
||||
0x6f, 0x6e, 0x12, 0x1d, 0x0a, 0x0a, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x6b, 0x65, 0x79,
|
||||
0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4b, 0x65,
|
||||
0x79, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x5f, 0x6b, 0x65, 0x79, 0x18,
|
||||
0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x4b, 0x65, 0x79,
|
||||
0x12, 0x16, 0x0a, 0x06, 0x62, 0x75, 0x63, 0x6b, 0x65, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09,
|
||||
0x52, 0x06, 0x62, 0x75, 0x63, 0x6b, 0x65, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x75, 0x72, 0x6c, 0x5f,
|
||||
0x70, 0x72, 0x65, 0x66, 0x69, 0x78, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x75, 0x72,
|
||||
0x6c, 0x50, 0x72, 0x65, 0x66, 0x69, 0x78, 0x12, 0x1d, 0x0a, 0x0a, 0x75, 0x72, 0x6c, 0x5f, 0x73,
|
||||
0x75, 0x66, 0x66, 0x69, 0x78, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x75, 0x72, 0x6c,
|
||||
0x53, 0x75, 0x66, 0x66, 0x69, 0x78, 0x12, 0x19, 0x0a, 0x08, 0x70, 0x72, 0x65, 0x5f, 0x73, 0x69,
|
||||
0x67, 0x6e, 0x18, 0x09, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x70, 0x72, 0x65, 0x53, 0x69, 0x67,
|
||||
0x6e, 0x22, 0x47, 0x0a, 0x14, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x74, 0x6f, 0x72, 0x61,
|
||||
0x67, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2f, 0x0a, 0x07, 0x73, 0x74, 0x6f,
|
||||
0x72, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x6d, 0x65, 0x6d,
|
||||
0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67,
|
||||
0x65, 0x52, 0x07, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x22, 0x48, 0x0a, 0x15, 0x43, 0x72,
|
||||
0x65, 0x61, 0x74, 0x65, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f,
|
||||
0x6e, 0x73, 0x65, 0x12, 0x2f, 0x0a, 0x07, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x18, 0x01,
|
||||
0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69,
|
||||
0x2e, 0x76, 0x32, 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x52, 0x07, 0x73, 0x74, 0x6f,
|
||||
0x72, 0x61, 0x67, 0x65, 0x22, 0x23, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x53, 0x74, 0x6f, 0x72, 0x61,
|
||||
0x67, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18,
|
||||
0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x02, 0x69, 0x64, 0x22, 0x45, 0x0a, 0x12, 0x47, 0x65, 0x74,
|
||||
0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12,
|
||||
0x2f, 0x0a, 0x07, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b,
|
||||
0x32, 0x15, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e,
|
||||
0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x52, 0x07, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65,
|
||||
0x22, 0x15, 0x0a, 0x13, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x73,
|
||||
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x49, 0x0a, 0x14, 0x4c, 0x69, 0x73, 0x74, 0x53,
|
||||
0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12,
|
||||
0x31, 0x0a, 0x08, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28,
|
||||
0x0b, 0x32, 0x15, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32,
|
||||
0x2e, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x52, 0x08, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67,
|
||||
0x65, 0x73, 0x22, 0x84, 0x01, 0x0a, 0x14, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x74, 0x6f,
|
||||
0x72, 0x61, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2f, 0x0a, 0x07, 0x73,
|
||||
0x52, 0x08, 0x73, 0x33, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x42, 0x08, 0x0a, 0x06, 0x63, 0x6f,
|
||||
0x6e, 0x66, 0x69, 0x67, 0x22, 0x82, 0x02, 0x0a, 0x08, 0x53, 0x33, 0x43, 0x6f, 0x6e, 0x66, 0x69,
|
||||
0x67, 0x12, 0x1b, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x5f, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x18, 0x01,
|
||||
0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x65, 0x6e, 0x64, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x12,
|
||||
0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61,
|
||||
0x74, 0x68, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01,
|
||||
0x28, 0x09, 0x52, 0x06, 0x72, 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x12, 0x1d, 0x0a, 0x0a, 0x61, 0x63,
|
||||
0x63, 0x65, 0x73, 0x73, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09,
|
||||
0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4b, 0x65, 0x79, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x65, 0x63,
|
||||
0x72, 0x65, 0x74, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73,
|
||||
0x65, 0x63, 0x72, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x12, 0x16, 0x0a, 0x06, 0x62, 0x75, 0x63, 0x6b,
|
||||
0x65, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x62, 0x75, 0x63, 0x6b, 0x65, 0x74,
|
||||
0x12, 0x1d, 0x0a, 0x0a, 0x75, 0x72, 0x6c, 0x5f, 0x70, 0x72, 0x65, 0x66, 0x69, 0x78, 0x18, 0x07,
|
||||
0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x75, 0x72, 0x6c, 0x50, 0x72, 0x65, 0x66, 0x69, 0x78, 0x12,
|
||||
0x1d, 0x0a, 0x0a, 0x75, 0x72, 0x6c, 0x5f, 0x73, 0x75, 0x66, 0x66, 0x69, 0x78, 0x18, 0x08, 0x20,
|
||||
0x01, 0x28, 0x09, 0x52, 0x09, 0x75, 0x72, 0x6c, 0x53, 0x75, 0x66, 0x66, 0x69, 0x78, 0x12, 0x19,
|
||||
0x0a, 0x08, 0x70, 0x72, 0x65, 0x5f, 0x73, 0x69, 0x67, 0x6e, 0x18, 0x09, 0x20, 0x01, 0x28, 0x08,
|
||||
0x52, 0x07, 0x70, 0x72, 0x65, 0x53, 0x69, 0x67, 0x6e, 0x22, 0x47, 0x0a, 0x14, 0x43, 0x72, 0x65,
|
||||
0x61, 0x74, 0x65, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
|
||||
0x74, 0x12, 0x2f, 0x0a, 0x07, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01,
|
||||
0x28, 0x0b, 0x32, 0x15, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76,
|
||||
0x32, 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x52, 0x07, 0x73, 0x74, 0x6f, 0x72, 0x61,
|
||||
0x67, 0x65, 0x22, 0x48, 0x0a, 0x15, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x74, 0x6f, 0x72,
|
||||
0x61, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2f, 0x0a, 0x07, 0x73,
|
||||
0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x6d,
|
||||
0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x74, 0x6f, 0x72,
|
||||
0x61, 0x67, 0x65, 0x52, 0x07, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x12, 0x3b, 0x0a, 0x0b,
|
||||
0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x6d, 0x61, 0x73, 0x6b, 0x18, 0x02, 0x20, 0x01, 0x28,
|
||||
0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
|
||||
0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x4d, 0x61, 0x73, 0x6b, 0x52, 0x0a, 0x75,
|
||||
0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x61, 0x73, 0x6b, 0x22, 0x48, 0x0a, 0x15, 0x55, 0x70, 0x64,
|
||||
0x61, 0x74, 0x65, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
|
||||
0x73, 0x65, 0x12, 0x2f, 0x0a, 0x07, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20,
|
||||
0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e,
|
||||
0x76, 0x32, 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x52, 0x07, 0x73, 0x74, 0x6f, 0x72,
|
||||
0x61, 0x67, 0x65, 0x22, 0x26, 0x0a, 0x14, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x53, 0x74, 0x6f,
|
||||
0x72, 0x61, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69,
|
||||
0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x02, 0x69, 0x64, 0x22, 0x17, 0x0a, 0x15, 0x44,
|
||||
0x65, 0x6c, 0x65, 0x74, 0x65, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70,
|
||||
0x6f, 0x6e, 0x73, 0x65, 0x32, 0x8c, 0x05, 0x0a, 0x0e, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65,
|
||||
0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x75, 0x0a, 0x0d, 0x43, 0x72, 0x65, 0x61, 0x74,
|
||||
0x65, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x12, 0x22, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73,
|
||||
0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x74,
|
||||
0x6f, 0x72, 0x61, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x6d,
|
||||
0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x43, 0x72, 0x65, 0x61,
|
||||
0x74, 0x65, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
|
||||
0x65, 0x22, 0x1b, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x15, 0x3a, 0x01, 0x2a, 0x22, 0x10, 0x2f, 0x61,
|
||||
0x70, 0x69, 0x2f, 0x76, 0x32, 0x2f, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x73, 0x12, 0x73,
|
||||
0x0a, 0x0a, 0x47, 0x65, 0x74, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x12, 0x1f, 0x2e, 0x6d,
|
||||
0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x47, 0x65, 0x74, 0x53,
|
||||
0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e,
|
||||
0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x47, 0x65, 0x74,
|
||||
0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22,
|
||||
0x22, 0xda, 0x41, 0x02, 0x69, 0x64, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x17, 0x12, 0x15, 0x2f, 0x61,
|
||||
0x70, 0x69, 0x2f, 0x76, 0x32, 0x2f, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x73, 0x2f, 0x7b,
|
||||
0x69, 0x64, 0x7d, 0x12, 0x6f, 0x0a, 0x0c, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x74, 0x6f, 0x72, 0x61,
|
||||
0x67, 0x65, 0x73, 0x12, 0x21, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e,
|
||||
0x76, 0x32, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x73, 0x52,
|
||||
0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61,
|
||||
0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67,
|
||||
0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x18, 0x82, 0xd3, 0xe4, 0x93,
|
||||
0x02, 0x12, 0x12, 0x10, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32, 0x2f, 0x73, 0x74, 0x6f, 0x72,
|
||||
0x61, 0x67, 0x65, 0x73, 0x12, 0x9e, 0x01, 0x0a, 0x0d, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53,
|
||||
0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x12, 0x22, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61,
|
||||
0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x74, 0x6f, 0x72,
|
||||
0x61, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x6d, 0x65, 0x6d,
|
||||
0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65,
|
||||
0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22,
|
||||
0x44, 0xda, 0x41, 0x13, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2c, 0x75, 0x70, 0x64, 0x61,
|
||||
0x74, 0x65, 0x5f, 0x6d, 0x61, 0x73, 0x6b, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x28, 0x3a, 0x07, 0x73,
|
||||
0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x32, 0x1d, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32, 0x2f,
|
||||
0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x73, 0x2f, 0x7b, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67,
|
||||
0x65, 0x2e, 0x69, 0x64, 0x7d, 0x12, 0x7c, 0x0a, 0x0d, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x53,
|
||||
0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x12, 0x22, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61,
|
||||
0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x53, 0x74, 0x6f, 0x72,
|
||||
0x61, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x6d, 0x65, 0x6d,
|
||||
0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65,
|
||||
0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22,
|
||||
0x22, 0xda, 0x41, 0x02, 0x69, 0x64, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x17, 0x2a, 0x15, 0x2f, 0x61,
|
||||
0x70, 0x69, 0x2f, 0x76, 0x32, 0x2f, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x73, 0x2f, 0x7b,
|
||||
0x69, 0x64, 0x7d, 0x42, 0xab, 0x01, 0x0a, 0x10, 0x63, 0x6f, 0x6d, 0x2e, 0x6d, 0x65, 0x6d, 0x6f,
|
||||
0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x42, 0x13, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67,
|
||||
0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a,
|
||||
0x30, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x75, 0x73, 0x65, 0x6d,
|
||||
0x65, 0x6d, 0x6f, 0x73, 0x2f, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f,
|
||||
0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32, 0x3b, 0x61, 0x70, 0x69, 0x76,
|
||||
0x32, 0xa2, 0x02, 0x03, 0x4d, 0x41, 0x58, 0xaa, 0x02, 0x0c, 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x2e,
|
||||
0x41, 0x70, 0x69, 0x2e, 0x56, 0x32, 0xca, 0x02, 0x0c, 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x5c, 0x41,
|
||||
0x70, 0x69, 0x5c, 0x56, 0x32, 0xe2, 0x02, 0x18, 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x5c, 0x41, 0x70,
|
||||
0x69, 0x5c, 0x56, 0x32, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61,
|
||||
0xea, 0x02, 0x0e, 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x3a, 0x3a, 0x41, 0x70, 0x69, 0x3a, 0x3a, 0x56,
|
||||
0x32, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
0x61, 0x67, 0x65, 0x52, 0x07, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x22, 0x23, 0x0a, 0x11,
|
||||
0x47, 0x65, 0x74, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
|
||||
0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x02, 0x69,
|
||||
0x64, 0x22, 0x45, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x52,
|
||||
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2f, 0x0a, 0x07, 0x73, 0x74, 0x6f, 0x72, 0x61,
|
||||
0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73,
|
||||
0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x52,
|
||||
0x07, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x22, 0x15, 0x0a, 0x13, 0x4c, 0x69, 0x73, 0x74,
|
||||
0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22,
|
||||
0x49, 0x0a, 0x14, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x73, 0x52,
|
||||
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x31, 0x0a, 0x08, 0x73, 0x74, 0x6f, 0x72, 0x61,
|
||||
0x67, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x6d, 0x65, 0x6d, 0x6f,
|
||||
0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65,
|
||||
0x52, 0x08, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x73, 0x22, 0x84, 0x01, 0x0a, 0x14, 0x55,
|
||||
0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75,
|
||||
0x65, 0x73, 0x74, 0x12, 0x2f, 0x0a, 0x07, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x18, 0x01,
|
||||
0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69,
|
||||
0x2e, 0x76, 0x32, 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x52, 0x07, 0x73, 0x74, 0x6f,
|
||||
0x72, 0x61, 0x67, 0x65, 0x12, 0x3b, 0x0a, 0x0b, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x6d,
|
||||
0x61, 0x73, 0x6b, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67,
|
||||
0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x65, 0x6c,
|
||||
0x64, 0x4d, 0x61, 0x73, 0x6b, 0x52, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x61, 0x73,
|
||||
0x6b, 0x22, 0x48, 0x0a, 0x15, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x74, 0x6f, 0x72, 0x61,
|
||||
0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2f, 0x0a, 0x07, 0x73, 0x74,
|
||||
0x6f, 0x72, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x6d, 0x65,
|
||||
0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x61,
|
||||
0x67, 0x65, 0x52, 0x07, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x22, 0x26, 0x0a, 0x14, 0x44,
|
||||
0x65, 0x6c, 0x65, 0x74, 0x65, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75,
|
||||
0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52,
|
||||
0x02, 0x69, 0x64, 0x22, 0x17, 0x0a, 0x15, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x53, 0x74, 0x6f,
|
||||
0x72, 0x61, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, 0x8c, 0x05, 0x0a,
|
||||
0x0e, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12,
|
||||
0x75, 0x0a, 0x0d, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65,
|
||||
0x12, 0x22, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e,
|
||||
0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x52, 0x65, 0x71,
|
||||
0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69,
|
||||
0x2e, 0x76, 0x32, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67,
|
||||
0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1b, 0x82, 0xd3, 0xe4, 0x93, 0x02,
|
||||
0x15, 0x3a, 0x01, 0x2a, 0x22, 0x10, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32, 0x2f, 0x73, 0x74,
|
||||
0x6f, 0x72, 0x61, 0x67, 0x65, 0x73, 0x12, 0x73, 0x0a, 0x0a, 0x47, 0x65, 0x74, 0x53, 0x74, 0x6f,
|
||||
0x72, 0x61, 0x67, 0x65, 0x12, 0x1f, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69,
|
||||
0x2e, 0x76, 0x32, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x52, 0x65,
|
||||
0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70,
|
||||
0x69, 0x2e, 0x76, 0x32, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x52,
|
||||
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x22, 0xda, 0x41, 0x02, 0x69, 0x64, 0x82, 0xd3,
|
||||
0xe4, 0x93, 0x02, 0x17, 0x12, 0x15, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32, 0x2f, 0x73, 0x74,
|
||||
0x6f, 0x72, 0x61, 0x67, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x12, 0x6f, 0x0a, 0x0c, 0x4c,
|
||||
0x69, 0x73, 0x74, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x73, 0x12, 0x21, 0x2e, 0x6d, 0x65,
|
||||
0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x53,
|
||||
0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22,
|
||||
0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x4c, 0x69,
|
||||
0x73, 0x74, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
|
||||
0x73, 0x65, 0x22, 0x18, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x12, 0x12, 0x10, 0x2f, 0x61, 0x70, 0x69,
|
||||
0x2f, 0x76, 0x32, 0x2f, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x73, 0x12, 0x9e, 0x01, 0x0a,
|
||||
0x0d, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x12, 0x22,
|
||||
0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x55, 0x70,
|
||||
0x64, 0x61, 0x74, 0x65, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65,
|
||||
0x73, 0x74, 0x1a, 0x23, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76,
|
||||
0x32, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x52,
|
||||
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x44, 0xda, 0x41, 0x13, 0x73, 0x74, 0x6f, 0x72,
|
||||
0x61, 0x67, 0x65, 0x2c, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x6d, 0x61, 0x73, 0x6b, 0x82,
|
||||
0xd3, 0xe4, 0x93, 0x02, 0x28, 0x3a, 0x07, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x32, 0x1d,
|
||||
0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32, 0x2f, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x73,
|
||||
0x2f, 0x7b, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, 0x69, 0x64, 0x7d, 0x12, 0x7c, 0x0a,
|
||||
0x0d, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x12, 0x22,
|
||||
0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x44, 0x65,
|
||||
0x6c, 0x65, 0x74, 0x65, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65,
|
||||
0x73, 0x74, 0x1a, 0x23, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76,
|
||||
0x32, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x52,
|
||||
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x22, 0xda, 0x41, 0x02, 0x69, 0x64, 0x82, 0xd3,
|
||||
0xe4, 0x93, 0x02, 0x17, 0x2a, 0x15, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32, 0x2f, 0x73, 0x74,
|
||||
0x6f, 0x72, 0x61, 0x67, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x42, 0xab, 0x01, 0x0a, 0x10,
|
||||
0x63, 0x6f, 0x6d, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32,
|
||||
0x42, 0x13, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65,
|
||||
0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x30, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e,
|
||||
0x63, 0x6f, 0x6d, 0x2f, 0x75, 0x73, 0x65, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2f, 0x6d, 0x65, 0x6d,
|
||||
0x6f, 0x73, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x61, 0x70, 0x69,
|
||||
0x2f, 0x76, 0x32, 0x3b, 0x61, 0x70, 0x69, 0x76, 0x32, 0xa2, 0x02, 0x03, 0x4d, 0x41, 0x58, 0xaa,
|
||||
0x02, 0x0c, 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x41, 0x70, 0x69, 0x2e, 0x56, 0x32, 0xca, 0x02,
|
||||
0x0c, 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x5c, 0x41, 0x70, 0x69, 0x5c, 0x56, 0x32, 0xe2, 0x02, 0x18,
|
||||
0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x5c, 0x41, 0x70, 0x69, 0x5c, 0x56, 0x32, 0x5c, 0x47, 0x50, 0x42,
|
||||
0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x0e, 0x4d, 0x65, 0x6d, 0x6f, 0x73,
|
||||
0x3a, 0x3a, 0x41, 0x70, 0x69, 0x3a, 0x3a, 0x56, 0x32, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f,
|
||||
0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
|
@ -13,9 +13,12 @@
|
||||
|
||||
- [store/idp.proto](#store_idp-proto)
|
||||
- [FieldMapping](#memos-store-FieldMapping)
|
||||
- [IdentityProvider](#memos-store-IdentityProvider)
|
||||
- [IdentityProviderConfig](#memos-store-IdentityProviderConfig)
|
||||
- [OAuth2Config](#memos-store-OAuth2Config)
|
||||
|
||||
- [IdentityProvider.Type](#memos-store-IdentityProvider-Type)
|
||||
|
||||
- [store/inbox.proto](#store_inbox-proto)
|
||||
- [InboxMessage](#memos-store-InboxMessage)
|
||||
|
||||
@ -175,6 +178,25 @@
|
||||
|
||||
|
||||
|
||||
<a name="memos-store-IdentityProvider"></a>
|
||||
|
||||
### IdentityProvider
|
||||
|
||||
|
||||
|
||||
| Field | Type | Label | Description |
|
||||
| ----- | ---- | ----- | ----------- |
|
||||
| id | [int32](#int32) | | |
|
||||
| name | [string](#string) | | |
|
||||
| type | [IdentityProvider.Type](#memos-store-IdentityProvider-Type) | | |
|
||||
| identifier_filter | [string](#string) | | |
|
||||
| config | [IdentityProviderConfig](#memos-store-IdentityProviderConfig) | | |
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<a name="memos-store-IdentityProviderConfig"></a>
|
||||
|
||||
### IdentityProviderConfig
|
||||
@ -183,7 +205,7 @@
|
||||
|
||||
| Field | Type | Label | Description |
|
||||
| ----- | ---- | ----- | ----------- |
|
||||
| oauth2 | [OAuth2Config](#memos-store-OAuth2Config) | | |
|
||||
| oauth2_config | [OAuth2Config](#memos-store-OAuth2Config) | | |
|
||||
|
||||
|
||||
|
||||
@ -213,6 +235,18 @@
|
||||
|
||||
|
||||
|
||||
<a name="memos-store-IdentityProvider-Type"></a>
|
||||
|
||||
### IdentityProvider.Type
|
||||
|
||||
|
||||
| Name | Number | Description |
|
||||
| ---- | ------ | ----------- |
|
||||
| TYPE_UNSPECIFIED | 0 | |
|
||||
| OAUTH2 | 1 | |
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -20,6 +20,131 @@ const (
|
||||
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
|
||||
)
|
||||
|
||||
type IdentityProvider_Type int32
|
||||
|
||||
const (
|
||||
IdentityProvider_TYPE_UNSPECIFIED IdentityProvider_Type = 0
|
||||
IdentityProvider_OAUTH2 IdentityProvider_Type = 1
|
||||
)
|
||||
|
||||
// Enum value maps for IdentityProvider_Type.
|
||||
var (
|
||||
IdentityProvider_Type_name = map[int32]string{
|
||||
0: "TYPE_UNSPECIFIED",
|
||||
1: "OAUTH2",
|
||||
}
|
||||
IdentityProvider_Type_value = map[string]int32{
|
||||
"TYPE_UNSPECIFIED": 0,
|
||||
"OAUTH2": 1,
|
||||
}
|
||||
)
|
||||
|
||||
func (x IdentityProvider_Type) Enum() *IdentityProvider_Type {
|
||||
p := new(IdentityProvider_Type)
|
||||
*p = x
|
||||
return p
|
||||
}
|
||||
|
||||
func (x IdentityProvider_Type) String() string {
|
||||
return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
|
||||
}
|
||||
|
||||
func (IdentityProvider_Type) Descriptor() protoreflect.EnumDescriptor {
|
||||
return file_store_idp_proto_enumTypes[0].Descriptor()
|
||||
}
|
||||
|
||||
func (IdentityProvider_Type) Type() protoreflect.EnumType {
|
||||
return &file_store_idp_proto_enumTypes[0]
|
||||
}
|
||||
|
||||
func (x IdentityProvider_Type) Number() protoreflect.EnumNumber {
|
||||
return protoreflect.EnumNumber(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use IdentityProvider_Type.Descriptor instead.
|
||||
func (IdentityProvider_Type) EnumDescriptor() ([]byte, []int) {
|
||||
return file_store_idp_proto_rawDescGZIP(), []int{0, 0}
|
||||
}
|
||||
|
||||
type IdentityProvider struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Id int32 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"`
|
||||
Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`
|
||||
Type IdentityProvider_Type `protobuf:"varint,3,opt,name=type,proto3,enum=memos.store.IdentityProvider_Type" json:"type,omitempty"`
|
||||
IdentifierFilter string `protobuf:"bytes,4,opt,name=identifier_filter,json=identifierFilter,proto3" json:"identifier_filter,omitempty"`
|
||||
Config *IdentityProviderConfig `protobuf:"bytes,5,opt,name=config,proto3" json:"config,omitempty"`
|
||||
}
|
||||
|
||||
func (x *IdentityProvider) Reset() {
|
||||
*x = IdentityProvider{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_store_idp_proto_msgTypes[0]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *IdentityProvider) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*IdentityProvider) ProtoMessage() {}
|
||||
|
||||
func (x *IdentityProvider) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_store_idp_proto_msgTypes[0]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use IdentityProvider.ProtoReflect.Descriptor instead.
|
||||
func (*IdentityProvider) Descriptor() ([]byte, []int) {
|
||||
return file_store_idp_proto_rawDescGZIP(), []int{0}
|
||||
}
|
||||
|
||||
func (x *IdentityProvider) GetId() int32 {
|
||||
if x != nil {
|
||||
return x.Id
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *IdentityProvider) GetName() string {
|
||||
if x != nil {
|
||||
return x.Name
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *IdentityProvider) GetType() IdentityProvider_Type {
|
||||
if x != nil {
|
||||
return x.Type
|
||||
}
|
||||
return IdentityProvider_TYPE_UNSPECIFIED
|
||||
}
|
||||
|
||||
func (x *IdentityProvider) GetIdentifierFilter() string {
|
||||
if x != nil {
|
||||
return x.IdentifierFilter
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *IdentityProvider) GetConfig() *IdentityProviderConfig {
|
||||
if x != nil {
|
||||
return x.Config
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type IdentityProviderConfig struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
@ -27,14 +152,14 @@ type IdentityProviderConfig struct {
|
||||
|
||||
// Types that are assignable to Config:
|
||||
//
|
||||
// *IdentityProviderConfig_Oauth2
|
||||
// *IdentityProviderConfig_Oauth2Config
|
||||
Config isIdentityProviderConfig_Config `protobuf_oneof:"config"`
|
||||
}
|
||||
|
||||
func (x *IdentityProviderConfig) Reset() {
|
||||
*x = IdentityProviderConfig{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_store_idp_proto_msgTypes[0]
|
||||
mi := &file_store_idp_proto_msgTypes[1]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@ -47,7 +172,7 @@ func (x *IdentityProviderConfig) String() string {
|
||||
func (*IdentityProviderConfig) ProtoMessage() {}
|
||||
|
||||
func (x *IdentityProviderConfig) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_store_idp_proto_msgTypes[0]
|
||||
mi := &file_store_idp_proto_msgTypes[1]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@ -60,7 +185,7 @@ func (x *IdentityProviderConfig) ProtoReflect() protoreflect.Message {
|
||||
|
||||
// Deprecated: Use IdentityProviderConfig.ProtoReflect.Descriptor instead.
|
||||
func (*IdentityProviderConfig) Descriptor() ([]byte, []int) {
|
||||
return file_store_idp_proto_rawDescGZIP(), []int{0}
|
||||
return file_store_idp_proto_rawDescGZIP(), []int{1}
|
||||
}
|
||||
|
||||
func (m *IdentityProviderConfig) GetConfig() isIdentityProviderConfig_Config {
|
||||
@ -70,9 +195,9 @@ func (m *IdentityProviderConfig) GetConfig() isIdentityProviderConfig_Config {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *IdentityProviderConfig) GetOauth2() *OAuth2Config {
|
||||
if x, ok := x.GetConfig().(*IdentityProviderConfig_Oauth2); ok {
|
||||
return x.Oauth2
|
||||
func (x *IdentityProviderConfig) GetOauth2Config() *OAuth2Config {
|
||||
if x, ok := x.GetConfig().(*IdentityProviderConfig_Oauth2Config); ok {
|
||||
return x.Oauth2Config
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@ -81,11 +206,11 @@ type isIdentityProviderConfig_Config interface {
|
||||
isIdentityProviderConfig_Config()
|
||||
}
|
||||
|
||||
type IdentityProviderConfig_Oauth2 struct {
|
||||
Oauth2 *OAuth2Config `protobuf:"bytes,1,opt,name=oauth2,proto3,oneof"`
|
||||
type IdentityProviderConfig_Oauth2Config struct {
|
||||
Oauth2Config *OAuth2Config `protobuf:"bytes,1,opt,name=oauth2_config,json=oauth2Config,proto3,oneof"`
|
||||
}
|
||||
|
||||
func (*IdentityProviderConfig_Oauth2) isIdentityProviderConfig_Config() {}
|
||||
func (*IdentityProviderConfig_Oauth2Config) isIdentityProviderConfig_Config() {}
|
||||
|
||||
type FieldMapping struct {
|
||||
state protoimpl.MessageState
|
||||
@ -100,7 +225,7 @@ type FieldMapping struct {
|
||||
func (x *FieldMapping) Reset() {
|
||||
*x = FieldMapping{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_store_idp_proto_msgTypes[1]
|
||||
mi := &file_store_idp_proto_msgTypes[2]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@ -113,7 +238,7 @@ func (x *FieldMapping) String() string {
|
||||
func (*FieldMapping) ProtoMessage() {}
|
||||
|
||||
func (x *FieldMapping) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_store_idp_proto_msgTypes[1]
|
||||
mi := &file_store_idp_proto_msgTypes[2]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@ -126,7 +251,7 @@ func (x *FieldMapping) ProtoReflect() protoreflect.Message {
|
||||
|
||||
// Deprecated: Use FieldMapping.ProtoReflect.Descriptor instead.
|
||||
func (*FieldMapping) Descriptor() ([]byte, []int) {
|
||||
return file_store_idp_proto_rawDescGZIP(), []int{1}
|
||||
return file_store_idp_proto_rawDescGZIP(), []int{2}
|
||||
}
|
||||
|
||||
func (x *FieldMapping) GetIdentifier() string {
|
||||
@ -167,7 +292,7 @@ type OAuth2Config struct {
|
||||
func (x *OAuth2Config) Reset() {
|
||||
*x = OAuth2Config{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_store_idp_proto_msgTypes[2]
|
||||
mi := &file_store_idp_proto_msgTypes[3]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@ -180,7 +305,7 @@ func (x *OAuth2Config) String() string {
|
||||
func (*OAuth2Config) ProtoMessage() {}
|
||||
|
||||
func (x *OAuth2Config) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_store_idp_proto_msgTypes[2]
|
||||
mi := &file_store_idp_proto_msgTypes[3]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@ -193,7 +318,7 @@ func (x *OAuth2Config) ProtoReflect() protoreflect.Message {
|
||||
|
||||
// Deprecated: Use OAuth2Config.ProtoReflect.Descriptor instead.
|
||||
func (*OAuth2Config) Descriptor() ([]byte, []int) {
|
||||
return file_store_idp_proto_rawDescGZIP(), []int{2}
|
||||
return file_store_idp_proto_rawDescGZIP(), []int{3}
|
||||
}
|
||||
|
||||
func (x *OAuth2Config) GetClientId() string {
|
||||
@ -249,46 +374,63 @@ var File_store_idp_proto protoreflect.FileDescriptor
|
||||
|
||||
var file_store_idp_proto_rawDesc = []byte{
|
||||
0x0a, 0x0f, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x2f, 0x69, 0x64, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74,
|
||||
0x6f, 0x12, 0x0b, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x22, 0x57,
|
||||
0x0a, 0x16, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64,
|
||||
0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x33, 0x0a, 0x06, 0x6f, 0x61, 0x75, 0x74,
|
||||
0x68, 0x32, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73,
|
||||
0x2e, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x2e, 0x4f, 0x41, 0x75, 0x74, 0x68, 0x32, 0x43, 0x6f, 0x6e,
|
||||
0x66, 0x69, 0x67, 0x48, 0x00, 0x52, 0x06, 0x6f, 0x61, 0x75, 0x74, 0x68, 0x32, 0x42, 0x08, 0x0a,
|
||||
0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x22, 0x67, 0x0a, 0x0c, 0x46, 0x69, 0x65, 0x6c, 0x64,
|
||||
0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x12, 0x1e, 0x0a, 0x0a, 0x69, 0x64, 0x65, 0x6e, 0x74,
|
||||
0x69, 0x66, 0x69, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x69, 0x64, 0x65,
|
||||
0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x12, 0x21, 0x0a, 0x0c, 0x64, 0x69, 0x73, 0x70, 0x6c,
|
||||
0x61, 0x79, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64,
|
||||
0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x6d,
|
||||
0x61, 0x69, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c,
|
||||
0x22, 0x84, 0x02, 0x0a, 0x0c, 0x4f, 0x41, 0x75, 0x74, 0x68, 0x32, 0x43, 0x6f, 0x6e, 0x66, 0x69,
|
||||
0x67, 0x12, 0x1b, 0x0a, 0x09, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01,
|
||||
0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x23,
|
||||
0x0a, 0x0d, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x18,
|
||||
0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x53, 0x65, 0x63,
|
||||
0x72, 0x65, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x61, 0x75, 0x74, 0x68, 0x5f, 0x75, 0x72, 0x6c, 0x18,
|
||||
0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x75, 0x74, 0x68, 0x55, 0x72, 0x6c, 0x12, 0x1b,
|
||||
0x0a, 0x09, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28,
|
||||
0x09, 0x52, 0x08, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x55, 0x72, 0x6c, 0x12, 0x22, 0x0a, 0x0d, 0x75,
|
||||
0x73, 0x65, 0x72, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x05, 0x20, 0x01,
|
||||
0x28, 0x09, 0x52, 0x0b, 0x75, 0x73, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x55, 0x72, 0x6c, 0x12,
|
||||
0x16, 0x0a, 0x06, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x09, 0x52,
|
||||
0x06, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x73, 0x12, 0x3e, 0x0a, 0x0d, 0x66, 0x69, 0x65, 0x6c, 0x64,
|
||||
0x5f, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19,
|
||||
0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x2e, 0x46, 0x69, 0x65,
|
||||
0x6c, 0x64, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x52, 0x0c, 0x66, 0x69, 0x65, 0x6c, 0x64,
|
||||
0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x42, 0x93, 0x01, 0x0a, 0x0f, 0x63, 0x6f, 0x6d, 0x2e,
|
||||
0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x42, 0x08, 0x49, 0x64, 0x70,
|
||||
0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x29, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e,
|
||||
0x63, 0x6f, 0x6d, 0x2f, 0x75, 0x73, 0x65, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2f, 0x6d, 0x65, 0x6d,
|
||||
0x6f, 0x73, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x73, 0x74, 0x6f,
|
||||
0x72, 0x65, 0xa2, 0x02, 0x03, 0x4d, 0x53, 0x58, 0xaa, 0x02, 0x0b, 0x4d, 0x65, 0x6d, 0x6f, 0x73,
|
||||
0x2e, 0x53, 0x74, 0x6f, 0x72, 0x65, 0xca, 0x02, 0x0b, 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x5c, 0x53,
|
||||
0x74, 0x6f, 0x72, 0x65, 0xe2, 0x02, 0x17, 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x5c, 0x53, 0x74, 0x6f,
|
||||
0x72, 0x65, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02,
|
||||
0x0c, 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x3a, 0x3a, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x62, 0x06, 0x70,
|
||||
0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
0x6f, 0x12, 0x0b, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x22, 0x82,
|
||||
0x02, 0x0a, 0x10, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, 0x76, 0x69,
|
||||
0x64, 0x65, 0x72, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52,
|
||||
0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28,
|
||||
0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x36, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18,
|
||||
0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x22, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x73, 0x74,
|
||||
0x6f, 0x72, 0x65, 0x2e, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, 0x76,
|
||||
0x69, 0x64, 0x65, 0x72, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12,
|
||||
0x2b, 0x0a, 0x11, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x5f, 0x66, 0x69,
|
||||
0x6c, 0x74, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x69, 0x64, 0x65, 0x6e,
|
||||
0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x3b, 0x0a, 0x06,
|
||||
0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x6d,
|
||||
0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x2e, 0x49, 0x64, 0x65, 0x6e, 0x74,
|
||||
0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69,
|
||||
0x67, 0x52, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x22, 0x28, 0x0a, 0x04, 0x54, 0x79, 0x70,
|
||||
0x65, 0x12, 0x14, 0x0a, 0x10, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43,
|
||||
0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x4f, 0x41, 0x55, 0x54, 0x48,
|
||||
0x32, 0x10, 0x01, 0x22, 0x64, 0x0a, 0x16, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x50,
|
||||
0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x40, 0x0a,
|
||||
0x0d, 0x6f, 0x61, 0x75, 0x74, 0x68, 0x32, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x01,
|
||||
0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x73, 0x74, 0x6f,
|
||||
0x72, 0x65, 0x2e, 0x4f, 0x41, 0x75, 0x74, 0x68, 0x32, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x48,
|
||||
0x00, 0x52, 0x0c, 0x6f, 0x61, 0x75, 0x74, 0x68, 0x32, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x42,
|
||||
0x08, 0x0a, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x22, 0x67, 0x0a, 0x0c, 0x46, 0x69, 0x65,
|
||||
0x6c, 0x64, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x12, 0x1e, 0x0a, 0x0a, 0x69, 0x64, 0x65,
|
||||
0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x69,
|
||||
0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x12, 0x21, 0x0a, 0x0c, 0x64, 0x69, 0x73,
|
||||
0x70, 0x6c, 0x61, 0x79, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52,
|
||||
0x0b, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05,
|
||||
0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x6d, 0x61,
|
||||
0x69, 0x6c, 0x22, 0x84, 0x02, 0x0a, 0x0c, 0x4f, 0x41, 0x75, 0x74, 0x68, 0x32, 0x43, 0x6f, 0x6e,
|
||||
0x66, 0x69, 0x67, 0x12, 0x1b, 0x0a, 0x09, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64,
|
||||
0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x64,
|
||||
0x12, 0x23, 0x0a, 0x0d, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x73, 0x65, 0x63, 0x72, 0x65,
|
||||
0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x53,
|
||||
0x65, 0x63, 0x72, 0x65, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x61, 0x75, 0x74, 0x68, 0x5f, 0x75, 0x72,
|
||||
0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x75, 0x74, 0x68, 0x55, 0x72, 0x6c,
|
||||
0x12, 0x1b, 0x0a, 0x09, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x04, 0x20,
|
||||
0x01, 0x28, 0x09, 0x52, 0x08, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x55, 0x72, 0x6c, 0x12, 0x22, 0x0a,
|
||||
0x0d, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x05,
|
||||
0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x75, 0x73, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x55, 0x72,
|
||||
0x6c, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28,
|
||||
0x09, 0x52, 0x06, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x73, 0x12, 0x3e, 0x0a, 0x0d, 0x66, 0x69, 0x65,
|
||||
0x6c, 0x64, 0x5f, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b,
|
||||
0x32, 0x19, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x2e, 0x46,
|
||||
0x69, 0x65, 0x6c, 0x64, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x52, 0x0c, 0x66, 0x69, 0x65,
|
||||
0x6c, 0x64, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x42, 0x93, 0x01, 0x0a, 0x0f, 0x63, 0x6f,
|
||||
0x6d, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x42, 0x08, 0x49,
|
||||
0x64, 0x70, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x29, 0x67, 0x69, 0x74, 0x68, 0x75,
|
||||
0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x75, 0x73, 0x65, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2f, 0x6d,
|
||||
0x65, 0x6d, 0x6f, 0x73, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x73,
|
||||
0x74, 0x6f, 0x72, 0x65, 0xa2, 0x02, 0x03, 0x4d, 0x53, 0x58, 0xaa, 0x02, 0x0b, 0x4d, 0x65, 0x6d,
|
||||
0x6f, 0x73, 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x65, 0xca, 0x02, 0x0b, 0x4d, 0x65, 0x6d, 0x6f, 0x73,
|
||||
0x5c, 0x53, 0x74, 0x6f, 0x72, 0x65, 0xe2, 0x02, 0x17, 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x5c, 0x53,
|
||||
0x74, 0x6f, 0x72, 0x65, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61,
|
||||
0xea, 0x02, 0x0c, 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x3a, 0x3a, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x62,
|
||||
0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
@ -303,20 +445,25 @@ func file_store_idp_proto_rawDescGZIP() []byte {
|
||||
return file_store_idp_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_store_idp_proto_msgTypes = make([]protoimpl.MessageInfo, 3)
|
||||
var file_store_idp_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
|
||||
var file_store_idp_proto_msgTypes = make([]protoimpl.MessageInfo, 4)
|
||||
var file_store_idp_proto_goTypes = []interface{}{
|
||||
(*IdentityProviderConfig)(nil), // 0: memos.store.IdentityProviderConfig
|
||||
(*FieldMapping)(nil), // 1: memos.store.FieldMapping
|
||||
(*OAuth2Config)(nil), // 2: memos.store.OAuth2Config
|
||||
(IdentityProvider_Type)(0), // 0: memos.store.IdentityProvider.Type
|
||||
(*IdentityProvider)(nil), // 1: memos.store.IdentityProvider
|
||||
(*IdentityProviderConfig)(nil), // 2: memos.store.IdentityProviderConfig
|
||||
(*FieldMapping)(nil), // 3: memos.store.FieldMapping
|
||||
(*OAuth2Config)(nil), // 4: memos.store.OAuth2Config
|
||||
}
|
||||
var file_store_idp_proto_depIdxs = []int32{
|
||||
2, // 0: memos.store.IdentityProviderConfig.oauth2:type_name -> memos.store.OAuth2Config
|
||||
1, // 1: memos.store.OAuth2Config.field_mapping:type_name -> memos.store.FieldMapping
|
||||
2, // [2:2] is the sub-list for method output_type
|
||||
2, // [2:2] is the sub-list for method input_type
|
||||
2, // [2:2] is the sub-list for extension type_name
|
||||
2, // [2:2] is the sub-list for extension extendee
|
||||
0, // [0:2] is the sub-list for field type_name
|
||||
0, // 0: memos.store.IdentityProvider.type:type_name -> memos.store.IdentityProvider.Type
|
||||
2, // 1: memos.store.IdentityProvider.config:type_name -> memos.store.IdentityProviderConfig
|
||||
4, // 2: memos.store.IdentityProviderConfig.oauth2_config:type_name -> memos.store.OAuth2Config
|
||||
3, // 3: memos.store.OAuth2Config.field_mapping:type_name -> memos.store.FieldMapping
|
||||
4, // [4:4] is the sub-list for method output_type
|
||||
4, // [4:4] is the sub-list for method input_type
|
||||
4, // [4:4] is the sub-list for extension type_name
|
||||
4, // [4:4] is the sub-list for extension extendee
|
||||
0, // [0:4] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_store_idp_proto_init() }
|
||||
@ -326,7 +473,7 @@ func file_store_idp_proto_init() {
|
||||
}
|
||||
if !protoimpl.UnsafeEnabled {
|
||||
file_store_idp_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*IdentityProviderConfig); i {
|
||||
switch v := v.(*IdentityProvider); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
@ -338,7 +485,7 @@ func file_store_idp_proto_init() {
|
||||
}
|
||||
}
|
||||
file_store_idp_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*FieldMapping); i {
|
||||
switch v := v.(*IdentityProviderConfig); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
@ -350,6 +497,18 @@ func file_store_idp_proto_init() {
|
||||
}
|
||||
}
|
||||
file_store_idp_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*FieldMapping); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_store_idp_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*OAuth2Config); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
@ -362,21 +521,22 @@ func file_store_idp_proto_init() {
|
||||
}
|
||||
}
|
||||
}
|
||||
file_store_idp_proto_msgTypes[0].OneofWrappers = []interface{}{
|
||||
(*IdentityProviderConfig_Oauth2)(nil),
|
||||
file_store_idp_proto_msgTypes[1].OneofWrappers = []interface{}{
|
||||
(*IdentityProviderConfig_Oauth2Config)(nil),
|
||||
}
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: file_store_idp_proto_rawDesc,
|
||||
NumEnums: 0,
|
||||
NumMessages: 3,
|
||||
NumEnums: 1,
|
||||
NumMessages: 4,
|
||||
NumExtensions: 0,
|
||||
NumServices: 0,
|
||||
},
|
||||
GoTypes: file_store_idp_proto_goTypes,
|
||||
DependencyIndexes: file_store_idp_proto_depIdxs,
|
||||
EnumInfos: file_store_idp_proto_enumTypes,
|
||||
MessageInfos: file_store_idp_proto_msgTypes,
|
||||
}.Build()
|
||||
File_store_idp_proto = out.File
|
||||
|
@ -4,9 +4,22 @@ package memos.store;
|
||||
|
||||
option go_package = "gen/store";
|
||||
|
||||
message IdentityProvider {
|
||||
int32 id = 1;
|
||||
string name = 2;
|
||||
|
||||
enum Type {
|
||||
TYPE_UNSPECIFIED = 0;
|
||||
OAUTH2 = 1;
|
||||
}
|
||||
Type type = 3;
|
||||
string identifier_filter = 4;
|
||||
IdentityProviderConfig config = 5;
|
||||
}
|
||||
|
||||
message IdentityProviderConfig {
|
||||
oneof config {
|
||||
OAuth2Config oauth2 = 1;
|
||||
OAuth2Config oauth2_config = 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5,7 +5,6 @@ import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"regexp"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
@ -14,8 +13,6 @@ import (
|
||||
"golang.org/x/crypto/bcrypt"
|
||||
|
||||
"github.com/usememos/memos/internal/util"
|
||||
"github.com/usememos/memos/plugin/idp"
|
||||
"github.com/usememos/memos/plugin/idp/oauth2"
|
||||
storepb "github.com/usememos/memos/proto/gen/store"
|
||||
"github.com/usememos/memos/server/route/api/auth"
|
||||
"github.com/usememos/memos/store"
|
||||
@ -40,7 +37,6 @@ type SignUp struct {
|
||||
|
||||
func (s *APIV1Service) registerAuthRoutes(g *echo.Group) {
|
||||
g.POST("/auth/signin", s.SignIn)
|
||||
g.POST("/auth/signin/sso", s.SignInSSO)
|
||||
g.POST("/auth/signout", s.SignOut)
|
||||
g.POST("/auth/signup", s.SignUp)
|
||||
}
|
||||
@ -111,117 +107,6 @@ func (s *APIV1Service) SignIn(c echo.Context) error {
|
||||
return c.JSON(http.StatusOK, userMessage)
|
||||
}
|
||||
|
||||
// SignInSSO godoc
|
||||
//
|
||||
// @Summary Sign-in to memos using SSO.
|
||||
// @Tags auth
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param body body SSOSignIn true "SSO sign-in object"
|
||||
// @Success 200 {object} store.User "User information"
|
||||
// @Failure 400 {object} nil "Malformatted signin request"
|
||||
// @Failure 401 {object} nil "Access denied, identifier does not match the filter."
|
||||
// @Failure 403 {object} nil "User has been archived with username {username}"
|
||||
// @Failure 404 {object} nil "Identity provider not found"
|
||||
// @Failure 500 {object} nil "Failed to find identity provider | Failed to create identity provider instance | Failed to exchange token | Failed to get user info | Failed to compile identifier filter | Incorrect login credentials, please try again | Failed to generate random password | Failed to generate password hash | Failed to create user | Failed to generate tokens | Failed to create activity"
|
||||
// @Router /api/v1/auth/signin/sso [POST]
|
||||
func (s *APIV1Service) SignInSSO(c echo.Context) error {
|
||||
ctx := c.Request().Context()
|
||||
signin := &SSOSignIn{}
|
||||
if err := json.NewDecoder(c.Request().Body).Decode(signin); err != nil {
|
||||
return echo.NewHTTPError(http.StatusBadRequest, "Malformatted signin request").SetInternal(err)
|
||||
}
|
||||
|
||||
identityProvider, err := s.Store.GetIdentityProvider(ctx, &store.FindIdentityProvider{
|
||||
ID: &signin.IdentityProviderID,
|
||||
})
|
||||
if err != nil {
|
||||
return echo.NewHTTPError(http.StatusInternalServerError, "Failed to find identity provider").SetInternal(err)
|
||||
}
|
||||
if identityProvider == nil {
|
||||
return echo.NewHTTPError(http.StatusNotFound, "Identity provider not found")
|
||||
}
|
||||
|
||||
var userInfo *idp.IdentityProviderUserInfo
|
||||
if identityProvider.Type == store.IdentityProviderOAuth2Type {
|
||||
oauth2IdentityProvider, err := oauth2.NewIdentityProvider(identityProvider.Config.OAuth2Config)
|
||||
if err != nil {
|
||||
return echo.NewHTTPError(http.StatusInternalServerError, "Failed to create identity provider instance").SetInternal(err)
|
||||
}
|
||||
token, err := oauth2IdentityProvider.ExchangeToken(ctx, signin.RedirectURI, signin.Code)
|
||||
if err != nil {
|
||||
return echo.NewHTTPError(http.StatusInternalServerError, "Failed to exchange token").SetInternal(err)
|
||||
}
|
||||
userInfo, err = oauth2IdentityProvider.UserInfo(token)
|
||||
if err != nil {
|
||||
return echo.NewHTTPError(http.StatusInternalServerError, "Failed to get user info").SetInternal(err)
|
||||
}
|
||||
}
|
||||
|
||||
identifierFilter := identityProvider.IdentifierFilter
|
||||
if identifierFilter != "" {
|
||||
identifierFilterRegex, err := regexp.Compile(identifierFilter)
|
||||
if err != nil {
|
||||
return echo.NewHTTPError(http.StatusInternalServerError, "Failed to compile identifier filter").SetInternal(err)
|
||||
}
|
||||
if !identifierFilterRegex.MatchString(userInfo.Identifier) {
|
||||
return echo.NewHTTPError(http.StatusUnauthorized, "Access denied, identifier does not match the filter.").SetInternal(err)
|
||||
}
|
||||
}
|
||||
|
||||
user, err := s.Store.GetUser(ctx, &store.FindUser{
|
||||
Username: &userInfo.Identifier,
|
||||
})
|
||||
if err != nil {
|
||||
return echo.NewHTTPError(http.StatusInternalServerError, "Incorrect login credentials, please try again")
|
||||
}
|
||||
if user == nil {
|
||||
workspaceGeneralSetting, err := s.Store.GetWorkspaceGeneralSetting(ctx)
|
||||
if err != nil {
|
||||
return echo.NewHTTPError(http.StatusInternalServerError, "Failed to find system setting").SetInternal(err)
|
||||
}
|
||||
if workspaceGeneralSetting.DisallowSignup {
|
||||
return echo.NewHTTPError(http.StatusUnauthorized, "signup is disabled").SetInternal(err)
|
||||
}
|
||||
|
||||
userCreate := &store.User{
|
||||
Username: userInfo.Identifier,
|
||||
// The new signup user should be normal user by default.
|
||||
Role: store.RoleUser,
|
||||
Nickname: userInfo.DisplayName,
|
||||
Email: userInfo.Email,
|
||||
}
|
||||
password, err := util.RandomString(20)
|
||||
if err != nil {
|
||||
return echo.NewHTTPError(http.StatusInternalServerError, "Failed to generate random password").SetInternal(err)
|
||||
}
|
||||
passwordHash, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
|
||||
if err != nil {
|
||||
return echo.NewHTTPError(http.StatusInternalServerError, "Failed to generate password hash").SetInternal(err)
|
||||
}
|
||||
userCreate.PasswordHash = string(passwordHash)
|
||||
user, err = s.Store.CreateUser(ctx, userCreate)
|
||||
if err != nil {
|
||||
return echo.NewHTTPError(http.StatusInternalServerError, "Failed to create user").SetInternal(err)
|
||||
}
|
||||
}
|
||||
if user.RowStatus == store.Archived {
|
||||
return echo.NewHTTPError(http.StatusForbidden, fmt.Sprintf("User has been archived with username %s", userInfo.Identifier))
|
||||
}
|
||||
|
||||
accessToken, err := auth.GenerateAccessToken(user.Username, user.ID, time.Now().Add(auth.AccessTokenDuration), []byte(s.Secret))
|
||||
if err != nil {
|
||||
return echo.NewHTTPError(http.StatusInternalServerError, fmt.Sprintf("failed to generate tokens, err: %s", err)).SetInternal(err)
|
||||
}
|
||||
if err := s.UpsertAccessTokenToStore(ctx, user, accessToken); err != nil {
|
||||
return echo.NewHTTPError(http.StatusInternalServerError, fmt.Sprintf("failed to upsert access token, err: %s", err)).SetInternal(err)
|
||||
}
|
||||
cookieExp := time.Now().Add(auth.CookieExpDuration)
|
||||
setTokenCookie(c, auth.AccessTokenCookieName, accessToken, cookieExp)
|
||||
userMessage := convertUserFromStore(user)
|
||||
return c.JSON(http.StatusOK, userMessage)
|
||||
}
|
||||
|
||||
// SignOut godoc
|
||||
//
|
||||
// @Summary Sign-out from memos.
|
||||
|
@ -1,349 +0,0 @@
|
||||
package v1
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"github.com/labstack/echo/v4"
|
||||
|
||||
"github.com/usememos/memos/internal/util"
|
||||
"github.com/usememos/memos/store"
|
||||
)
|
||||
|
||||
type IdentityProviderType string
|
||||
|
||||
const (
|
||||
IdentityProviderOAuth2Type IdentityProviderType = "OAUTH2"
|
||||
)
|
||||
|
||||
func (t IdentityProviderType) String() string {
|
||||
return string(t)
|
||||
}
|
||||
|
||||
type IdentityProviderConfig struct {
|
||||
OAuth2Config *IdentityProviderOAuth2Config `json:"oauth2Config"`
|
||||
}
|
||||
|
||||
type IdentityProviderOAuth2Config struct {
|
||||
ClientID string `json:"clientId"`
|
||||
ClientSecret string `json:"clientSecret"`
|
||||
AuthURL string `json:"authUrl"`
|
||||
TokenURL string `json:"tokenUrl"`
|
||||
UserInfoURL string `json:"userInfoUrl"`
|
||||
Scopes []string `json:"scopes"`
|
||||
FieldMapping *FieldMapping `json:"fieldMapping"`
|
||||
}
|
||||
|
||||
type FieldMapping struct {
|
||||
Identifier string `json:"identifier"`
|
||||
DisplayName string `json:"displayName"`
|
||||
Email string `json:"email"`
|
||||
}
|
||||
|
||||
type IdentityProvider struct {
|
||||
ID int32 `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Type IdentityProviderType `json:"type"`
|
||||
IdentifierFilter string `json:"identifierFilter"`
|
||||
Config *IdentityProviderConfig `json:"config"`
|
||||
}
|
||||
|
||||
type CreateIdentityProviderRequest struct {
|
||||
Name string `json:"name"`
|
||||
Type IdentityProviderType `json:"type"`
|
||||
IdentifierFilter string `json:"identifierFilter"`
|
||||
Config *IdentityProviderConfig `json:"config"`
|
||||
}
|
||||
|
||||
type UpdateIdentityProviderRequest struct {
|
||||
ID int32 `json:"-"`
|
||||
Type IdentityProviderType `json:"type"`
|
||||
Name *string `json:"name"`
|
||||
IdentifierFilter *string `json:"identifierFilter"`
|
||||
Config *IdentityProviderConfig `json:"config"`
|
||||
}
|
||||
|
||||
func (s *APIV1Service) registerIdentityProviderRoutes(g *echo.Group) {
|
||||
g.GET("/idp", s.GetIdentityProviderList)
|
||||
g.POST("/idp", s.CreateIdentityProvider)
|
||||
g.GET("/idp/:idpId", s.GetIdentityProvider)
|
||||
g.PATCH("/idp/:idpId", s.UpdateIdentityProvider)
|
||||
g.DELETE("/idp/:idpId", s.DeleteIdentityProvider)
|
||||
}
|
||||
|
||||
// GetIdentityProviderList godoc
|
||||
//
|
||||
// @Summary Get a list of identity providers
|
||||
// @Description *clientSecret is only available for host user
|
||||
// @Tags idp
|
||||
// @Produce json
|
||||
// @Success 200 {object} []IdentityProvider "List of available identity providers"
|
||||
// @Failure 500 {object} nil "Failed to find identity provider list | Failed to find user"
|
||||
// @Router /api/v1/idp [GET]
|
||||
func (s *APIV1Service) GetIdentityProviderList(c echo.Context) error {
|
||||
ctx := c.Request().Context()
|
||||
list, err := s.Store.ListIdentityProviders(ctx, &store.FindIdentityProvider{})
|
||||
if err != nil {
|
||||
return echo.NewHTTPError(http.StatusInternalServerError, "Failed to find identity provider list").SetInternal(err)
|
||||
}
|
||||
|
||||
userID, ok := c.Get(userIDContextKey).(int32)
|
||||
isHostUser := false
|
||||
if ok {
|
||||
user, err := s.Store.GetUser(ctx, &store.FindUser{
|
||||
ID: &userID,
|
||||
})
|
||||
if err != nil {
|
||||
return echo.NewHTTPError(http.StatusInternalServerError, "Failed to find user").SetInternal(err)
|
||||
}
|
||||
if user == nil || user.Role == store.RoleHost {
|
||||
isHostUser = true
|
||||
}
|
||||
}
|
||||
|
||||
identityProviderList := []*IdentityProvider{}
|
||||
for _, item := range list {
|
||||
identityProvider := convertIdentityProviderFromStore(item)
|
||||
// data desensitize
|
||||
if !isHostUser {
|
||||
identityProvider.Config.OAuth2Config.ClientSecret = ""
|
||||
}
|
||||
identityProviderList = append(identityProviderList, identityProvider)
|
||||
}
|
||||
return c.JSON(http.StatusOK, identityProviderList)
|
||||
}
|
||||
|
||||
// CreateIdentityProvider godoc
|
||||
//
|
||||
// @Summary Create Identity Provider
|
||||
// @Tags idp
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param body body CreateIdentityProviderRequest true "Identity provider information"
|
||||
// @Success 200 {object} store.IdentityProvider "Identity provider information"
|
||||
// @Failure 401 {object} nil "Missing user in session | Unauthorized"
|
||||
// @Failure 400 {object} nil "Malformatted post identity provider request"
|
||||
// @Failure 500 {object} nil "Failed to find user | Failed to create identity provider"
|
||||
// @Router /api/v1/idp [POST]
|
||||
func (s *APIV1Service) CreateIdentityProvider(c echo.Context) error {
|
||||
ctx := c.Request().Context()
|
||||
userID, ok := c.Get(userIDContextKey).(int32)
|
||||
if !ok {
|
||||
return echo.NewHTTPError(http.StatusUnauthorized, "Missing user in session")
|
||||
}
|
||||
|
||||
user, err := s.Store.GetUser(ctx, &store.FindUser{
|
||||
ID: &userID,
|
||||
})
|
||||
if err != nil {
|
||||
return echo.NewHTTPError(http.StatusInternalServerError, "Failed to find user").SetInternal(err)
|
||||
}
|
||||
if user == nil || user.Role != store.RoleHost {
|
||||
return echo.NewHTTPError(http.StatusUnauthorized, "Unauthorized")
|
||||
}
|
||||
|
||||
identityProviderCreate := &CreateIdentityProviderRequest{}
|
||||
if err := json.NewDecoder(c.Request().Body).Decode(identityProviderCreate); err != nil {
|
||||
return echo.NewHTTPError(http.StatusBadRequest, "Malformatted post identity provider request").SetInternal(err)
|
||||
}
|
||||
|
||||
identityProvider, err := s.Store.CreateIdentityProvider(ctx, &store.IdentityProvider{
|
||||
Name: identityProviderCreate.Name,
|
||||
Type: store.IdentityProviderType(identityProviderCreate.Type),
|
||||
IdentifierFilter: identityProviderCreate.IdentifierFilter,
|
||||
Config: convertIdentityProviderConfigToStore(identityProviderCreate.Config),
|
||||
})
|
||||
if err != nil {
|
||||
return echo.NewHTTPError(http.StatusInternalServerError, "Failed to create identity provider").SetInternal(err)
|
||||
}
|
||||
return c.JSON(http.StatusOK, convertIdentityProviderFromStore(identityProvider))
|
||||
}
|
||||
|
||||
// GetIdentityProvider godoc
|
||||
//
|
||||
// @Summary Get an identity provider by ID
|
||||
// @Tags idp
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param idpId path int true "Identity provider ID"
|
||||
// @Success 200 {object} store.IdentityProvider "Requested identity provider"
|
||||
// @Failure 400 {object} nil "ID is not a number: %s"
|
||||
// @Failure 401 {object} nil "Missing user in session | Unauthorized"
|
||||
// @Failure 404 {object} nil "Identity provider not found"
|
||||
// @Failure 500 {object} nil "Failed to find identity provider list | Failed to find user"
|
||||
// @Router /api/v1/idp/{idpId} [GET]
|
||||
func (s *APIV1Service) GetIdentityProvider(c echo.Context) error {
|
||||
ctx := c.Request().Context()
|
||||
userID, ok := c.Get(userIDContextKey).(int32)
|
||||
if !ok {
|
||||
return echo.NewHTTPError(http.StatusUnauthorized, "Missing user in session")
|
||||
}
|
||||
|
||||
user, err := s.Store.GetUser(ctx, &store.FindUser{
|
||||
ID: &userID,
|
||||
})
|
||||
if err != nil {
|
||||
return echo.NewHTTPError(http.StatusInternalServerError, "Failed to find user").SetInternal(err)
|
||||
}
|
||||
if user == nil || user.Role != store.RoleHost {
|
||||
return echo.NewHTTPError(http.StatusUnauthorized, "Unauthorized")
|
||||
}
|
||||
|
||||
identityProviderID, err := util.ConvertStringToInt32(c.Param("idpId"))
|
||||
if err != nil {
|
||||
return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("ID is not a number: %s", c.Param("idpId"))).SetInternal(err)
|
||||
}
|
||||
identityProvider, err := s.Store.GetIdentityProvider(ctx, &store.FindIdentityProvider{
|
||||
ID: &identityProviderID,
|
||||
})
|
||||
if err != nil {
|
||||
return echo.NewHTTPError(http.StatusInternalServerError, "Failed to get identity provider").SetInternal(err)
|
||||
}
|
||||
if identityProvider == nil {
|
||||
return echo.NewHTTPError(http.StatusNotFound, "Identity provider not found")
|
||||
}
|
||||
|
||||
return c.JSON(http.StatusOK, convertIdentityProviderFromStore(identityProvider))
|
||||
}
|
||||
|
||||
// DeleteIdentityProvider godoc
|
||||
//
|
||||
// @Summary Delete an identity provider by ID
|
||||
// @Tags idp
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param idpId path int true "Identity Provider ID"
|
||||
// @Success 200 {boolean} true "Identity Provider deleted"
|
||||
// @Failure 400 {object} nil "ID is not a number: %s | Malformatted patch identity provider request"
|
||||
// @Failure 401 {object} nil "Missing user in session | Unauthorized"
|
||||
// @Failure 500 {object} nil "Failed to find user | Failed to patch identity provider"
|
||||
// @Router /api/v1/idp/{idpId} [DELETE]
|
||||
func (s *APIV1Service) DeleteIdentityProvider(c echo.Context) error {
|
||||
ctx := c.Request().Context()
|
||||
userID, ok := c.Get(userIDContextKey).(int32)
|
||||
if !ok {
|
||||
return echo.NewHTTPError(http.StatusUnauthorized, "Missing user in session")
|
||||
}
|
||||
|
||||
user, err := s.Store.GetUser(ctx, &store.FindUser{
|
||||
ID: &userID,
|
||||
})
|
||||
if err != nil {
|
||||
return echo.NewHTTPError(http.StatusInternalServerError, "Failed to find user").SetInternal(err)
|
||||
}
|
||||
if user == nil || user.Role != store.RoleHost {
|
||||
return echo.NewHTTPError(http.StatusUnauthorized, "Unauthorized")
|
||||
}
|
||||
|
||||
identityProviderID, err := util.ConvertStringToInt32(c.Param("idpId"))
|
||||
if err != nil {
|
||||
return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("ID is not a number: %s", c.Param("idpId"))).SetInternal(err)
|
||||
}
|
||||
|
||||
if err = s.Store.DeleteIdentityProvider(ctx, &store.DeleteIdentityProvider{ID: identityProviderID}); err != nil {
|
||||
return echo.NewHTTPError(http.StatusInternalServerError, "Failed to delete identity provider").SetInternal(err)
|
||||
}
|
||||
return c.JSON(http.StatusOK, true)
|
||||
}
|
||||
|
||||
// UpdateIdentityProvider godoc
|
||||
//
|
||||
// @Summary Update an identity provider by ID
|
||||
// @Tags idp
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param idpId path int true "Identity Provider ID"
|
||||
// @Param body body UpdateIdentityProviderRequest true "Patched identity provider information"
|
||||
// @Success 200 {object} store.IdentityProvider "Patched identity provider"
|
||||
// @Failure 400 {object} nil "ID is not a number: %s | Malformatted patch identity provider request"
|
||||
// @Failure 401 {object} nil "Missing user in session | Unauthorized
|
||||
// @Failure 500 {object} nil "Failed to find user | Failed to patch identity provider"
|
||||
// @Router /api/v1/idp/{idpId} [PATCH]
|
||||
func (s *APIV1Service) UpdateIdentityProvider(c echo.Context) error {
|
||||
ctx := c.Request().Context()
|
||||
userID, ok := c.Get(userIDContextKey).(int32)
|
||||
if !ok {
|
||||
return echo.NewHTTPError(http.StatusUnauthorized, "Missing user in session")
|
||||
}
|
||||
|
||||
user, err := s.Store.GetUser(ctx, &store.FindUser{
|
||||
ID: &userID,
|
||||
})
|
||||
if err != nil {
|
||||
return echo.NewHTTPError(http.StatusInternalServerError, "Failed to find user").SetInternal(err)
|
||||
}
|
||||
if user == nil || user.Role != store.RoleHost {
|
||||
return echo.NewHTTPError(http.StatusUnauthorized, "Unauthorized")
|
||||
}
|
||||
|
||||
identityProviderID, err := util.ConvertStringToInt32(c.Param("idpId"))
|
||||
if err != nil {
|
||||
return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("ID is not a number: %s", c.Param("idpId"))).SetInternal(err)
|
||||
}
|
||||
|
||||
identityProviderPatch := &UpdateIdentityProviderRequest{
|
||||
ID: identityProviderID,
|
||||
}
|
||||
if err := json.NewDecoder(c.Request().Body).Decode(identityProviderPatch); err != nil {
|
||||
return echo.NewHTTPError(http.StatusBadRequest, "Malformatted patch identity provider request").SetInternal(err)
|
||||
}
|
||||
|
||||
identityProvider, err := s.Store.UpdateIdentityProvider(ctx, &store.UpdateIdentityProvider{
|
||||
ID: identityProviderPatch.ID,
|
||||
Type: store.IdentityProviderType(identityProviderPatch.Type),
|
||||
Name: identityProviderPatch.Name,
|
||||
IdentifierFilter: identityProviderPatch.IdentifierFilter,
|
||||
Config: convertIdentityProviderConfigToStore(identityProviderPatch.Config),
|
||||
})
|
||||
if err != nil {
|
||||
return echo.NewHTTPError(http.StatusInternalServerError, "Failed to patch identity provider").SetInternal(err)
|
||||
}
|
||||
return c.JSON(http.StatusOK, convertIdentityProviderFromStore(identityProvider))
|
||||
}
|
||||
|
||||
func convertIdentityProviderFromStore(identityProvider *store.IdentityProvider) *IdentityProvider {
|
||||
return &IdentityProvider{
|
||||
ID: identityProvider.ID,
|
||||
Name: identityProvider.Name,
|
||||
Type: IdentityProviderType(identityProvider.Type),
|
||||
IdentifierFilter: identityProvider.IdentifierFilter,
|
||||
Config: convertIdentityProviderConfigFromStore(identityProvider.Config),
|
||||
}
|
||||
}
|
||||
|
||||
func convertIdentityProviderConfigFromStore(config *store.IdentityProviderConfig) *IdentityProviderConfig {
|
||||
return &IdentityProviderConfig{
|
||||
OAuth2Config: &IdentityProviderOAuth2Config{
|
||||
ClientID: config.OAuth2Config.ClientID,
|
||||
ClientSecret: config.OAuth2Config.ClientSecret,
|
||||
AuthURL: config.OAuth2Config.AuthURL,
|
||||
TokenURL: config.OAuth2Config.TokenURL,
|
||||
UserInfoURL: config.OAuth2Config.UserInfoURL,
|
||||
Scopes: config.OAuth2Config.Scopes,
|
||||
FieldMapping: &FieldMapping{
|
||||
Identifier: config.OAuth2Config.FieldMapping.Identifier,
|
||||
DisplayName: config.OAuth2Config.FieldMapping.DisplayName,
|
||||
Email: config.OAuth2Config.FieldMapping.Email,
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func convertIdentityProviderConfigToStore(config *IdentityProviderConfig) *store.IdentityProviderConfig {
|
||||
return &store.IdentityProviderConfig{
|
||||
OAuth2Config: &store.IdentityProviderOAuth2Config{
|
||||
ClientID: config.OAuth2Config.ClientID,
|
||||
ClientSecret: config.OAuth2Config.ClientSecret,
|
||||
AuthURL: config.OAuth2Config.AuthURL,
|
||||
TokenURL: config.OAuth2Config.TokenURL,
|
||||
UserInfoURL: config.OAuth2Config.UserInfoURL,
|
||||
Scopes: config.OAuth2Config.Scopes,
|
||||
FieldMapping: &store.FieldMapping{
|
||||
Identifier: config.OAuth2Config.FieldMapping.Identifier,
|
||||
DisplayName: config.OAuth2Config.FieldMapping.DisplayName,
|
||||
Email: config.OAuth2Config.FieldMapping.Email,
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
@ -68,7 +68,6 @@ func (s *APIV1Service) Register(rootGroup *echo.Group) {
|
||||
s.registerSystemRoutes(apiV1Group)
|
||||
s.registerSystemSettingRoutes(apiV1Group)
|
||||
s.registerAuthRoutes(apiV1Group)
|
||||
s.registerIdentityProviderRoutes(apiV1Group)
|
||||
s.registerUserRoutes(apiV1Group)
|
||||
s.registerTagRoutes(apiV1Group)
|
||||
s.registerStorageRoutes(apiV1Group)
|
||||
|
@ -4,6 +4,8 @@ var authenticationAllowlistMethods = map[string]bool{
|
||||
"/memos.api.v2.WorkspaceService/GetWorkspaceProfile": true,
|
||||
"/memos.api.v2.WorkspaceSettingService/GetWorkspaceSetting": true,
|
||||
"/memos.api.v2.WorkspaceSettingService/ListWorkspaceSettings": true,
|
||||
"/memos.api.v2.IdentityProviderService/ListIdentityProviders": true,
|
||||
"/memos.api.v2.IdentityProviderService/GetIdentityProvider": true,
|
||||
"/memos.api.v2.AuthService/GetAuthStatus": true,
|
||||
"/memos.api.v2.AuthService/SignIn": true,
|
||||
"/memos.api.v2.AuthService/SignInWithSSO": true,
|
||||
|
@ -181,42 +181,42 @@ paths:
|
||||
in: query
|
||||
required: false
|
||||
type: string
|
||||
- name: identityProvider.config.oauth2.clientId
|
||||
- name: identityProvider.config.oauth2Config.clientId
|
||||
in: query
|
||||
required: false
|
||||
type: string
|
||||
- name: identityProvider.config.oauth2.clientSecret
|
||||
- name: identityProvider.config.oauth2Config.clientSecret
|
||||
in: query
|
||||
required: false
|
||||
type: string
|
||||
- name: identityProvider.config.oauth2.authUrl
|
||||
- name: identityProvider.config.oauth2Config.authUrl
|
||||
in: query
|
||||
required: false
|
||||
type: string
|
||||
- name: identityProvider.config.oauth2.tokenUrl
|
||||
- name: identityProvider.config.oauth2Config.tokenUrl
|
||||
in: query
|
||||
required: false
|
||||
type: string
|
||||
- name: identityProvider.config.oauth2.userInfoUrl
|
||||
- name: identityProvider.config.oauth2Config.userInfoUrl
|
||||
in: query
|
||||
required: false
|
||||
type: string
|
||||
- name: identityProvider.config.oauth2.scopes
|
||||
- name: identityProvider.config.oauth2Config.scopes
|
||||
in: query
|
||||
required: false
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
collectionFormat: multi
|
||||
- name: identityProvider.config.oauth2.fieldMapping.identifier
|
||||
- name: identityProvider.config.oauth2Config.fieldMapping.identifier
|
||||
in: query
|
||||
required: false
|
||||
type: string
|
||||
- name: identityProvider.config.oauth2.fieldMapping.displayName
|
||||
- name: identityProvider.config.oauth2Config.fieldMapping.displayName
|
||||
in: query
|
||||
required: false
|
||||
type: string
|
||||
- name: identityProvider.config.oauth2.fieldMapping.email
|
||||
- name: identityProvider.config.oauth2Config.fieldMapping.email
|
||||
in: query
|
||||
required: false
|
||||
type: string
|
||||
@ -1070,7 +1070,7 @@ paths:
|
||||
type: object
|
||||
properties:
|
||||
type:
|
||||
$ref: '#/definitions/v2IdentityProviderType'
|
||||
$ref: '#/definitions/apiv2IdentityProviderType'
|
||||
title:
|
||||
type: string
|
||||
identifierFilter:
|
||||
@ -2006,11 +2006,33 @@ definitions:
|
||||
type: string
|
||||
email:
|
||||
type: string
|
||||
apiv2IdentityProvider:
|
||||
type: object
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
title: |-
|
||||
The name of the identityProvider.
|
||||
Format: identityProviders/{id}
|
||||
type:
|
||||
$ref: '#/definitions/apiv2IdentityProviderType'
|
||||
title:
|
||||
type: string
|
||||
identifierFilter:
|
||||
type: string
|
||||
config:
|
||||
$ref: '#/definitions/apiv2IdentityProviderConfig'
|
||||
apiv2IdentityProviderConfig:
|
||||
type: object
|
||||
properties:
|
||||
oauth2:
|
||||
oauth2Config:
|
||||
$ref: '#/definitions/apiv2OAuth2Config'
|
||||
apiv2IdentityProviderType:
|
||||
type: string
|
||||
enum:
|
||||
- TYPE_UNSPECIFIED
|
||||
- OAUTH2
|
||||
default: TYPE_UNSPECIFIED
|
||||
apiv2OAuth2Config:
|
||||
type: object
|
||||
properties:
|
||||
@ -2293,7 +2315,7 @@ definitions:
|
||||
type: object
|
||||
properties:
|
||||
identityProvider:
|
||||
$ref: '#/definitions/v2IdentityProvider'
|
||||
$ref: '#/definitions/apiv2IdentityProvider'
|
||||
description: The created identityProvider.
|
||||
v2CreateMemoCommentResponse:
|
||||
type: object
|
||||
@ -2389,7 +2411,7 @@ definitions:
|
||||
type: object
|
||||
properties:
|
||||
identityProvider:
|
||||
$ref: '#/definitions/v2IdentityProvider'
|
||||
$ref: '#/definitions/apiv2IdentityProvider'
|
||||
description: The identityProvider.
|
||||
v2GetLinkMetadataResponse:
|
||||
type: object
|
||||
@ -2454,28 +2476,6 @@ definitions:
|
||||
properties:
|
||||
setting:
|
||||
$ref: '#/definitions/apiv2WorkspaceSetting'
|
||||
v2IdentityProvider:
|
||||
type: object
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
title: |-
|
||||
The name of the identityProvider.
|
||||
Format: identityProviders/{id}
|
||||
type:
|
||||
$ref: '#/definitions/v2IdentityProviderType'
|
||||
title:
|
||||
type: string
|
||||
identifierFilter:
|
||||
type: string
|
||||
config:
|
||||
$ref: '#/definitions/apiv2IdentityProviderConfig'
|
||||
v2IdentityProviderType:
|
||||
type: string
|
||||
enum:
|
||||
- TYPE_UNSPECIFIED
|
||||
- OAUTH2
|
||||
default: TYPE_UNSPECIFIED
|
||||
v2Inbox:
|
||||
type: object
|
||||
properties:
|
||||
@ -2530,7 +2530,7 @@ definitions:
|
||||
type: array
|
||||
items:
|
||||
type: object
|
||||
$ref: '#/definitions/v2IdentityProvider'
|
||||
$ref: '#/definitions/apiv2IdentityProvider'
|
||||
v2ListInboxesResponse:
|
||||
type: object
|
||||
properties:
|
||||
@ -2820,7 +2820,7 @@ definitions:
|
||||
type: object
|
||||
properties:
|
||||
identityProvider:
|
||||
$ref: '#/definitions/v2IdentityProvider'
|
||||
$ref: '#/definitions/apiv2IdentityProvider'
|
||||
description: The updated identityProvider.
|
||||
v2UpdateInboxResponse:
|
||||
type: object
|
||||
|
@ -18,6 +18,7 @@ import (
|
||||
"github.com/usememos/memos/plugin/idp"
|
||||
"github.com/usememos/memos/plugin/idp/oauth2"
|
||||
apiv2pb "github.com/usememos/memos/proto/gen/api/v2"
|
||||
storepb "github.com/usememos/memos/proto/gen/store"
|
||||
"github.com/usememos/memos/server/route/api/auth"
|
||||
"github.com/usememos/memos/store"
|
||||
)
|
||||
@ -71,7 +72,7 @@ func (s *APIV2Service) SignIn(ctx context.Context, request *apiv2pb.SignInReques
|
||||
}
|
||||
|
||||
func (s *APIV2Service) SignInWithSSO(ctx context.Context, request *apiv2pb.SignInWithSSORequest) (*apiv2pb.SignInWithSSOResponse, error) {
|
||||
identityProvider, err := s.Store.GetIdentityProvider(ctx, &store.FindIdentityProvider{
|
||||
identityProvider, err := s.Store.GetIdentityProviderV1(ctx, &store.FindIdentityProvider{
|
||||
ID: &request.IdpId,
|
||||
})
|
||||
if err != nil {
|
||||
@ -82,8 +83,8 @@ func (s *APIV2Service) SignInWithSSO(ctx context.Context, request *apiv2pb.SignI
|
||||
}
|
||||
|
||||
var userInfo *idp.IdentityProviderUserInfo
|
||||
if identityProvider.Type == store.IdentityProviderOAuth2Type {
|
||||
oauth2IdentityProvider, err := oauth2.NewIdentityProvider(identityProvider.Config.OAuth2Config)
|
||||
if identityProvider.Type == storepb.IdentityProvider_OAUTH2 {
|
||||
oauth2IdentityProvider, err := oauth2.NewIdentityProvider(identityProvider.Config.GetOauth2Config())
|
||||
if err != nil {
|
||||
return nil, status.Errorf(codes.Internal, fmt.Sprintf("failed to create oauth2 identity provider, err: %s", err))
|
||||
}
|
||||
|
174
server/route/api/v2/idp_service.go
Normal file
174
server/route/api/v2/idp_service.go
Normal file
@ -0,0 +1,174 @@
|
||||
package v2
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/status"
|
||||
|
||||
apiv2pb "github.com/usememos/memos/proto/gen/api/v2"
|
||||
storepb "github.com/usememos/memos/proto/gen/store"
|
||||
"github.com/usememos/memos/store"
|
||||
)
|
||||
|
||||
func (s *APIV2Service) CreateIdentityProvider(ctx context.Context, request *apiv2pb.CreateIdentityProviderRequest) (*apiv2pb.CreateIdentityProviderResponse, error) {
|
||||
currentUser, err := getCurrentUser(ctx, s.Store)
|
||||
if err != nil {
|
||||
return nil, status.Errorf(codes.Internal, "failed to get user: %v", err)
|
||||
}
|
||||
if currentUser.Role != store.RoleHost {
|
||||
return nil, status.Errorf(codes.PermissionDenied, "permission denied")
|
||||
}
|
||||
|
||||
identityProvider, err := s.Store.CreateIdentityProviderV1(ctx, convertIdentityProviderToStore(request.IdentityProvider))
|
||||
if err != nil {
|
||||
return nil, status.Errorf(codes.Internal, "failed to create identity provider, error: %+v", err)
|
||||
}
|
||||
return &apiv2pb.CreateIdentityProviderResponse{
|
||||
IdentityProvider: convertIdentityProviderFromStore(identityProvider),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *APIV2Service) ListIdentityProviders(ctx context.Context, _ *apiv2pb.ListIdentityProvidersRequest) (*apiv2pb.ListIdentityProvidersResponse, error) {
|
||||
identityProviders, err := s.Store.ListIdentityProvidersV1(ctx, &store.FindIdentityProvider{})
|
||||
if err != nil {
|
||||
return nil, status.Errorf(codes.Internal, "failed to list identity providers, error: %+v", err)
|
||||
}
|
||||
|
||||
response := &apiv2pb.ListIdentityProvidersResponse{
|
||||
IdentityProviders: []*apiv2pb.IdentityProvider{},
|
||||
}
|
||||
for _, identityProvider := range identityProviders {
|
||||
response.IdentityProviders = append(response.IdentityProviders, convertIdentityProviderFromStore(identityProvider))
|
||||
}
|
||||
return response, nil
|
||||
}
|
||||
|
||||
func (s *APIV2Service) GetIdentityProvider(ctx context.Context, request *apiv2pb.GetIdentityProviderRequest) (*apiv2pb.GetIdentityProviderResponse, error) {
|
||||
id, err := ExtractIdentityProviderIDFromName(request.Name)
|
||||
if err != nil {
|
||||
return nil, status.Errorf(codes.InvalidArgument, "invalid identity provider name: %v", err)
|
||||
}
|
||||
identityProvider, err := s.Store.GetIdentityProviderV1(ctx, &store.FindIdentityProvider{
|
||||
ID: &id,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, status.Errorf(codes.Internal, "failed to get identity provider, error: %+v", err)
|
||||
}
|
||||
if identityProvider == nil {
|
||||
return nil, status.Errorf(codes.NotFound, "identity provider not found")
|
||||
}
|
||||
return &apiv2pb.GetIdentityProviderResponse{
|
||||
IdentityProvider: convertIdentityProviderFromStore(identityProvider),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *APIV2Service) UpdateIdentityProvider(ctx context.Context, request *apiv2pb.UpdateIdentityProviderRequest) (*apiv2pb.UpdateIdentityProviderResponse, error) {
|
||||
if request.UpdateMask == nil || len(request.UpdateMask.Paths) == 0 {
|
||||
return nil, status.Errorf(codes.InvalidArgument, "update_mask is required")
|
||||
}
|
||||
|
||||
id, err := ExtractIdentityProviderIDFromName(request.IdentityProvider.Name)
|
||||
if err != nil {
|
||||
return nil, status.Errorf(codes.InvalidArgument, "invalid identity provider name: %v", err)
|
||||
}
|
||||
update := &store.UpdateIdentityProviderV1{
|
||||
ID: id,
|
||||
Type: storepb.IdentityProvider_Type(storepb.IdentityProvider_Type_value[request.IdentityProvider.Type.String()]),
|
||||
}
|
||||
for _, field := range request.UpdateMask.Paths {
|
||||
switch field {
|
||||
case "title":
|
||||
update.Name = &request.IdentityProvider.Title
|
||||
case "config":
|
||||
update.Config = convertIdentityProviderConfigToStore(request.IdentityProvider.Type, request.IdentityProvider.Config)
|
||||
}
|
||||
}
|
||||
|
||||
identityProvider, err := s.Store.UpdateIdentityProviderV1(ctx, update)
|
||||
if err != nil {
|
||||
return nil, status.Errorf(codes.Internal, "failed to update identity provider, error: %+v", err)
|
||||
}
|
||||
return &apiv2pb.UpdateIdentityProviderResponse{
|
||||
IdentityProvider: convertIdentityProviderFromStore(identityProvider),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *APIV2Service) DeleteIdentityProvider(ctx context.Context, request *apiv2pb.DeleteIdentityProviderRequest) (*apiv2pb.DeleteIdentityProviderResponse, error) {
|
||||
id, err := ExtractIdentityProviderIDFromName(request.Name)
|
||||
if err != nil {
|
||||
return nil, status.Errorf(codes.InvalidArgument, "invalid identity provider name: %v", err)
|
||||
}
|
||||
if err := s.Store.DeleteIdentityProvider(ctx, &store.DeleteIdentityProvider{ID: id}); err != nil {
|
||||
return nil, status.Errorf(codes.Internal, "failed to delete identity provider, error: %+v", err)
|
||||
}
|
||||
return &apiv2pb.DeleteIdentityProviderResponse{}, nil
|
||||
}
|
||||
|
||||
func convertIdentityProviderFromStore(identityProvider *storepb.IdentityProvider) *apiv2pb.IdentityProvider {
|
||||
temp := &apiv2pb.IdentityProvider{
|
||||
Name: fmt.Sprintf("%s%d", IdentityProviderNamePrefix, identityProvider.Id),
|
||||
Title: identityProvider.Name,
|
||||
IdentifierFilter: identityProvider.IdentifierFilter,
|
||||
Type: apiv2pb.IdentityProvider_Type(apiv2pb.IdentityProvider_Type_value[identityProvider.Type.String()]),
|
||||
}
|
||||
if identityProvider.Type == storepb.IdentityProvider_OAUTH2 {
|
||||
oauth2Config := identityProvider.Config.GetOauth2Config()
|
||||
temp.Config = &apiv2pb.IdentityProviderConfig{
|
||||
Config: &apiv2pb.IdentityProviderConfig_Oauth2Config{
|
||||
Oauth2Config: &apiv2pb.OAuth2Config{
|
||||
ClientId: oauth2Config.ClientId,
|
||||
ClientSecret: oauth2Config.ClientSecret,
|
||||
AuthUrl: oauth2Config.AuthUrl,
|
||||
TokenUrl: oauth2Config.TokenUrl,
|
||||
UserInfoUrl: oauth2Config.UserInfoUrl,
|
||||
Scopes: oauth2Config.Scopes,
|
||||
FieldMapping: &apiv2pb.FieldMapping{
|
||||
Identifier: oauth2Config.FieldMapping.Identifier,
|
||||
DisplayName: oauth2Config.FieldMapping.DisplayName,
|
||||
Email: oauth2Config.FieldMapping.Email,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
return temp
|
||||
}
|
||||
|
||||
func convertIdentityProviderToStore(identityProvider *apiv2pb.IdentityProvider) *storepb.IdentityProvider {
|
||||
id, _ := ExtractIdentityProviderIDFromName(identityProvider.Name)
|
||||
|
||||
temp := &storepb.IdentityProvider{
|
||||
Id: id,
|
||||
Name: identityProvider.Title,
|
||||
IdentifierFilter: identityProvider.IdentifierFilter,
|
||||
Type: storepb.IdentityProvider_Type(storepb.IdentityProvider_Type_value[identityProvider.Type.String()]),
|
||||
Config: convertIdentityProviderConfigToStore(identityProvider.Type, identityProvider.Config),
|
||||
}
|
||||
return temp
|
||||
}
|
||||
|
||||
func convertIdentityProviderConfigToStore(identityProviderType apiv2pb.IdentityProvider_Type, config *apiv2pb.IdentityProviderConfig) *storepb.IdentityProviderConfig {
|
||||
if identityProviderType == apiv2pb.IdentityProvider_OAUTH2 {
|
||||
oauth2Config := config.GetOauth2Config()
|
||||
return &storepb.IdentityProviderConfig{
|
||||
Config: &storepb.IdentityProviderConfig_Oauth2Config{
|
||||
Oauth2Config: &storepb.OAuth2Config{
|
||||
ClientId: oauth2Config.ClientId,
|
||||
ClientSecret: oauth2Config.ClientSecret,
|
||||
AuthUrl: oauth2Config.AuthUrl,
|
||||
TokenUrl: oauth2Config.TokenUrl,
|
||||
UserInfoUrl: oauth2Config.UserInfoUrl,
|
||||
Scopes: oauth2Config.Scopes,
|
||||
FieldMapping: &storepb.FieldMapping{
|
||||
Identifier: oauth2Config.FieldMapping.Identifier,
|
||||
DisplayName: oauth2Config.FieldMapping.DisplayName,
|
||||
Email: oauth2Config.FieldMapping.Email,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
@ -16,6 +16,7 @@ const (
|
||||
ResourceNamePrefix = "resources/"
|
||||
InboxNamePrefix = "inboxes/"
|
||||
StorageNamePrefix = "storages/"
|
||||
IdentityProviderNamePrefix = "identityProviders/"
|
||||
)
|
||||
|
||||
// GetNameParentTokens returns the tokens from a resource name.
|
||||
@ -110,3 +111,15 @@ func ExtractStorageIDFromName(name string) (int32, error) {
|
||||
}
|
||||
return id, nil
|
||||
}
|
||||
|
||||
func ExtractIdentityProviderIDFromName(name string) (int32, error) {
|
||||
tokens, err := GetNameParentTokens(name, IdentityProviderNamePrefix)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
id, err := util.ConvertStringToInt32(tokens[0])
|
||||
if err != nil {
|
||||
return 0, errors.Errorf("invalid identity provider ID %q", tokens[0])
|
||||
}
|
||||
return id, nil
|
||||
}
|
||||
|
@ -105,7 +105,7 @@ func convertStorageFromStore(storage *storepb.Storage) *apiv2pb.Storage {
|
||||
if storage.Type == storepb.Storage_S3 {
|
||||
s3Config := storage.Config.GetS3Config()
|
||||
temp.Config = &apiv2pb.StorageConfig{
|
||||
StorageConfig: &apiv2pb.StorageConfig_S3Config{
|
||||
Config: &apiv2pb.StorageConfig_S3Config{
|
||||
S3Config: &apiv2pb.S3Config{
|
||||
EndPoint: s3Config.EndPoint,
|
||||
Path: s3Config.Path,
|
||||
|
@ -32,6 +32,7 @@ type APIV2Service struct {
|
||||
apiv2pb.UnimplementedWebhookServiceServer
|
||||
apiv2pb.UnimplementedLinkServiceServer
|
||||
apiv2pb.UnimplementedStorageServiceServer
|
||||
apiv2pb.UnimplementedIdentityProviderServiceServer
|
||||
|
||||
Secret string
|
||||
Profile *profile.Profile
|
||||
@ -70,6 +71,7 @@ func NewAPIV2Service(secret string, profile *profile.Profile, store *store.Store
|
||||
apiv2pb.RegisterWebhookServiceServer(grpcServer, apiv2Service)
|
||||
apiv2pb.RegisterLinkServiceServer(grpcServer, apiv2Service)
|
||||
apiv2pb.RegisterStorageServiceServer(grpcServer, apiv2Service)
|
||||
apiv2pb.RegisterIdentityProviderServiceServer(grpcServer, apiv2Service)
|
||||
reflection.Register(grpcServer)
|
||||
|
||||
return apiv2Service
|
||||
@ -129,6 +131,9 @@ func (s *APIV2Service) RegisterGateway(ctx context.Context, e *echo.Echo) error
|
||||
if err := apiv2pb.RegisterStorageServiceHandler(context.Background(), gwMux, conn); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := apiv2pb.RegisterIdentityProviderServiceHandler(context.Background(), gwMux, conn); err != nil {
|
||||
return err
|
||||
}
|
||||
e.Any("/api/v2/*", echo.WrapHandler(gwMux))
|
||||
|
||||
// GRPC web proxy.
|
||||
|
@ -2,29 +2,18 @@ package mysql
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"strings"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
|
||||
storepb "github.com/usememos/memos/proto/gen/store"
|
||||
"github.com/usememos/memos/store"
|
||||
)
|
||||
|
||||
func (d *DB) CreateIdentityProvider(ctx context.Context, create *store.IdentityProvider) (*store.IdentityProvider, error) {
|
||||
var configBytes []byte
|
||||
if create.Type == store.IdentityProviderOAuth2Type {
|
||||
bytes, err := json.Marshal(create.Config.OAuth2Config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
configBytes = bytes
|
||||
} else {
|
||||
return nil, errors.Errorf("unsupported idp type %s", string(create.Type))
|
||||
}
|
||||
|
||||
placeholders := []string{"?", "?", "?", "?"}
|
||||
fields := []string{"`name`", "`type`", "`identifier_filter`", "`config`"}
|
||||
args := []any{create.Name, create.Type, create.IdentifierFilter, string(configBytes)}
|
||||
args := []any{create.Name, create.Type.String(), create.IdentifierFilter, create.Config}
|
||||
|
||||
stmt := "INSERT INTO `idp` (" + strings.Join(fields, ", ") + ") VALUES (" + strings.Join(placeholders, ", ") + ")"
|
||||
result, err := d.db.ExecContext(ctx, stmt, args...)
|
||||
@ -58,28 +47,17 @@ func (d *DB) ListIdentityProviders(ctx context.Context, find *store.FindIdentity
|
||||
var identityProviders []*store.IdentityProvider
|
||||
for rows.Next() {
|
||||
var identityProvider store.IdentityProvider
|
||||
var identityProviderConfig string
|
||||
var typeString string
|
||||
if err := rows.Scan(
|
||||
&identityProvider.ID,
|
||||
&identityProvider.Name,
|
||||
&identityProvider.Type,
|
||||
&typeString,
|
||||
&identityProvider.IdentifierFilter,
|
||||
&identityProviderConfig,
|
||||
&identityProvider.Config,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if identityProvider.Type == store.IdentityProviderOAuth2Type {
|
||||
oauth2Config := &store.IdentityProviderOAuth2Config{}
|
||||
if err := json.Unmarshal([]byte(identityProviderConfig), oauth2Config); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
identityProvider.Config = &store.IdentityProviderConfig{
|
||||
OAuth2Config: oauth2Config,
|
||||
}
|
||||
} else {
|
||||
return nil, errors.Errorf("unsupported idp type %s", string(identityProvider.Type))
|
||||
}
|
||||
identityProvider.Type = storepb.IdentityProvider_Type(storepb.IdentityProvider_Type_value[typeString])
|
||||
identityProviders = append(identityProviders, &identityProvider)
|
||||
}
|
||||
|
||||
@ -112,17 +90,7 @@ func (d *DB) UpdateIdentityProvider(ctx context.Context, update *store.UpdateIde
|
||||
set, args = append(set, "`identifier_filter` = ?"), append(args, *v)
|
||||
}
|
||||
if v := update.Config; v != nil {
|
||||
var configBytes []byte
|
||||
if update.Type == store.IdentityProviderOAuth2Type {
|
||||
bytes, err := json.Marshal(update.Config.OAuth2Config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
configBytes = bytes
|
||||
} else {
|
||||
return nil, errors.Errorf("unsupported idp type %s", string(update.Type))
|
||||
}
|
||||
set, args = append(set, "`config` = ?"), append(args, string(configBytes))
|
||||
set, args = append(set, "`config` = ?"), append(args, *v)
|
||||
}
|
||||
args = append(args, update.ID)
|
||||
|
||||
|
@ -2,28 +2,15 @@ package postgres
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"strings"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
|
||||
storepb "github.com/usememos/memos/proto/gen/store"
|
||||
"github.com/usememos/memos/store"
|
||||
)
|
||||
|
||||
func (d *DB) CreateIdentityProvider(ctx context.Context, create *store.IdentityProvider) (*store.IdentityProvider, error) {
|
||||
var configBytes []byte
|
||||
if create.Type == store.IdentityProviderOAuth2Type {
|
||||
bytes, err := json.Marshal(create.Config.OAuth2Config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
configBytes = bytes
|
||||
} else {
|
||||
return nil, errors.Errorf("unsupported idp type %s", string(create.Type))
|
||||
}
|
||||
|
||||
fields := []string{"name", "type", "identifier_filter", "config"}
|
||||
args := []any{create.Name, create.Type, create.IdentifierFilter, string(configBytes)}
|
||||
args := []any{create.Name, create.Type.Type(), create.IdentifierFilter, create.Config}
|
||||
stmt := "INSERT INTO idp (" + strings.Join(fields, ", ") + ") VALUES (" + placeholders(len(args)) + ") RETURNING id"
|
||||
if err := d.db.QueryRowContext(ctx, stmt, args...).Scan(&create.ID); err != nil {
|
||||
return nil, err
|
||||
@ -58,28 +45,18 @@ func (d *DB) ListIdentityProviders(ctx context.Context, find *store.FindIdentity
|
||||
var identityProviders []*store.IdentityProvider
|
||||
for rows.Next() {
|
||||
var identityProvider store.IdentityProvider
|
||||
var identityProviderConfig string
|
||||
var typeString string
|
||||
if err := rows.Scan(
|
||||
&identityProvider.ID,
|
||||
&identityProvider.Name,
|
||||
&identityProvider.Type,
|
||||
&typeString,
|
||||
&identityProvider.IdentifierFilter,
|
||||
&identityProviderConfig,
|
||||
&identityProvider.Config,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if identityProvider.Type == store.IdentityProviderOAuth2Type {
|
||||
oauth2Config := &store.IdentityProviderOAuth2Config{}
|
||||
if err := json.Unmarshal([]byte(identityProviderConfig), oauth2Config); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
identityProvider.Config = &store.IdentityProviderConfig{
|
||||
OAuth2Config: oauth2Config,
|
||||
}
|
||||
} else {
|
||||
return nil, errors.Errorf("unsupported idp type %s", string(identityProvider.Type))
|
||||
}
|
||||
identityProvider.Type = storepb.IdentityProvider_Type(storepb.IdentityProvider_Type_value[typeString])
|
||||
identityProviders = append(identityProviders, &identityProvider)
|
||||
}
|
||||
|
||||
@ -90,18 +67,6 @@ func (d *DB) ListIdentityProviders(ctx context.Context, find *store.FindIdentity
|
||||
return identityProviders, nil
|
||||
}
|
||||
|
||||
func (d *DB) GetIdentityProvider(ctx context.Context, find *store.FindIdentityProvider) (*store.IdentityProvider, error) {
|
||||
list, err := d.ListIdentityProviders(ctx, find)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(list) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
return list[0], nil
|
||||
}
|
||||
|
||||
func (d *DB) UpdateIdentityProvider(ctx context.Context, update *store.UpdateIdentityProvider) (*store.IdentityProvider, error) {
|
||||
set, args := []string{}, []any{}
|
||||
if v := update.Name; v != nil {
|
||||
@ -111,17 +76,7 @@ func (d *DB) UpdateIdentityProvider(ctx context.Context, update *store.UpdateIde
|
||||
set, args = append(set, "identifier_filter = "+placeholder(len(args)+1)), append(args, *v)
|
||||
}
|
||||
if v := update.Config; v != nil {
|
||||
var configBytes []byte
|
||||
if update.Type == store.IdentityProviderOAuth2Type {
|
||||
bytes, err := json.Marshal(update.Config.OAuth2Config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
configBytes = bytes
|
||||
} else {
|
||||
return nil, errors.Errorf("unsupported idp type %s", string(update.Type))
|
||||
}
|
||||
set, args = append(set, "config = "+placeholder(len(args)+1)), append(args, string(configBytes))
|
||||
set, args = append(set, "config = "+placeholder(len(args)+1)), append(args, *v)
|
||||
}
|
||||
|
||||
stmt := `
|
||||
@ -133,29 +88,18 @@ func (d *DB) UpdateIdentityProvider(ctx context.Context, update *store.UpdateIde
|
||||
args = append(args, update.ID)
|
||||
|
||||
var identityProvider store.IdentityProvider
|
||||
var identityProviderConfig string
|
||||
var typeString string
|
||||
if err := d.db.QueryRowContext(ctx, stmt, args...).Scan(
|
||||
&identityProvider.ID,
|
||||
&identityProvider.Name,
|
||||
&identityProvider.Type,
|
||||
&typeString,
|
||||
&identityProvider.IdentifierFilter,
|
||||
&identityProviderConfig,
|
||||
&identityProvider.Config,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if identityProvider.Type == store.IdentityProviderOAuth2Type {
|
||||
oauth2Config := &store.IdentityProviderOAuth2Config{}
|
||||
if err := json.Unmarshal([]byte(identityProviderConfig), oauth2Config); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
identityProvider.Config = &store.IdentityProviderConfig{
|
||||
OAuth2Config: oauth2Config,
|
||||
}
|
||||
} else {
|
||||
return nil, errors.Errorf("unsupported idp type %s", string(identityProvider.Type))
|
||||
}
|
||||
|
||||
identityProvider.Type = storepb.IdentityProvider_Type(storepb.IdentityProvider_Type_value[typeString])
|
||||
return &identityProvider, nil
|
||||
}
|
||||
|
||||
|
@ -2,30 +2,17 @@ package sqlite
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
|
||||
storepb "github.com/usememos/memos/proto/gen/store"
|
||||
"github.com/usememos/memos/store"
|
||||
)
|
||||
|
||||
func (d *DB) CreateIdentityProvider(ctx context.Context, create *store.IdentityProvider) (*store.IdentityProvider, error) {
|
||||
var configBytes []byte
|
||||
if create.Type == store.IdentityProviderOAuth2Type {
|
||||
bytes, err := json.Marshal(create.Config.OAuth2Config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
configBytes = bytes
|
||||
} else {
|
||||
return nil, errors.Errorf("unsupported idp type %s", string(create.Type))
|
||||
}
|
||||
|
||||
placeholders := []string{"?", "?", "?", "?"}
|
||||
fields := []string{"`name`", "`type`", "`identifier_filter`", "`config`"}
|
||||
args := []any{create.Name, create.Type, create.IdentifierFilter, string(configBytes)}
|
||||
args := []any{create.Name, create.Type.String(), create.IdentifierFilter, create.Config}
|
||||
|
||||
stmt := "INSERT INTO `idp` (" + strings.Join(fields, ", ") + ") VALUES (" + strings.Join(placeholders, ", ") + ") RETURNING `id`"
|
||||
if err := d.db.QueryRowContext(ctx, stmt, args...).Scan(&create.ID); err != nil {
|
||||
@ -61,28 +48,17 @@ func (d *DB) ListIdentityProviders(ctx context.Context, find *store.FindIdentity
|
||||
var identityProviders []*store.IdentityProvider
|
||||
for rows.Next() {
|
||||
var identityProvider store.IdentityProvider
|
||||
var identityProviderConfig string
|
||||
var typeString string
|
||||
if err := rows.Scan(
|
||||
&identityProvider.ID,
|
||||
&identityProvider.Name,
|
||||
&identityProvider.Type,
|
||||
&typeString,
|
||||
&identityProvider.IdentifierFilter,
|
||||
&identityProviderConfig,
|
||||
&identityProvider.Config,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if identityProvider.Type == store.IdentityProviderOAuth2Type {
|
||||
oauth2Config := &store.IdentityProviderOAuth2Config{}
|
||||
if err := json.Unmarshal([]byte(identityProviderConfig), oauth2Config); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
identityProvider.Config = &store.IdentityProviderConfig{
|
||||
OAuth2Config: oauth2Config,
|
||||
}
|
||||
} else {
|
||||
return nil, errors.Errorf("unsupported idp type %s", string(identityProvider.Type))
|
||||
}
|
||||
identityProvider.Type = storepb.IdentityProvider_Type(storepb.IdentityProvider_Type_value[typeString])
|
||||
identityProviders = append(identityProviders, &identityProvider)
|
||||
}
|
||||
|
||||
@ -102,17 +78,7 @@ func (d *DB) UpdateIdentityProvider(ctx context.Context, update *store.UpdateIde
|
||||
set, args = append(set, "identifier_filter = ?"), append(args, *v)
|
||||
}
|
||||
if v := update.Config; v != nil {
|
||||
var configBytes []byte
|
||||
if update.Type == store.IdentityProviderOAuth2Type {
|
||||
bytes, err := json.Marshal(update.Config.OAuth2Config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
configBytes = bytes
|
||||
} else {
|
||||
return nil, errors.Errorf("unsupported idp type %s", string(update.Type))
|
||||
}
|
||||
set, args = append(set, "config = ?"), append(args, string(configBytes))
|
||||
set, args = append(set, "config = ?"), append(args, *v)
|
||||
}
|
||||
args = append(args, update.ID)
|
||||
|
||||
@ -123,29 +89,17 @@ func (d *DB) UpdateIdentityProvider(ctx context.Context, update *store.UpdateIde
|
||||
RETURNING id, name, type, identifier_filter, config
|
||||
`
|
||||
var identityProvider store.IdentityProvider
|
||||
var identityProviderConfig string
|
||||
var typeString string
|
||||
if err := d.db.QueryRowContext(ctx, stmt, args...).Scan(
|
||||
&identityProvider.ID,
|
||||
&identityProvider.Name,
|
||||
&identityProvider.Type,
|
||||
&typeString,
|
||||
&identityProvider.IdentifierFilter,
|
||||
&identityProviderConfig,
|
||||
&identityProvider.Config,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if identityProvider.Type == store.IdentityProviderOAuth2Type {
|
||||
oauth2Config := &store.IdentityProviderOAuth2Config{}
|
||||
if err := json.Unmarshal([]byte(identityProviderConfig), oauth2Config); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
identityProvider.Config = &store.IdentityProviderConfig{
|
||||
OAuth2Config: oauth2Config,
|
||||
}
|
||||
} else {
|
||||
return nil, errors.Errorf("unsupported idp type %s", string(identityProvider.Type))
|
||||
}
|
||||
|
||||
identityProvider.Type = storepb.IdentityProvider_Type(storepb.IdentityProvider_Type_value[typeString])
|
||||
return &identityProvider, nil
|
||||
}
|
||||
|
||||
|
168
store/idp.go
168
store/idp.go
@ -2,44 +2,19 @@ package store
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"google.golang.org/protobuf/encoding/protojson"
|
||||
|
||||
storepb "github.com/usememos/memos/proto/gen/store"
|
||||
)
|
||||
|
||||
type IdentityProviderType string
|
||||
|
||||
const (
|
||||
IdentityProviderOAuth2Type IdentityProviderType = "OAUTH2"
|
||||
)
|
||||
|
||||
func (t IdentityProviderType) String() string {
|
||||
return string(t)
|
||||
}
|
||||
|
||||
type IdentityProviderConfig struct {
|
||||
OAuth2Config *IdentityProviderOAuth2Config
|
||||
}
|
||||
|
||||
type IdentityProviderOAuth2Config struct {
|
||||
ClientID string `json:"clientId"`
|
||||
ClientSecret string `json:"clientSecret"`
|
||||
AuthURL string `json:"authUrl"`
|
||||
TokenURL string `json:"tokenUrl"`
|
||||
UserInfoURL string `json:"userInfoUrl"`
|
||||
Scopes []string `json:"scopes"`
|
||||
FieldMapping *FieldMapping `json:"fieldMapping"`
|
||||
}
|
||||
|
||||
type FieldMapping struct {
|
||||
Identifier string `json:"identifier"`
|
||||
DisplayName string `json:"displayName"`
|
||||
Email string `json:"email"`
|
||||
}
|
||||
|
||||
type IdentityProvider struct {
|
||||
ID int32
|
||||
Name string
|
||||
Type IdentityProviderType
|
||||
Type storepb.IdentityProvider_Type
|
||||
IdentifierFilter string
|
||||
Config *IdentityProviderConfig
|
||||
Config string
|
||||
}
|
||||
|
||||
type FindIdentityProvider struct {
|
||||
@ -48,64 +23,107 @@ type FindIdentityProvider struct {
|
||||
|
||||
type UpdateIdentityProvider struct {
|
||||
ID int32
|
||||
Type IdentityProviderType
|
||||
Name *string
|
||||
IdentifierFilter *string
|
||||
Config *IdentityProviderConfig
|
||||
Config *string
|
||||
}
|
||||
|
||||
type DeleteIdentityProvider struct {
|
||||
ID int32
|
||||
}
|
||||
|
||||
func (s *Store) CreateIdentityProvider(ctx context.Context, create *IdentityProvider) (*IdentityProvider, error) {
|
||||
identityProvider, err := s.driver.CreateIdentityProvider(ctx, create)
|
||||
func (s *Store) CreateIdentityProviderV1(ctx context.Context, create *storepb.IdentityProvider) (*storepb.IdentityProvider, error) {
|
||||
raw, err := convertIdentityProviderToRaw(create)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
identityProviderRaw, err := s.driver.CreateIdentityProvider(ctx, raw)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
s.idpCache.Store(identityProvider.ID, identityProvider)
|
||||
identityProvider, err := convertIdentityProviderFromRaw(identityProviderRaw)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
s.idpV1Cache.Store(identityProvider.Id, identityProvider)
|
||||
return identityProvider, nil
|
||||
}
|
||||
|
||||
func (s *Store) ListIdentityProviders(ctx context.Context, find *FindIdentityProvider) ([]*IdentityProvider, error) {
|
||||
identityProviders, err := s.driver.ListIdentityProviders(ctx, find)
|
||||
func (s *Store) ListIdentityProvidersV1(ctx context.Context, find *FindIdentityProvider) ([]*storepb.IdentityProvider, error) {
|
||||
list, err := s.driver.ListIdentityProviders(ctx, find)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, item := range identityProviders {
|
||||
s.idpCache.Store(item.ID, item)
|
||||
identityProviders := []*storepb.IdentityProvider{}
|
||||
for _, raw := range list {
|
||||
identityProvider, err := convertIdentityProviderFromRaw(raw)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
s.idpV1Cache.Store(identityProvider.Id, identityProvider)
|
||||
}
|
||||
return identityProviders, nil
|
||||
}
|
||||
|
||||
func (s *Store) GetIdentityProvider(ctx context.Context, find *FindIdentityProvider) (*IdentityProvider, error) {
|
||||
func (s *Store) GetIdentityProviderV1(ctx context.Context, find *FindIdentityProvider) (*storepb.IdentityProvider, error) {
|
||||
if find.ID != nil {
|
||||
if cache, ok := s.idpCache.Load(*find.ID); ok {
|
||||
return cache.(*IdentityProvider), nil
|
||||
if cache, ok := s.idpV1Cache.Load(*find.ID); ok {
|
||||
return cache.(*storepb.IdentityProvider), nil
|
||||
}
|
||||
}
|
||||
|
||||
list, err := s.ListIdentityProviders(ctx, find)
|
||||
list, err := s.ListIdentityProvidersV1(ctx, find)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(list) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
if len(list) > 1 {
|
||||
return nil, errors.Errorf("Found multiple identity providers with ID %d", *find.ID)
|
||||
}
|
||||
|
||||
identityProvider := list[0]
|
||||
return identityProvider, nil
|
||||
}
|
||||
|
||||
func (s *Store) UpdateIdentityProvider(ctx context.Context, update *UpdateIdentityProvider) (*IdentityProvider, error) {
|
||||
identityProvider, err := s.driver.UpdateIdentityProvider(ctx, update)
|
||||
type UpdateIdentityProviderV1 struct {
|
||||
ID int32
|
||||
Type storepb.IdentityProvider_Type
|
||||
Name *string
|
||||
IdentifierFilter *string
|
||||
Config *storepb.IdentityProviderConfig
|
||||
}
|
||||
|
||||
func (s *Store) UpdateIdentityProviderV1(ctx context.Context, update *UpdateIdentityProviderV1) (*storepb.IdentityProvider, error) {
|
||||
updateRaw := &UpdateIdentityProvider{
|
||||
ID: update.ID,
|
||||
}
|
||||
if update.Name != nil {
|
||||
updateRaw.Name = update.Name
|
||||
}
|
||||
if update.IdentifierFilter != nil {
|
||||
updateRaw.IdentifierFilter = update.IdentifierFilter
|
||||
}
|
||||
if update.Config != nil {
|
||||
configRaw, err := convertIdentityProviderConfigToRaw(update.Type, update.Config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
updateRaw.Config = &configRaw
|
||||
}
|
||||
identityProviderRaw, err := s.driver.UpdateIdentityProvider(ctx, updateRaw)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
s.idpCache.Store(identityProvider.ID, identityProvider)
|
||||
identityProvider, err := convertIdentityProviderFromRaw(identityProviderRaw)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
s.idpV1Cache.Store(identityProvider.Id, identityProvider)
|
||||
return identityProvider, nil
|
||||
}
|
||||
|
||||
@ -118,3 +136,57 @@ func (s *Store) DeleteIdentityProvider(ctx context.Context, delete *DeleteIdenti
|
||||
s.idpCache.Delete(delete.ID)
|
||||
return nil
|
||||
}
|
||||
|
||||
func convertIdentityProviderFromRaw(raw *IdentityProvider) (*storepb.IdentityProvider, error) {
|
||||
identityProvider := &storepb.IdentityProvider{
|
||||
Id: raw.ID,
|
||||
Name: raw.Name,
|
||||
Type: raw.Type,
|
||||
IdentifierFilter: raw.IdentifierFilter,
|
||||
}
|
||||
config, err := convertIdentityProviderConfigFromRaw(identityProvider.Type, raw.Config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
identityProvider.Config = config
|
||||
return identityProvider, nil
|
||||
}
|
||||
|
||||
func convertIdentityProviderToRaw(identityProvider *storepb.IdentityProvider) (*IdentityProvider, error) {
|
||||
raw := &IdentityProvider{
|
||||
ID: identityProvider.Id,
|
||||
Name: identityProvider.Name,
|
||||
Type: identityProvider.Type,
|
||||
IdentifierFilter: identityProvider.IdentifierFilter,
|
||||
}
|
||||
configRaw, err := convertIdentityProviderConfigToRaw(identityProvider.Type, identityProvider.Config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
raw.Config = configRaw
|
||||
return raw, nil
|
||||
}
|
||||
|
||||
func convertIdentityProviderConfigFromRaw(identityProviderType storepb.IdentityProvider_Type, raw string) (*storepb.IdentityProviderConfig, error) {
|
||||
config := &storepb.IdentityProviderConfig{}
|
||||
if identityProviderType == storepb.IdentityProvider_OAUTH2 {
|
||||
oauth2Config := &storepb.OAuth2Config{}
|
||||
if err := protojsonUnmarshaler.Unmarshal([]byte(raw), oauth2Config); err != nil {
|
||||
return nil, errors.Wrap(err, "Failed to unmarshal OAuth2Config")
|
||||
}
|
||||
config.Config = &storepb.IdentityProviderConfig_Oauth2Config{Oauth2Config: oauth2Config}
|
||||
}
|
||||
return config, nil
|
||||
}
|
||||
|
||||
func convertIdentityProviderConfigToRaw(identityProviderType storepb.IdentityProvider_Type, config *storepb.IdentityProviderConfig) (string, error) {
|
||||
raw := ""
|
||||
if identityProviderType == storepb.IdentityProvider_OAUTH2 {
|
||||
bytes, err := protojson.Marshal(config.GetOauth2Config())
|
||||
if err != nil {
|
||||
return "", errors.Wrap(err, "Failed to marshal OAuth2Config")
|
||||
}
|
||||
raw = string(bytes)
|
||||
}
|
||||
return raw, nil
|
||||
}
|
||||
|
@ -4,7 +4,7 @@ import (
|
||||
"context"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"google.golang.org/protobuf/proto"
|
||||
"google.golang.org/protobuf/encoding/protojson"
|
||||
|
||||
storepb "github.com/usememos/memos/proto/gen/store"
|
||||
)
|
||||
@ -65,7 +65,7 @@ func (s *Store) CreateStorageV1(ctx context.Context, create *storepb.Storage) (*
|
||||
}
|
||||
|
||||
if create.Type == storepb.Storage_S3 {
|
||||
configBytes, err := proto.Marshal(create.Config.GetS3Config())
|
||||
configBytes, err := protojson.Marshal(create.Config.GetS3Config())
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to marshal s3 config")
|
||||
}
|
||||
@ -174,7 +174,7 @@ func convertStorageConfigFromRaw(storageType storepb.Storage_Type, configRaw str
|
||||
func convertStorageConfigToRaw(storageType storepb.Storage_Type, config *storepb.StorageConfig) (string, error) {
|
||||
raw := ""
|
||||
if storageType == storepb.Storage_S3 {
|
||||
bytes, err := proto.Marshal(config.GetS3Config())
|
||||
bytes, err := protojson.Marshal(config.GetS3Config())
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
@ -11,11 +11,11 @@ import (
|
||||
type Store struct {
|
||||
Profile *profile.Profile
|
||||
driver Driver
|
||||
workspaceSettingCache sync.Map // map[string]*WorkspaceSetting
|
||||
workspaceSettingV1Cache sync.Map // map[string]*storepb.WorkspaceSetting
|
||||
workspaceSettingCache sync.Map // map[string]*storepb.WorkspaceSetting
|
||||
userCache sync.Map // map[int]*User
|
||||
userSettingCache sync.Map // map[string]*UserSetting
|
||||
idpCache sync.Map // map[int]*IdentityProvider
|
||||
idpV1Cache sync.Map // map[int]*storepb.IdentityProvider
|
||||
}
|
||||
|
||||
// New creates a new instance of Store.
|
||||
|
@ -32,20 +32,10 @@ func (s *Store) ListWorkspaceSettings(ctx context.Context, find *FindWorkspaceSe
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, systemSettingMessage := range list {
|
||||
s.workspaceSettingCache.Store(systemSettingMessage.Name, systemSettingMessage)
|
||||
}
|
||||
return list, nil
|
||||
}
|
||||
|
||||
func (s *Store) GetWorkspaceSetting(ctx context.Context, find *FindWorkspaceSetting) (*WorkspaceSetting, error) {
|
||||
if find.Name != "" {
|
||||
if cache, ok := s.workspaceSettingCache.Load(find.Name); ok {
|
||||
return cache.(*WorkspaceSetting), nil
|
||||
}
|
||||
}
|
||||
|
||||
list, err := s.ListWorkspaceSettings(ctx, find)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -56,7 +46,6 @@ func (s *Store) GetWorkspaceSetting(ctx context.Context, find *FindWorkspaceSett
|
||||
}
|
||||
|
||||
systemSettingMessage := list[0]
|
||||
s.workspaceSettingCache.Store(systemSettingMessage.Name, systemSettingMessage)
|
||||
return systemSettingMessage, nil
|
||||
}
|
||||
|
||||
@ -65,7 +54,6 @@ func (s *Store) DeleteWorkspaceSetting(ctx context.Context, delete *DeleteWorksp
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "Failed to delete workspace setting")
|
||||
}
|
||||
s.workspaceSettingCache.Delete(delete.Name)
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -101,7 +89,7 @@ func (s *Store) UpsertWorkspaceSettingV1(ctx context.Context, upsert *storepb.Wo
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "Failed to convert workspace setting")
|
||||
}
|
||||
s.workspaceSettingV1Cache.Store(workspaceSetting.Key.String(), workspaceSetting)
|
||||
s.workspaceSettingCache.Store(workspaceSetting.Key.String(), workspaceSetting)
|
||||
return workspaceSetting, nil
|
||||
}
|
||||
|
||||
@ -117,14 +105,14 @@ func (s *Store) ListWorkspaceSettingsV1(ctx context.Context, find *FindWorkspace
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "Failed to convert workspace setting")
|
||||
}
|
||||
s.workspaceSettingV1Cache.Store(workspaceSetting.Key.String(), workspaceSetting)
|
||||
s.workspaceSettingCache.Store(workspaceSetting.Key.String(), workspaceSetting)
|
||||
workspaceSettings = append(workspaceSettings, workspaceSetting)
|
||||
}
|
||||
return workspaceSettings, nil
|
||||
}
|
||||
|
||||
func (s *Store) GetWorkspaceSettingV1(ctx context.Context, find *FindWorkspaceSetting) (*storepb.WorkspaceSetting, error) {
|
||||
if cache, ok := s.workspaceSettingV1Cache.Load(find.Name); ok {
|
||||
if cache, ok := s.workspaceSettingCache.Load(find.Name); ok {
|
||||
return cache.(*storepb.WorkspaceSetting), nil
|
||||
}
|
||||
|
||||
|
@ -6,51 +6,54 @@ import (
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
storepb "github.com/usememos/memos/proto/gen/store"
|
||||
"github.com/usememos/memos/store"
|
||||
)
|
||||
|
||||
func TestIdentityProviderStore(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
ts := NewTestingStore(ctx, t)
|
||||
createdIDP, err := ts.CreateIdentityProvider(ctx, &store.IdentityProvider{
|
||||
createdIDP, err := ts.CreateIdentityProviderV1(ctx, &storepb.IdentityProvider{
|
||||
Name: "GitHub OAuth",
|
||||
Type: store.IdentityProviderOAuth2Type,
|
||||
Type: storepb.IdentityProvider_OAUTH2,
|
||||
IdentifierFilter: "",
|
||||
Config: &store.IdentityProviderConfig{
|
||||
OAuth2Config: &store.IdentityProviderOAuth2Config{
|
||||
ClientID: "client_id",
|
||||
Config: &storepb.IdentityProviderConfig{
|
||||
Config: &storepb.IdentityProviderConfig_Oauth2Config{
|
||||
Oauth2Config: &storepb.OAuth2Config{
|
||||
ClientId: "client_id",
|
||||
ClientSecret: "client_secret",
|
||||
AuthURL: "https://github.com/auth",
|
||||
TokenURL: "https://github.com/token",
|
||||
UserInfoURL: "https://github.com/user",
|
||||
AuthUrl: "https://github.com/auth",
|
||||
TokenUrl: "https://github.com/token",
|
||||
UserInfoUrl: "https://github.com/user",
|
||||
Scopes: []string{"login"},
|
||||
FieldMapping: &store.FieldMapping{
|
||||
FieldMapping: &storepb.FieldMapping{
|
||||
Identifier: "login",
|
||||
DisplayName: "name",
|
||||
Email: "emai",
|
||||
Email: "email",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
require.NoError(t, err)
|
||||
idp, err := ts.GetIdentityProvider(ctx, &store.FindIdentityProvider{
|
||||
ID: &createdIDP.ID,
|
||||
idp, err := ts.GetIdentityProviderV1(ctx, &store.FindIdentityProvider{
|
||||
ID: &createdIDP.Id,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, idp)
|
||||
require.Equal(t, createdIDP, idp)
|
||||
newName := "My GitHub OAuth"
|
||||
updatedIdp, err := ts.UpdateIdentityProvider(ctx, &store.UpdateIdentityProvider{
|
||||
ID: idp.ID,
|
||||
updatedIdp, err := ts.UpdateIdentityProviderV1(ctx, &store.UpdateIdentityProviderV1{
|
||||
ID: idp.Id,
|
||||
Name: &newName,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, newName, updatedIdp.Name)
|
||||
err = ts.DeleteIdentityProvider(ctx, &store.DeleteIdentityProvider{
|
||||
ID: idp.ID,
|
||||
ID: idp.Id,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
idpList, err := ts.ListIdentityProviders(ctx, &store.FindIdentityProvider{})
|
||||
idpList, err := ts.ListIdentityProvidersV1(ctx, &store.FindIdentityProvider{})
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, 0, len(idpList))
|
||||
ts.Close()
|
||||
|
@ -14,7 +14,6 @@
|
||||
"@matejmazur/react-katex": "^3.1.3",
|
||||
"@mui/joy": "5.0.0-beta.32",
|
||||
"@reduxjs/toolkit": "^2.2.3",
|
||||
"axios": "^1.6.8",
|
||||
"classnames": "^2.5.1",
|
||||
"copy-to-clipboard": "^3.3.3",
|
||||
"fuse.js": "^7.0.0",
|
||||
|
@ -23,9 +23,6 @@ dependencies:
|
||||
'@reduxjs/toolkit':
|
||||
specifier: ^2.2.3
|
||||
version: 2.2.3(react-redux@9.1.0)(react@18.2.0)
|
||||
axios:
|
||||
specifier: ^1.6.8
|
||||
version: 1.6.8
|
||||
classnames:
|
||||
specifier: ^2.5.1
|
||||
version: 2.5.1
|
||||
@ -2048,10 +2045,6 @@ packages:
|
||||
is-shared-array-buffer: 1.0.3
|
||||
dev: true
|
||||
|
||||
/asynckit@0.4.0:
|
||||
resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==}
|
||||
dev: false
|
||||
|
||||
/autoprefixer@10.4.19(postcss@8.4.38):
|
||||
resolution: {integrity: sha512-BaENR2+zBZ8xXhM4pUaKUxlVdxZ0EZhjvbopwnXmxRUfqDmwSpC2lAi/QXvx7NRdPCo1WKEcEF6mV64si1z4Ew==}
|
||||
engines: {node: ^10 || ^12 || >=14}
|
||||
@ -2075,16 +2068,6 @@ packages:
|
||||
possible-typed-array-names: 1.0.0
|
||||
dev: true
|
||||
|
||||
/axios@1.6.8:
|
||||
resolution: {integrity: sha512-v/ZHtJDU39mDpyBoFVkETcd/uNdxrWRrg3bKpOKzXFA6Bvqopts6ALSMU3y6ijYxbw2B+wPrIv46egTzJXCLGQ==}
|
||||
dependencies:
|
||||
follow-redirects: 1.15.6
|
||||
form-data: 4.0.0
|
||||
proxy-from-env: 1.1.0
|
||||
transitivePeerDependencies:
|
||||
- debug
|
||||
dev: false
|
||||
|
||||
/babel-plugin-macros@3.1.0:
|
||||
resolution: {integrity: sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==}
|
||||
engines: {node: '>=10', npm: '>=6'}
|
||||
@ -2216,13 +2199,6 @@ packages:
|
||||
/color-name@1.1.4:
|
||||
resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==}
|
||||
|
||||
/combined-stream@1.0.8:
|
||||
resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==}
|
||||
engines: {node: '>= 0.8'}
|
||||
dependencies:
|
||||
delayed-stream: 1.0.0
|
||||
dev: false
|
||||
|
||||
/commander@4.1.1:
|
||||
resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==}
|
||||
engines: {node: '>= 6'}
|
||||
@ -2681,11 +2657,6 @@ packages:
|
||||
robust-predicates: 3.0.2
|
||||
dev: false
|
||||
|
||||
/delayed-stream@1.0.0:
|
||||
resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==}
|
||||
engines: {node: '>=0.4.0'}
|
||||
dev: false
|
||||
|
||||
/dequal@2.0.3:
|
||||
resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==}
|
||||
engines: {node: '>=6'}
|
||||
@ -3159,16 +3130,6 @@ packages:
|
||||
resolution: {integrity: sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==}
|
||||
dev: true
|
||||
|
||||
/follow-redirects@1.15.6:
|
||||
resolution: {integrity: sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==}
|
||||
engines: {node: '>=4.0'}
|
||||
peerDependencies:
|
||||
debug: '*'
|
||||
peerDependenciesMeta:
|
||||
debug:
|
||||
optional: true
|
||||
dev: false
|
||||
|
||||
/for-each@0.3.3:
|
||||
resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==}
|
||||
dependencies:
|
||||
@ -3183,15 +3144,6 @@ packages:
|
||||
signal-exit: 4.1.0
|
||||
dev: false
|
||||
|
||||
/form-data@4.0.0:
|
||||
resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==}
|
||||
engines: {node: '>= 6'}
|
||||
dependencies:
|
||||
asynckit: 0.4.0
|
||||
combined-stream: 1.0.8
|
||||
mime-types: 2.1.35
|
||||
dev: false
|
||||
|
||||
/fraction.js@4.3.7:
|
||||
resolution: {integrity: sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==}
|
||||
dev: true
|
||||
@ -4142,18 +4094,6 @@ packages:
|
||||
braces: 3.0.2
|
||||
picomatch: 2.3.1
|
||||
|
||||
/mime-db@1.52.0:
|
||||
resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==}
|
||||
engines: {node: '>= 0.6'}
|
||||
dev: false
|
||||
|
||||
/mime-types@2.1.35:
|
||||
resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==}
|
||||
engines: {node: '>= 0.6'}
|
||||
dependencies:
|
||||
mime-db: 1.52.0
|
||||
dev: false
|
||||
|
||||
/mime@1.6.0:
|
||||
resolution: {integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==}
|
||||
engines: {node: '>=4'}
|
||||
@ -4564,10 +4504,6 @@ packages:
|
||||
long: 5.2.3
|
||||
dev: true
|
||||
|
||||
/proxy-from-env@1.1.0:
|
||||
resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==}
|
||||
dev: false
|
||||
|
||||
/prr@1.0.1:
|
||||
resolution: {integrity: sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==}
|
||||
requiresBuild: true
|
||||
|
@ -1,18 +1,18 @@
|
||||
import { Button, Divider, IconButton, Input, Option, Select, Typography } from "@mui/joy";
|
||||
import { useEffect, useState } from "react";
|
||||
import { toast } from "react-hot-toast";
|
||||
import * as api from "@/helpers/api";
|
||||
import { UNKNOWN_ID } from "@/helpers/consts";
|
||||
import { identityProviderServiceClient } from "@/grpcweb";
|
||||
import { absolutifyLink } from "@/helpers/utils";
|
||||
import { FieldMapping, IdentityProvider, IdentityProvider_Type, OAuth2Config } from "@/types/proto/api/v2/idp_service";
|
||||
import { useTranslate } from "@/utils/i18n";
|
||||
import { generateDialog } from "./Dialog";
|
||||
import Icon from "./Icon";
|
||||
|
||||
const templateList: IdentityProvider[] = [
|
||||
{
|
||||
id: UNKNOWN_ID,
|
||||
name: "GitHub",
|
||||
type: "OAUTH2",
|
||||
name: "",
|
||||
title: "GitHub",
|
||||
type: IdentityProvider_Type.OAUTH2,
|
||||
identifierFilter: "",
|
||||
config: {
|
||||
oauth2Config: {
|
||||
@ -31,9 +31,9 @@ const templateList: IdentityProvider[] = [
|
||||
},
|
||||
},
|
||||
{
|
||||
id: UNKNOWN_ID,
|
||||
name: "GitLab",
|
||||
type: "OAUTH2",
|
||||
name: "",
|
||||
title: "GitLab",
|
||||
type: IdentityProvider_Type.OAUTH2,
|
||||
identifierFilter: "",
|
||||
config: {
|
||||
oauth2Config: {
|
||||
@ -52,9 +52,9 @@ const templateList: IdentityProvider[] = [
|
||||
},
|
||||
},
|
||||
{
|
||||
id: UNKNOWN_ID,
|
||||
name: "Google",
|
||||
type: "OAUTH2",
|
||||
name: "",
|
||||
title: "Google",
|
||||
type: IdentityProvider_Type.OAUTH2,
|
||||
identifierFilter: "",
|
||||
config: {
|
||||
oauth2Config: {
|
||||
@ -73,9 +73,9 @@ const templateList: IdentityProvider[] = [
|
||||
},
|
||||
},
|
||||
{
|
||||
id: UNKNOWN_ID,
|
||||
name: "Custom",
|
||||
type: "OAUTH2",
|
||||
name: "",
|
||||
title: "Custom",
|
||||
type: IdentityProvider_Type.OAUTH2,
|
||||
identifierFilter: "",
|
||||
config: {
|
||||
oauth2Config: {
|
||||
@ -108,8 +108,8 @@ const CreateIdentityProviderDialog: React.FC<Props> = (props: Props) => {
|
||||
name: "",
|
||||
identifierFilter: "",
|
||||
});
|
||||
const [type, setType] = useState<IdentityProviderType>("OAUTH2");
|
||||
const [oauth2Config, setOAuth2Config] = useState<IdentityProviderOAuth2Config>({
|
||||
const [type, setType] = useState<IdentityProvider_Type>(IdentityProvider_Type.OAUTH2);
|
||||
const [oauth2Config, setOAuth2Config] = useState<OAuth2Config>({
|
||||
clientId: "",
|
||||
clientSecret: "",
|
||||
authUrl: "",
|
||||
@ -133,9 +133,10 @@ const CreateIdentityProviderDialog: React.FC<Props> = (props: Props) => {
|
||||
identifierFilter: identityProvider.identifierFilter,
|
||||
});
|
||||
setType(identityProvider.type);
|
||||
if (identityProvider.type === "OAUTH2") {
|
||||
setOAuth2Config(identityProvider.config.oauth2Config);
|
||||
setOAuth2Scopes(identityProvider.config.oauth2Config.scopes.join(" "));
|
||||
if (identityProvider.type === IdentityProvider_Type.OAUTH2) {
|
||||
const oauth2Config = OAuth2Config.fromPartial(identityProvider.config?.oauth2Config || {});
|
||||
setOAuth2Config(oauth2Config);
|
||||
setOAuth2Scopes(oauth2Config.scopes.join(" "));
|
||||
}
|
||||
}
|
||||
}, []);
|
||||
@ -145,16 +146,17 @@ const CreateIdentityProviderDialog: React.FC<Props> = (props: Props) => {
|
||||
return;
|
||||
}
|
||||
|
||||
const template = templateList.find((t) => t.name === selectedTemplate);
|
||||
const template = templateList.find((t) => t.title === selectedTemplate);
|
||||
if (template) {
|
||||
setBasicInfo({
|
||||
name: template.name,
|
||||
identifierFilter: template.identifierFilter,
|
||||
});
|
||||
setType(template.type);
|
||||
if (template.type === "OAUTH2") {
|
||||
setOAuth2Config(template.config.oauth2Config);
|
||||
setOAuth2Scopes(template.config.oauth2Config.scopes.join(" "));
|
||||
if (template.type === IdentityProvider_Type.OAUTH2) {
|
||||
const oauth2Config = OAuth2Config.fromPartial(template.config?.oauth2Config || {});
|
||||
setOAuth2Config(oauth2Config);
|
||||
setOAuth2Scopes(oauth2Config.scopes.join(" "));
|
||||
}
|
||||
}
|
||||
}, [selectedTemplate]);
|
||||
@ -174,7 +176,7 @@ const CreateIdentityProviderDialog: React.FC<Props> = (props: Props) => {
|
||||
oauth2Config.tokenUrl === "" ||
|
||||
oauth2Config.userInfoUrl === "" ||
|
||||
oauth2Scopes === "" ||
|
||||
oauth2Config.fieldMapping.identifier === ""
|
||||
oauth2Config.fieldMapping?.identifier === ""
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
@ -191,7 +193,8 @@ const CreateIdentityProviderDialog: React.FC<Props> = (props: Props) => {
|
||||
const handleConfirmBtnClick = async () => {
|
||||
try {
|
||||
if (isCreating) {
|
||||
await api.createIdentityProvider({
|
||||
await identityProviderServiceClient.createIdentityProvider({
|
||||
identityProvider: {
|
||||
...basicInfo,
|
||||
type: type,
|
||||
config: {
|
||||
@ -200,19 +203,22 @@ const CreateIdentityProviderDialog: React.FC<Props> = (props: Props) => {
|
||||
scopes: oauth2Scopes.split(" "),
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
toast.success(t("setting.sso-section.sso-created", { name: basicInfo.name }));
|
||||
} else {
|
||||
await api.patchIdentityProvider({
|
||||
id: identityProvider.id,
|
||||
type: type,
|
||||
await identityProviderServiceClient.updateIdentityProvider({
|
||||
identityProvider: {
|
||||
...basicInfo,
|
||||
type: type,
|
||||
config: {
|
||||
oauth2Config: {
|
||||
...oauth2Config,
|
||||
scopes: oauth2Scopes.split(" "),
|
||||
},
|
||||
},
|
||||
},
|
||||
updateMask: ["title", "identifierFilter", "config"],
|
||||
});
|
||||
toast.success(t("setting.sso-section.sso-updated", { name: basicInfo.name }));
|
||||
}
|
||||
@ -226,7 +232,7 @@ const CreateIdentityProviderDialog: React.FC<Props> = (props: Props) => {
|
||||
destroy();
|
||||
};
|
||||
|
||||
const setPartialOAuth2Config = (state: Partial<IdentityProviderOAuth2Config>) => {
|
||||
const setPartialOAuth2Config = (state: Partial<OAuth2Config>) => {
|
||||
setOAuth2Config({
|
||||
...oauth2Config,
|
||||
...state,
|
||||
@ -259,8 +265,8 @@ const CreateIdentityProviderDialog: React.FC<Props> = (props: Props) => {
|
||||
</Typography>
|
||||
<Select className="mb-1 h-auto w-full" value={selectedTemplate} onChange={(_, e) => setSelectedTemplate(e ?? selectedTemplate)}>
|
||||
{templateList.map((template) => (
|
||||
<Option key={template.name} value={template.name}>
|
||||
{template.name}
|
||||
<Option key={template.title} value={template.title}>
|
||||
{template.title}
|
||||
</Option>
|
||||
))}
|
||||
</Select>
|
||||
@ -380,8 +386,10 @@ const CreateIdentityProviderDialog: React.FC<Props> = (props: Props) => {
|
||||
<Input
|
||||
className="mb-2"
|
||||
placeholder={t("setting.sso-section.identifier")}
|
||||
value={oauth2Config.fieldMapping.identifier}
|
||||
onChange={(e) => setPartialOAuth2Config({ fieldMapping: { ...oauth2Config.fieldMapping, identifier: e.target.value } })}
|
||||
value={oauth2Config.fieldMapping!.identifier}
|
||||
onChange={(e) =>
|
||||
setPartialOAuth2Config({ fieldMapping: { ...oauth2Config.fieldMapping, identifier: e.target.value } as FieldMapping })
|
||||
}
|
||||
fullWidth
|
||||
/>
|
||||
<Typography className="!mb-1" level="body-md">
|
||||
@ -390,8 +398,10 @@ const CreateIdentityProviderDialog: React.FC<Props> = (props: Props) => {
|
||||
<Input
|
||||
className="mb-2"
|
||||
placeholder={t("setting.sso-section.display-name")}
|
||||
value={oauth2Config.fieldMapping.displayName}
|
||||
onChange={(e) => setPartialOAuth2Config({ fieldMapping: { ...oauth2Config.fieldMapping, displayName: e.target.value } })}
|
||||
value={oauth2Config.fieldMapping!.displayName}
|
||||
onChange={(e) =>
|
||||
setPartialOAuth2Config({ fieldMapping: { ...oauth2Config.fieldMapping, displayName: e.target.value } as FieldMapping })
|
||||
}
|
||||
fullWidth
|
||||
/>
|
||||
<Typography className="!mb-1" level="body-md">
|
||||
@ -400,8 +410,10 @@ const CreateIdentityProviderDialog: React.FC<Props> = (props: Props) => {
|
||||
<Input
|
||||
className="mb-2"
|
||||
placeholder={t("common.email")}
|
||||
value={oauth2Config.fieldMapping.email}
|
||||
onChange={(e) => setPartialOAuth2Config({ fieldMapping: { ...oauth2Config.fieldMapping, email: e.target.value } })}
|
||||
value={oauth2Config.fieldMapping!.email}
|
||||
onChange={(e) =>
|
||||
setPartialOAuth2Config({ fieldMapping: { ...oauth2Config.fieldMapping, email: e.target.value } as FieldMapping })
|
||||
}
|
||||
fullWidth
|
||||
/>
|
||||
</>
|
||||
|
@ -2,7 +2,8 @@ import { Button, Divider, Dropdown, List, ListItem, Menu, MenuButton, MenuItem }
|
||||
import { useEffect, useState } from "react";
|
||||
import { toast } from "react-hot-toast";
|
||||
import { Link } from "react-router-dom";
|
||||
import * as api from "@/helpers/api";
|
||||
import { identityProviderServiceClient } from "@/grpcweb";
|
||||
import { IdentityProvider } from "@/types/proto/api/v2/idp_service";
|
||||
import { useTranslate } from "@/utils/i18n";
|
||||
import showCreateIdentityProviderDialog from "../CreateIdentityProviderDialog";
|
||||
import { showCommonDialog } from "../Dialog/CommonDialog";
|
||||
@ -18,8 +19,8 @@ const SSOSection = () => {
|
||||
}, []);
|
||||
|
||||
const fetchIdentityProviderList = async () => {
|
||||
const { data: identityProviderList } = await api.getIdentityProviderList();
|
||||
setIdentityProviderList(identityProviderList);
|
||||
const { identityProviders } = await identityProviderServiceClient.listIdentityProviders({});
|
||||
setIdentityProviderList(identityProviders);
|
||||
};
|
||||
|
||||
const handleDeleteIdentityProvider = async (identityProvider: IdentityProvider) => {
|
||||
@ -32,10 +33,10 @@ const SSOSection = () => {
|
||||
dialogName: "delete-identity-provider-dialog",
|
||||
onConfirm: async () => {
|
||||
try {
|
||||
await api.deleteIdentityProvider(identityProvider.id);
|
||||
await identityProviderServiceClient.deleteIdentityProvider({ name: identityProvider.name });
|
||||
} catch (error: any) {
|
||||
console.error(error);
|
||||
toast.error(error.response.data.message);
|
||||
toast.error(error.details);
|
||||
}
|
||||
await fetchIdentityProviderList();
|
||||
},
|
||||
@ -54,12 +55,12 @@ const SSOSection = () => {
|
||||
<Divider />
|
||||
{identityProviderList.map((identityProvider) => (
|
||||
<div
|
||||
key={identityProvider.id}
|
||||
key={identityProvider.name}
|
||||
className="py-2 w-full border-b last:border-b dark:border-zinc-700 flex flex-row items-center justify-between"
|
||||
>
|
||||
<div className="flex flex-row items-center">
|
||||
<p className="ml-2">
|
||||
{identityProvider.name}
|
||||
{identityProvider.title}
|
||||
<span className="text-sm ml-1 opacity-40">({identityProvider.type})</span>
|
||||
</p>
|
||||
</div>
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { createChannel, createClientFactory, FetchTransport } from "nice-grpc-web";
|
||||
import { ActivityServiceDefinition } from "./types/proto/api/v2/activity_service";
|
||||
import { AuthServiceDefinition } from "./types/proto/api/v2/auth_service";
|
||||
import { IdentityProviderServiceDefinition } from "./types/proto/api/v2/idp_service";
|
||||
import { InboxServiceDefinition } from "./types/proto/api/v2/inbox_service";
|
||||
import { LinkServiceDefinition } from "./types/proto/api/v2/link_service";
|
||||
import { MemoServiceDefinition } from "./types/proto/api/v2/memo_service";
|
||||
@ -44,3 +45,5 @@ export const webhookServiceClient = clientFactory.create(WebhookServiceDefinitio
|
||||
export const linkServiceClient = clientFactory.create(LinkServiceDefinition, channel);
|
||||
|
||||
export const storageServiceClient = clientFactory.create(StorageServiceDefinition, channel);
|
||||
|
||||
export const identityProviderServiceClient = clientFactory.create(IdentityProviderServiceDefinition, channel);
|
||||
|
@ -1,20 +0,0 @@
|
||||
import axios from "axios";
|
||||
|
||||
axios.defaults.baseURL = import.meta.env.VITE_API_BASE_URL || "";
|
||||
axios.defaults.withCredentials = true;
|
||||
|
||||
export function getIdentityProviderList() {
|
||||
return axios.get<IdentityProvider[]>(`/api/v1/idp`);
|
||||
}
|
||||
|
||||
export function createIdentityProvider(identityProviderCreate: IdentityProviderCreate) {
|
||||
return axios.post<IdentityProvider>(`/api/v1/idp`, identityProviderCreate);
|
||||
}
|
||||
|
||||
export function patchIdentityProvider(identityProviderPatch: IdentityProviderPatch) {
|
||||
return axios.patch<IdentityProvider>(`/api/v1/idp/${identityProviderPatch.id}`, identityProviderPatch);
|
||||
}
|
||||
|
||||
export function deleteIdentityProvider(id: IdentityProviderId) {
|
||||
return axios.delete(`/api/v1/idp/${id}`);
|
||||
}
|
@ -5,13 +5,13 @@ import { toast } from "react-hot-toast";
|
||||
import { Link } from "react-router-dom";
|
||||
import AppearanceSelect from "@/components/AppearanceSelect";
|
||||
import LocaleSelect from "@/components/LocaleSelect";
|
||||
import { authServiceClient } from "@/grpcweb";
|
||||
import * as api from "@/helpers/api";
|
||||
import { authServiceClient, identityProviderServiceClient } from "@/grpcweb";
|
||||
import { absolutifyLink } from "@/helpers/utils";
|
||||
import useLoading from "@/hooks/useLoading";
|
||||
import useNavigateTo from "@/hooks/useNavigateTo";
|
||||
import { useCommonContext } from "@/layouts/CommonContextProvider";
|
||||
import { useUserStore, useWorkspaceSettingStore } from "@/store/v1";
|
||||
import { extractIdentityProviderIdFromName, useUserStore, useWorkspaceSettingStore } from "@/store/v1";
|
||||
import { IdentityProvider, IdentityProvider_Type } from "@/types/proto/api/v2/idp_service";
|
||||
import { WorkspaceGeneralSetting } from "@/types/proto/api/v2/workspace_setting_service";
|
||||
import { WorkspaceSettingKey } from "@/types/proto/store/workspace_setting";
|
||||
import { useTranslate } from "@/utils/i18n";
|
||||
@ -33,8 +33,8 @@ const SignIn = () => {
|
||||
|
||||
useEffect(() => {
|
||||
const fetchIdentityProviderList = async () => {
|
||||
const { data: identityProviderList } = await api.getIdentityProviderList();
|
||||
setIdentityProviderList(identityProviderList);
|
||||
const { identityProviders } = await identityProviderServiceClient.listIdentityProviders({});
|
||||
setIdentityProviderList(identityProviders);
|
||||
};
|
||||
fetchIdentityProviderList();
|
||||
}, []);
|
||||
@ -95,10 +95,14 @@ const SignIn = () => {
|
||||
};
|
||||
|
||||
const handleSignInWithIdentityProvider = async (identityProvider: IdentityProvider) => {
|
||||
const stateQueryParameter = `auth.signin.${identityProvider.name}-${identityProvider.id}`;
|
||||
if (identityProvider.type === "OAUTH2") {
|
||||
const stateQueryParameter = `auth.signin.${identityProvider.title}-${extractIdentityProviderIdFromName(identityProvider.name)}`;
|
||||
if (identityProvider.type === IdentityProvider_Type.OAUTH2) {
|
||||
const redirectUri = absolutifyLink("/auth/callback");
|
||||
const oauth2Config = identityProvider.config.oauth2Config;
|
||||
const oauth2Config = identityProvider.config?.oauth2Config;
|
||||
if (!oauth2Config) {
|
||||
toast.error("Identity provider configuration is invalid.");
|
||||
return;
|
||||
}
|
||||
const authUrl = `${oauth2Config.authUrl}?client_id=${
|
||||
oauth2Config.clientId
|
||||
}&redirect_uri=${redirectUri}&state=${stateQueryParameter}&response_type=code&scope=${encodeURIComponent(
|
||||
@ -185,7 +189,7 @@ const SignIn = () => {
|
||||
<div className="w-full flex flex-col space-y-2">
|
||||
{identityProviderList.map((identityProvider) => (
|
||||
<Button
|
||||
key={identityProvider.id}
|
||||
key={identityProvider.name}
|
||||
variant="outlined"
|
||||
color="neutral"
|
||||
className="w-full"
|
||||
|
@ -1,7 +1,12 @@
|
||||
export const WorkspaceSettingPrefix = "settings/";
|
||||
export const UserNamePrefix = "users/";
|
||||
export const MemoNamePrefix = "memos/";
|
||||
export const IdentityProviderNamePrefix = "identityProviders/";
|
||||
|
||||
export const extractMemoIdFromName = (name: string) => {
|
||||
return parseInt(name.split(MemoNamePrefix).pop() || "", 10);
|
||||
};
|
||||
|
||||
export const extractIdentityProviderIdFromName = (name: string) => {
|
||||
return parseInt(name.split(IdentityProviderNamePrefix).pop() || "", 10);
|
||||
};
|
||||
|
46
web/src/types/modules/idp.d.ts
vendored
46
web/src/types/modules/idp.d.ts
vendored
@ -1,46 +0,0 @@
|
||||
type IdentityProviderId = number;
|
||||
|
||||
type IdentityProviderType = "OAUTH2";
|
||||
|
||||
interface FieldMapping {
|
||||
identifier: string;
|
||||
displayName: string;
|
||||
email: string;
|
||||
}
|
||||
|
||||
interface IdentityProviderOAuth2Config {
|
||||
clientId: string;
|
||||
clientSecret: string;
|
||||
authUrl: string;
|
||||
tokenUrl: string;
|
||||
userInfoUrl: string;
|
||||
scopes: string[];
|
||||
fieldMapping: FieldMapping;
|
||||
}
|
||||
|
||||
interface IdentityProviderConfig {
|
||||
oauth2Config: IdentityProviderOAuth2Config;
|
||||
}
|
||||
|
||||
interface IdentityProvider {
|
||||
id: IdentityProviderId;
|
||||
name: string;
|
||||
type: IdentityProviderType;
|
||||
identifierFilter: string;
|
||||
config: IdentityProviderConfig;
|
||||
}
|
||||
|
||||
interface IdentityProviderCreate {
|
||||
name: string;
|
||||
type: IdentityProviderType;
|
||||
identifierFilter: string;
|
||||
config: IdentityProviderConfig;
|
||||
}
|
||||
|
||||
interface IdentityProviderPatch {
|
||||
id: IdentityProviderId;
|
||||
type: IdentityProviderType;
|
||||
name?: string;
|
||||
identifierFilter?: string;
|
||||
config?: IdentityProviderConfig;
|
||||
}
|
Loading…
Reference in New Issue
Block a user