mirror of
https://github.com/aykhans/slash-e.git
synced 2025-04-20 22:07:15 +00:00
chore: update oauth2 plugin
This commit is contained in:
parent
e53ced8996
commit
89d1812c07
1
go.mod
1
go.mod
@ -75,6 +75,7 @@ require (
|
|||||||
github.com/posthog/posthog-go v0.0.0-20240327112532-87b23fe11103
|
github.com/posthog/posthog-go v0.0.0-20240327112532-87b23fe11103
|
||||||
golang.org/x/exp v0.0.0-20240409090435-93d18d7e34b8
|
golang.org/x/exp v0.0.0-20240409090435-93d18d7e34b8
|
||||||
golang.org/x/mod v0.19.0
|
golang.org/x/mod v0.19.0
|
||||||
|
golang.org/x/oauth2 v0.22.0
|
||||||
google.golang.org/genproto/googleapis/api v0.0.0-20240723171418-e6d459c13d2a
|
google.golang.org/genproto/googleapis/api v0.0.0-20240723171418-e6d459c13d2a
|
||||||
google.golang.org/grpc v1.65.0
|
google.golang.org/grpc v1.65.0
|
||||||
google.golang.org/protobuf v1.34.2
|
google.golang.org/protobuf v1.34.2
|
||||||
|
2
go.sum
2
go.sum
@ -449,6 +449,8 @@ golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ=
|
|||||||
golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE=
|
golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE=
|
||||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||||
|
golang.org/x/oauth2 v0.22.0 h1:BzDx2FehcG7jJwgWLELCdmLuxk2i+x9UDpSiss2u0ZA=
|
||||||
|
golang.org/x/oauth2 v0.22.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
|
||||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
7
plugin/idp/idp.go
Normal file
7
plugin/idp/idp.go
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
package idp
|
||||||
|
|
||||||
|
type IdentityProviderUserInfo struct {
|
||||||
|
Identifier string
|
||||||
|
Email string
|
||||||
|
DisplayName string
|
||||||
|
}
|
117
plugin/idp/oauth2/oauth2.go
Normal file
117
plugin/idp/oauth2/oauth2.go
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
// Package oauth2 is the plugin for OAuth2 Identity Provider.
|
||||||
|
package oauth2
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
"golang.org/x/oauth2"
|
||||||
|
|
||||||
|
"github.com/yourselfhosted/slash/plugin/idp"
|
||||||
|
storepb "github.com/yourselfhosted/slash/proto/gen/store"
|
||||||
|
)
|
||||||
|
|
||||||
|
// IdentityProvider represents an OAuth2 Identity Provider.
|
||||||
|
type IdentityProvider struct {
|
||||||
|
config *storepb.IdentityProviderConfig_OAuth2Config
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewIdentityProvider initializes a new OAuth2 Identity Provider with the given configuration.
|
||||||
|
func NewIdentityProvider(config *storepb.IdentityProviderConfig_OAuth2Config) (*IdentityProvider, error) {
|
||||||
|
for v, field := range map[string]string{
|
||||||
|
config.ClientId: "clientId",
|
||||||
|
config.ClientSecret: "clientSecret",
|
||||||
|
config.TokenUrl: "tokenUrl",
|
||||||
|
config.UserInfoUrl: "userInfoUrl",
|
||||||
|
config.FieldMapping.Identifier: "fieldMapping.identifier",
|
||||||
|
} {
|
||||||
|
if v == "" {
|
||||||
|
return nil, errors.Errorf(`the field "%s" is empty but required`, field)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return &IdentityProvider{
|
||||||
|
config: config,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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,
|
||||||
|
ClientSecret: p.config.ClientSecret,
|
||||||
|
RedirectURL: redirectURL,
|
||||||
|
Scopes: p.config.Scopes,
|
||||||
|
Endpoint: oauth2.Endpoint{
|
||||||
|
AuthURL: p.config.AuthUrl,
|
||||||
|
TokenURL: p.config.TokenUrl,
|
||||||
|
AuthStyle: oauth2.AuthStyleInParams,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
token, err := conf.Exchange(ctx, code)
|
||||||
|
if err != nil {
|
||||||
|
return "", errors.Wrap(err, "failed to exchange access token")
|
||||||
|
}
|
||||||
|
|
||||||
|
accessToken, ok := token.Extra("access_token").(string)
|
||||||
|
if !ok {
|
||||||
|
return "", errors.New(`missing "access_token" from authorization response`)
|
||||||
|
}
|
||||||
|
|
||||||
|
return accessToken, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "failed to new http request")
|
||||||
|
}
|
||||||
|
req.Header.Set("Content-Type", "application/json")
|
||||||
|
req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", token))
|
||||||
|
resp, err := client.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "failed to get user information")
|
||||||
|
}
|
||||||
|
body, err := io.ReadAll(resp.Body)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "failed to read response body")
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
var claims map[string]any
|
||||||
|
err = json.Unmarshal(body, &claims)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "failed to unmarshal response body")
|
||||||
|
}
|
||||||
|
|
||||||
|
userInfo := &idp.IdentityProviderUserInfo{}
|
||||||
|
if v, ok := claims[p.config.FieldMapping.Identifier].(string); ok {
|
||||||
|
userInfo.Identifier = v
|
||||||
|
}
|
||||||
|
if userInfo.Identifier == "" {
|
||||||
|
return nil, errors.Errorf("the field %q is not found in claims or has empty value", p.config.FieldMapping.Identifier)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Best effort to map optional fields
|
||||||
|
if p.config.FieldMapping.DisplayName != "" {
|
||||||
|
if v, ok := claims[p.config.FieldMapping.DisplayName].(string); ok {
|
||||||
|
userInfo.DisplayName = v
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if userInfo.DisplayName == "" {
|
||||||
|
userInfo.DisplayName = userInfo.Identifier
|
||||||
|
}
|
||||||
|
if p.config.FieldMapping.Email != "" {
|
||||||
|
if v, ok := claims[p.config.FieldMapping.Email].(string); ok {
|
||||||
|
userInfo.Email = v
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return userInfo, nil
|
||||||
|
}
|
163
plugin/idp/oauth2/oauth2_test.go
Normal file
163
plugin/idp/oauth2/oauth2_test.go
Normal file
@ -0,0 +1,163 @@
|
|||||||
|
package oauth2
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"net/http"
|
||||||
|
"net/http/httptest"
|
||||||
|
"net/url"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
|
"github.com/yourselfhosted/slash/plugin/idp"
|
||||||
|
storepb "github.com/yourselfhosted/slash/proto/gen/store"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestNewIdentityProvider(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
config *storepb.IdentityProviderConfig_OAuth2Config
|
||||||
|
containsErr string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "no tokenUrl",
|
||||||
|
config: &storepb.IdentityProviderConfig_OAuth2Config{
|
||||||
|
ClientId: "test-client-id",
|
||||||
|
ClientSecret: "test-client-secret",
|
||||||
|
AuthUrl: "",
|
||||||
|
TokenUrl: "",
|
||||||
|
UserInfoUrl: "https://example.com/api/user",
|
||||||
|
FieldMapping: &storepb.IdentityProviderConfig_FieldMapping{
|
||||||
|
Identifier: "login",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
containsErr: `the field "tokenUrl" is empty but required`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "no userInfoUrl",
|
||||||
|
config: &storepb.IdentityProviderConfig_OAuth2Config{
|
||||||
|
ClientId: "test-client-id",
|
||||||
|
ClientSecret: "test-client-secret",
|
||||||
|
AuthUrl: "",
|
||||||
|
TokenUrl: "https://example.com/token",
|
||||||
|
UserInfoUrl: "",
|
||||||
|
FieldMapping: &storepb.IdentityProviderConfig_FieldMapping{
|
||||||
|
Identifier: "login",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
containsErr: `the field "userInfoUrl" is empty but required`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "no field mapping identifier",
|
||||||
|
config: &storepb.IdentityProviderConfig_OAuth2Config{
|
||||||
|
ClientId: "test-client-id",
|
||||||
|
ClientSecret: "test-client-secret",
|
||||||
|
AuthUrl: "",
|
||||||
|
TokenUrl: "https://example.com/token",
|
||||||
|
UserInfoUrl: "https://example.com/api/user",
|
||||||
|
FieldMapping: &storepb.IdentityProviderConfig_FieldMapping{
|
||||||
|
Identifier: "",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
containsErr: `the field "fieldMapping.identifier" is empty but required`,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, test := range tests {
|
||||||
|
t.Run(test.name, func(t *testing.T) {
|
||||||
|
_, err := NewIdentityProvider(test.config)
|
||||||
|
assert.ErrorContains(t, err, test.containsErr)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func newMockServer(t *testing.T, code, accessToken string, userinfo []byte) *httptest.Server {
|
||||||
|
mux := http.NewServeMux()
|
||||||
|
|
||||||
|
var rawIDToken string
|
||||||
|
mux.HandleFunc("/oauth2/token", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
require.Equal(t, http.MethodPost, r.Method)
|
||||||
|
|
||||||
|
body, err := io.ReadAll(r.Body)
|
||||||
|
require.NoError(t, err)
|
||||||
|
vals, err := url.ParseQuery(string(body))
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
require.Equal(t, code, vals.Get("code"))
|
||||||
|
require.Equal(t, "authorization_code", vals.Get("grant_type"))
|
||||||
|
|
||||||
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
err = json.NewEncoder(w).Encode(map[string]any{
|
||||||
|
"access_token": accessToken,
|
||||||
|
"token_type": "Bearer",
|
||||||
|
"expires_in": 3600,
|
||||||
|
"id_token": rawIDToken,
|
||||||
|
})
|
||||||
|
require.NoError(t, err)
|
||||||
|
})
|
||||||
|
mux.HandleFunc("/oauth2/userinfo", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
_, err := w.Write(userinfo)
|
||||||
|
require.NoError(t, err)
|
||||||
|
})
|
||||||
|
|
||||||
|
s := httptest.NewServer(mux)
|
||||||
|
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestIdentityProvider(t *testing.T) {
|
||||||
|
ctx := context.Background()
|
||||||
|
|
||||||
|
const (
|
||||||
|
testClientID = "test-client-id"
|
||||||
|
testCode = "test-code"
|
||||||
|
testAccessToken = "test-access-token"
|
||||||
|
testSubject = "123456789"
|
||||||
|
testName = "John Doe"
|
||||||
|
testEmail = "john.doe@example.com"
|
||||||
|
)
|
||||||
|
userInfo, err := json.Marshal(
|
||||||
|
map[string]any{
|
||||||
|
"sub": testSubject,
|
||||||
|
"name": testName,
|
||||||
|
"email": testEmail,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
s := newMockServer(t, testCode, testAccessToken, userInfo)
|
||||||
|
|
||||||
|
oauth2, err := NewIdentityProvider(
|
||||||
|
&storepb.IdentityProviderConfig_OAuth2Config{
|
||||||
|
ClientId: testClientID,
|
||||||
|
ClientSecret: "test-client-secret",
|
||||||
|
TokenUrl: fmt.Sprintf("%s/oauth2/token", s.URL),
|
||||||
|
UserInfoUrl: fmt.Sprintf("%s/oauth2/userinfo", s.URL),
|
||||||
|
FieldMapping: &storepb.IdentityProviderConfig_FieldMapping{
|
||||||
|
Identifier: "sub",
|
||||||
|
DisplayName: "name",
|
||||||
|
Email: "email",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
redirectURL := "https://example.com/oauth/callback"
|
||||||
|
oauthToken, err := oauth2.ExchangeToken(ctx, redirectURL, testCode)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, testAccessToken, oauthToken)
|
||||||
|
|
||||||
|
userInfoResult, err := oauth2.UserInfo(oauthToken)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
wantUserInfo := &idp.IdentityProviderUserInfo{
|
||||||
|
Identifier: testSubject,
|
||||||
|
DisplayName: testName,
|
||||||
|
Email: testEmail,
|
||||||
|
}
|
||||||
|
assert.Equal(t, wantUserInfo, userInfoResult)
|
||||||
|
}
|
@ -209,7 +209,7 @@
|
|||||||
|
|
||||||
| Field | Type | Label | Description |
|
| Field | Type | Label | Description |
|
||||||
| ----- | ---- | ----- | ----------- |
|
| ----- | ---- | ----- | ----------- |
|
||||||
| oauth2_config | [IdentityProviderConfig.OAuth2Config](#slash-store-IdentityProviderConfig-OAuth2Config) | | |
|
| oauth2 | [IdentityProviderConfig.OAuth2Config](#slash-store-IdentityProviderConfig-OAuth2Config) | | |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -224,6 +224,7 @@
|
|||||||
|
|
||||||
| Field | Type | Label | Description |
|
| Field | Type | Label | Description |
|
||||||
| ----- | ---- | ----- | ----------- |
|
| ----- | ---- | ----- | ----------- |
|
||||||
|
| identifier | [string](#string) | | |
|
||||||
| email | [string](#string) | | |
|
| email | [string](#string) | | |
|
||||||
| display_name | [string](#string) | | |
|
| display_name | [string](#string) | | |
|
||||||
|
|
||||||
|
@ -136,7 +136,7 @@ type IdentityProviderConfig struct {
|
|||||||
|
|
||||||
// Types that are assignable to Config:
|
// Types that are assignable to Config:
|
||||||
//
|
//
|
||||||
// *IdentityProviderConfig_Oauth2Config
|
// *IdentityProviderConfig_Oauth2
|
||||||
Config isIdentityProviderConfig_Config `protobuf_oneof:"config"`
|
Config isIdentityProviderConfig_Config `protobuf_oneof:"config"`
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -179,9 +179,9 @@ func (m *IdentityProviderConfig) GetConfig() isIdentityProviderConfig_Config {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x *IdentityProviderConfig) GetOauth2Config() *IdentityProviderConfig_OAuth2Config {
|
func (x *IdentityProviderConfig) GetOauth2() *IdentityProviderConfig_OAuth2Config {
|
||||||
if x, ok := x.GetConfig().(*IdentityProviderConfig_Oauth2Config); ok {
|
if x, ok := x.GetConfig().(*IdentityProviderConfig_Oauth2); ok {
|
||||||
return x.Oauth2Config
|
return x.Oauth2
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -190,19 +190,20 @@ type isIdentityProviderConfig_Config interface {
|
|||||||
isIdentityProviderConfig_Config()
|
isIdentityProviderConfig_Config()
|
||||||
}
|
}
|
||||||
|
|
||||||
type IdentityProviderConfig_Oauth2Config struct {
|
type IdentityProviderConfig_Oauth2 struct {
|
||||||
Oauth2Config *IdentityProviderConfig_OAuth2Config `protobuf:"bytes,1,opt,name=oauth2_config,json=oauth2Config,proto3,oneof"`
|
Oauth2 *IdentityProviderConfig_OAuth2Config `protobuf:"bytes,1,opt,name=oauth2,proto3,oneof"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (*IdentityProviderConfig_Oauth2Config) isIdentityProviderConfig_Config() {}
|
func (*IdentityProviderConfig_Oauth2) isIdentityProviderConfig_Config() {}
|
||||||
|
|
||||||
type IdentityProviderConfig_FieldMapping struct {
|
type IdentityProviderConfig_FieldMapping struct {
|
||||||
state protoimpl.MessageState
|
state protoimpl.MessageState
|
||||||
sizeCache protoimpl.SizeCache
|
sizeCache protoimpl.SizeCache
|
||||||
unknownFields protoimpl.UnknownFields
|
unknownFields protoimpl.UnknownFields
|
||||||
|
|
||||||
Email string `protobuf:"bytes,1,opt,name=email,proto3" json:"email,omitempty"`
|
Identifier string `protobuf:"bytes,1,opt,name=identifier,proto3" json:"identifier,omitempty"`
|
||||||
DisplayName string `protobuf:"bytes,2,opt,name=display_name,json=displayName,proto3" json:"display_name,omitempty"`
|
Email string `protobuf:"bytes,2,opt,name=email,proto3" json:"email,omitempty"`
|
||||||
|
DisplayName string `protobuf:"bytes,3,opt,name=display_name,json=displayName,proto3" json:"display_name,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x *IdentityProviderConfig_FieldMapping) Reset() {
|
func (x *IdentityProviderConfig_FieldMapping) Reset() {
|
||||||
@ -237,6 +238,13 @@ func (*IdentityProviderConfig_FieldMapping) Descriptor() ([]byte, []int) {
|
|||||||
return file_store_idp_proto_rawDescGZIP(), []int{1, 0}
|
return file_store_idp_proto_rawDescGZIP(), []int{1, 0}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (x *IdentityProviderConfig_FieldMapping) GetIdentifier() string {
|
||||||
|
if x != nil {
|
||||||
|
return x.Identifier
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
func (x *IdentityProviderConfig_FieldMapping) GetEmail() string {
|
func (x *IdentityProviderConfig_FieldMapping) GetEmail() string {
|
||||||
if x != nil {
|
if x != nil {
|
||||||
return x.Email
|
return x.Email
|
||||||
@ -363,47 +371,49 @@ var file_store_idp_proto_rawDesc = []byte{
|
|||||||
0x6e, 0x66, 0x69, 0x67, 0x52, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x22, 0x28, 0x0a, 0x04,
|
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,
|
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,
|
0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x4f, 0x41,
|
||||||
0x55, 0x54, 0x48, 0x32, 0x10, 0x01, 0x22, 0xe2, 0x03, 0x0a, 0x16, 0x49, 0x64, 0x65, 0x6e, 0x74,
|
0x55, 0x54, 0x48, 0x32, 0x10, 0x01, 0x22, 0xf5, 0x03, 0x0a, 0x16, 0x49, 0x64, 0x65, 0x6e, 0x74,
|
||||||
0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69,
|
0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69,
|
||||||
0x67, 0x12, 0x57, 0x0a, 0x0d, 0x6f, 0x61, 0x75, 0x74, 0x68, 0x32, 0x5f, 0x63, 0x6f, 0x6e, 0x66,
|
0x67, 0x12, 0x4a, 0x0a, 0x06, 0x6f, 0x61, 0x75, 0x74, 0x68, 0x32, 0x18, 0x01, 0x20, 0x01, 0x28,
|
||||||
0x69, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x73, 0x6c, 0x61, 0x73, 0x68,
|
|
||||||
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, 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, 0x1a, 0x47, 0x0a, 0x0c, 0x46, 0x69,
|
|
||||||
0x65, 0x6c, 0x64, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x6d,
|
|
||||||
0x61, 0x69, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c,
|
|
||||||
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, 0x1a, 0x9b, 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, 0x55, 0x0a, 0x0d, 0x66, 0x69,
|
|
||||||
0x65, 0x6c, 0x64, 0x5f, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x18, 0x07, 0x20, 0x01, 0x28,
|
|
||||||
0x0b, 0x32, 0x30, 0x2e, 0x73, 0x6c, 0x61, 0x73, 0x68, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x2e,
|
0x0b, 0x32, 0x30, 0x2e, 0x73, 0x6c, 0x61, 0x73, 0x68, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x2e,
|
||||||
0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72,
|
0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72,
|
||||||
0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x4d, 0x61, 0x70, 0x70,
|
0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x4f, 0x41, 0x75, 0x74, 0x68, 0x32, 0x43, 0x6f, 0x6e,
|
||||||
0x69, 0x6e, 0x67, 0x52, 0x0c, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e,
|
0x66, 0x69, 0x67, 0x48, 0x00, 0x52, 0x06, 0x6f, 0x61, 0x75, 0x74, 0x68, 0x32, 0x1a, 0x67, 0x0a,
|
||||||
0x67, 0x42, 0x08, 0x0a, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x42, 0x99, 0x01, 0x0a, 0x0f,
|
0x0c, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x12, 0x1e, 0x0a,
|
||||||
0x63, 0x6f, 0x6d, 0x2e, 0x73, 0x6c, 0x61, 0x73, 0x68, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x42,
|
0x0a, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28,
|
||||||
0x08, 0x49, 0x64, 0x70, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x2f, 0x67, 0x69, 0x74,
|
0x09, 0x52, 0x0a, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x12, 0x14, 0x0a,
|
||||||
0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x79, 0x6f, 0x75, 0x72, 0x73, 0x65, 0x6c, 0x66,
|
0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x6d,
|
||||||
0x68, 0x6f, 0x73, 0x74, 0x65, 0x64, 0x2f, 0x73, 0x6c, 0x61, 0x73, 0x68, 0x2f, 0x70, 0x72, 0x6f,
|
0x61, 0x69, 0x6c, 0x12, 0x21, 0x0a, 0x0c, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x5f, 0x6e,
|
||||||
0x74, 0x6f, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x73, 0x74, 0x6f, 0x72, 0x65, 0xa2, 0x02, 0x03, 0x53,
|
0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x69, 0x73, 0x70, 0x6c,
|
||||||
0x53, 0x58, 0xaa, 0x02, 0x0b, 0x53, 0x6c, 0x61, 0x73, 0x68, 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x65,
|
0x61, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x1a, 0x9b, 0x02, 0x0a, 0x0c, 0x4f, 0x41, 0x75, 0x74, 0x68,
|
||||||
0xca, 0x02, 0x0b, 0x53, 0x6c, 0x61, 0x73, 0x68, 0x5c, 0x53, 0x74, 0x6f, 0x72, 0x65, 0xe2, 0x02,
|
0x32, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x1b, 0x0a, 0x09, 0x63, 0x6c, 0x69, 0x65, 0x6e,
|
||||||
0x17, 0x53, 0x6c, 0x61, 0x73, 0x68, 0x5c, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x5c, 0x47, 0x50, 0x42,
|
0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x63, 0x6c, 0x69, 0x65,
|
||||||
0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x0c, 0x53, 0x6c, 0x61, 0x73, 0x68,
|
0x6e, 0x74, 0x49, 0x64, 0x12, 0x23, 0x0a, 0x0d, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x73,
|
||||||
0x3a, 0x3a, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
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, 0x55, 0x0a,
|
||||||
|
0x0d, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x5f, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x18, 0x07,
|
||||||
|
0x20, 0x01, 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x73, 0x6c, 0x61, 0x73, 0x68, 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, 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, 0x08, 0x0a, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x42, 0x99,
|
||||||
|
0x01, 0x0a, 0x0f, 0x63, 0x6f, 0x6d, 0x2e, 0x73, 0x6c, 0x61, 0x73, 0x68, 0x2e, 0x73, 0x74, 0x6f,
|
||||||
|
0x72, 0x65, 0x42, 0x08, 0x49, 0x64, 0x70, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x2f,
|
||||||
|
0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x79, 0x6f, 0x75, 0x72, 0x73,
|
||||||
|
0x65, 0x6c, 0x66, 0x68, 0x6f, 0x73, 0x74, 0x65, 0x64, 0x2f, 0x73, 0x6c, 0x61, 0x73, 0x68, 0x2f,
|
||||||
|
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x73, 0x74, 0x6f, 0x72, 0x65, 0xa2,
|
||||||
|
0x02, 0x03, 0x53, 0x53, 0x58, 0xaa, 0x02, 0x0b, 0x53, 0x6c, 0x61, 0x73, 0x68, 0x2e, 0x53, 0x74,
|
||||||
|
0x6f, 0x72, 0x65, 0xca, 0x02, 0x0b, 0x53, 0x6c, 0x61, 0x73, 0x68, 0x5c, 0x53, 0x74, 0x6f, 0x72,
|
||||||
|
0x65, 0xe2, 0x02, 0x17, 0x53, 0x6c, 0x61, 0x73, 0x68, 0x5c, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x5c,
|
||||||
|
0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x0c, 0x53, 0x6c,
|
||||||
|
0x61, 0x73, 0x68, 0x3a, 0x3a, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74,
|
||||||
|
0x6f, 0x33,
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -430,7 +440,7 @@ var file_store_idp_proto_goTypes = []any{
|
|||||||
var file_store_idp_proto_depIdxs = []int32{
|
var file_store_idp_proto_depIdxs = []int32{
|
||||||
0, // 0: slash.store.IdentityProvider.type:type_name -> slash.store.IdentityProvider.Type
|
0, // 0: slash.store.IdentityProvider.type:type_name -> slash.store.IdentityProvider.Type
|
||||||
2, // 1: slash.store.IdentityProvider.config:type_name -> slash.store.IdentityProviderConfig
|
2, // 1: slash.store.IdentityProvider.config:type_name -> slash.store.IdentityProviderConfig
|
||||||
4, // 2: slash.store.IdentityProviderConfig.oauth2_config:type_name -> slash.store.IdentityProviderConfig.OAuth2Config
|
4, // 2: slash.store.IdentityProviderConfig.oauth2:type_name -> slash.store.IdentityProviderConfig.OAuth2Config
|
||||||
3, // 3: slash.store.IdentityProviderConfig.OAuth2Config.field_mapping:type_name -> slash.store.IdentityProviderConfig.FieldMapping
|
3, // 3: slash.store.IdentityProviderConfig.OAuth2Config.field_mapping:type_name -> slash.store.IdentityProviderConfig.FieldMapping
|
||||||
4, // [4:4] is the sub-list for method output_type
|
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 method input_type
|
||||||
@ -495,7 +505,7 @@ func file_store_idp_proto_init() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
file_store_idp_proto_msgTypes[1].OneofWrappers = []any{
|
file_store_idp_proto_msgTypes[1].OneofWrappers = []any{
|
||||||
(*IdentityProviderConfig_Oauth2Config)(nil),
|
(*IdentityProviderConfig_Oauth2)(nil),
|
||||||
}
|
}
|
||||||
type x struct{}
|
type x struct{}
|
||||||
out := protoimpl.TypeBuilder{
|
out := protoimpl.TypeBuilder{
|
||||||
|
@ -17,12 +17,13 @@ message IdentityProvider {
|
|||||||
|
|
||||||
message IdentityProviderConfig {
|
message IdentityProviderConfig {
|
||||||
oneof config {
|
oneof config {
|
||||||
OAuth2Config oauth2_config = 1;
|
OAuth2Config oauth2 = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
message FieldMapping {
|
message FieldMapping {
|
||||||
string email = 1;
|
string identifier = 1;
|
||||||
string display_name = 2;
|
string email = 2;
|
||||||
|
string display_name = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
message OAuth2Config {
|
message OAuth2Config {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user