mirror of
https://github.com/opencloud-eu/opencloud.git
synced 2026-01-30 16:38:58 -06:00
Merge branch 'master' into ocis-init
This commit is contained in:
@@ -197,6 +197,8 @@ func ldapConfigFromString(cfg config.LDAPProvider) map[string]interface{} {
|
||||
"group_base_dn": cfg.GroupBaseDN,
|
||||
"user_filter": cfg.UserFilter,
|
||||
"group_filter": cfg.GroupFilter,
|
||||
"user_scope": cfg.UserScope,
|
||||
"group_scope": cfg.GroupScope,
|
||||
"user_objectclass": cfg.UserObjectClass,
|
||||
"group_objectclass": cfg.GroupObjectClass,
|
||||
"login_attributes": cfg.LoginAttributes,
|
||||
|
||||
@@ -67,6 +67,8 @@ type LDAPProvider struct {
|
||||
BindPassword string `env:"LDAP_BIND_PASSWORD;AUTH_BASIC_LDAP_BIND_PASSWORD"`
|
||||
UserBaseDN string `env:"LDAP_USER_BASE_DN;AUTH_BASIC_LDAP_USER_BASE_DN"`
|
||||
GroupBaseDN string `env:"LDAP_GROUP_BASE_DN;AUTH_BASIC_LDAP_GROUP_BASE_DN"`
|
||||
UserScope string `env:"LDAP_USER_SCOPE;AUTH_BASIC_LDAP_USER_SCOPE"`
|
||||
GroupScope string `env:"LDAP_GROUP_SCOPE;AUTH_BASIC_LDAP_GROUP_SCOPE"`
|
||||
UserFilter string `env:"LDAP_USERFILTER;AUTH_BASIC_LDAP_USERFILTER"`
|
||||
GroupFilter string `env:"LDAP_GROUPFILTER;AUTH_BASIC_LDAP_USERFILTER"`
|
||||
UserObjectClass string `env:"LDAP_USER_OBJECTCLASS;AUTH_BASIC_LDAP_USER_OBJECTCLASS"`
|
||||
|
||||
@@ -36,31 +36,33 @@ func DefaultConfig() *config.Config {
|
||||
AuthProvider: "ldap",
|
||||
AuthProviders: config.AuthProviders{
|
||||
LDAP: config.LDAPProvider{
|
||||
URI: "ldaps://localhost:9126",
|
||||
CACert: filepath.Join(defaults.BaseDataPath(), "ldap", "ldap.crt"),
|
||||
URI: "ldaps://localhost:9235",
|
||||
CACert: filepath.Join(defaults.BaseDataPath(), "idm", "ldap.crt"),
|
||||
Insecure: false,
|
||||
UserBaseDN: "dc=ocis,dc=test",
|
||||
GroupBaseDN: "dc=ocis,dc=test",
|
||||
LoginAttributes: []string{"cn", "mail"},
|
||||
UserBaseDN: "ou=users,o=libregraph-idm",
|
||||
GroupBaseDN: "ou=groups,o=libregraph-idm",
|
||||
UserScope: "sub",
|
||||
GroupScope: "sub",
|
||||
LoginAttributes: []string{"uid", "mail"},
|
||||
UserFilter: "",
|
||||
GroupFilter: "",
|
||||
UserObjectClass: "posixAccount",
|
||||
GroupObjectClass: "posixGroup",
|
||||
BindDN: "cn=reva,ou=sysusers,dc=ocis,dc=test",
|
||||
UserObjectClass: "inetOrgPerson",
|
||||
GroupObjectClass: "groupOfNames",
|
||||
BindDN: "uid=reva,ou=sysusers,o=libregraph-idm",
|
||||
BindPassword: "reva",
|
||||
IDP: "https://localhost:9200",
|
||||
UserSchema: config.LDAPUserSchema{
|
||||
ID: "ownclouduuid",
|
||||
Mail: "mail",
|
||||
DisplayName: "displayname",
|
||||
Username: "cn",
|
||||
Username: "uid",
|
||||
},
|
||||
GroupSchema: config.LDAPGroupSchema{
|
||||
ID: "cn",
|
||||
ID: "ownclouduuid",
|
||||
Mail: "mail",
|
||||
DisplayName: "cn",
|
||||
Groupname: "cn",
|
||||
Member: "cn",
|
||||
Member: "member",
|
||||
},
|
||||
},
|
||||
JSON: config.JSONProvider{},
|
||||
|
||||
@@ -30,15 +30,15 @@ func DefaultConfig() *config.Config {
|
||||
Insecure: false,
|
||||
},
|
||||
Identity: config.Identity{
|
||||
Backend: "cs3",
|
||||
Backend: "ldap",
|
||||
LDAP: config.LDAP{
|
||||
URI: "ldap://localhost:9125",
|
||||
Insecure: false,
|
||||
BindDN: "",
|
||||
BindPassword: "",
|
||||
URI: "ldaps://localhost:9235",
|
||||
Insecure: true,
|
||||
BindDN: "uid=libregraph,ou=sysusers,o=libregraph-idm",
|
||||
BindPassword: "idm",
|
||||
UseServerUUID: false,
|
||||
WriteEnabled: false,
|
||||
UserBaseDN: "ou=users,dc=ocis,dc=test",
|
||||
WriteEnabled: true,
|
||||
UserBaseDN: "ou=users,o=libregraph-idm",
|
||||
UserSearchScope: "sub",
|
||||
UserFilter: "",
|
||||
UserObjectClass: "inetOrgPerson",
|
||||
@@ -48,7 +48,7 @@ func DefaultConfig() *config.Config {
|
||||
// FIXME: switch this to some more widely available attribute by default
|
||||
// ideally this needs to be constant for the lifetime of a users
|
||||
UserIDAttribute: "owncloudUUID",
|
||||
GroupBaseDN: "ou=groups,dc=ocis,dc=test",
|
||||
GroupBaseDN: "ou=groups,o=libregraph-idm",
|
||||
GroupSearchScope: "sub",
|
||||
GroupFilter: "",
|
||||
GroupObjectClass: "groupOfNames",
|
||||
|
||||
@@ -77,11 +77,11 @@ func (g Graph) GetRootDriveChildren(w http.ResponseWriter, r *http.Request) {
|
||||
render.JSON(w, r, &listResponse{Value: files})
|
||||
}
|
||||
|
||||
func (g Graph) getDriveItem(ctx context.Context, root *storageprovider.ResourceId) (*libregraph.DriveItem, error) {
|
||||
func (g Graph) getDriveItem(ctx context.Context, root storageprovider.ResourceId) (*libregraph.DriveItem, error) {
|
||||
client := g.GetGatewayClient()
|
||||
|
||||
ref := &storageprovider.Reference{
|
||||
ResourceId: root,
|
||||
ResourceId: &root,
|
||||
}
|
||||
res, err := client.Stat(ctx, &storageprovider.StatRequest{Ref: ref})
|
||||
if err != nil {
|
||||
@@ -196,18 +196,16 @@ func cs3ResourceToRemoteItem(res *storageprovider.ResourceInfo) (*libregraph.Rem
|
||||
return remoteItem, nil
|
||||
}
|
||||
|
||||
func (g Graph) getPathForResource(ctx context.Context, ID *storageprovider.ResourceId) (*string, error) {
|
||||
func (g Graph) getPathForResource(ctx context.Context, id storageprovider.ResourceId) (string, error) {
|
||||
client := g.GetGatewayClient()
|
||||
var path *string
|
||||
res, err := client.GetPath(ctx, &storageprovider.GetPathRequest{ResourceId: ID})
|
||||
res, err := client.GetPath(ctx, &storageprovider.GetPathRequest{ResourceId: &id})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return "", err
|
||||
}
|
||||
if res.Status.Code != cs3rpc.Code_CODE_OK {
|
||||
return nil, fmt.Errorf("could not stat %s: %s", ID, res.Status.Message)
|
||||
return "", fmt.Errorf("could not stat %v: %s", id, res.Status.Message)
|
||||
}
|
||||
path = &res.Path
|
||||
return path, err
|
||||
return res.Path, err
|
||||
}
|
||||
|
||||
// GetExtendedSpaceProperties reads properties from the opaque and transforms them into driveItems
|
||||
@@ -221,7 +219,7 @@ func (g Graph) GetExtendedSpaceProperties(ctx context.Context, baseURL *url.URL,
|
||||
|
||||
for _, itemName := range names {
|
||||
if itemID, ok := metadata[itemName]; ok {
|
||||
spaceItem := g.getSpecialDriveItem(ctx, resourceid.OwnCloudResourceIDUnwrap(string(itemID.Value)), itemName, baseURL, space)
|
||||
spaceItem := g.getSpecialDriveItem(ctx, *resourceid.OwnCloudResourceIDUnwrap(string(itemID.Value)), itemName, baseURL, space)
|
||||
if spaceItem != nil {
|
||||
spaceItems = append(spaceItems, *spaceItem)
|
||||
}
|
||||
@@ -230,24 +228,26 @@ func (g Graph) GetExtendedSpaceProperties(ctx context.Context, baseURL *url.URL,
|
||||
return spaceItems
|
||||
}
|
||||
|
||||
func (g Graph) getSpecialDriveItem(ctx context.Context, ID *storageprovider.ResourceId, itemName string, baseURL *url.URL, space *storageprovider.StorageSpace) *libregraph.DriveItem {
|
||||
func (g Graph) getSpecialDriveItem(ctx context.Context, id storageprovider.ResourceId, itemName string, baseURL *url.URL, space *storageprovider.StorageSpace) *libregraph.DriveItem {
|
||||
var spaceItem *libregraph.DriveItem
|
||||
if ID == nil {
|
||||
if id.StorageId == "" && id.OpaqueId == "" {
|
||||
return nil
|
||||
}
|
||||
|
||||
spaceItem, err := g.getDriveItem(ctx, ID)
|
||||
spaceItem, err := g.getDriveItem(ctx, id)
|
||||
if err != nil {
|
||||
g.logger.Error().Err(err).Str("ID", ID.OpaqueId).Msg("Could not get readme Item")
|
||||
g.logger.Error().Err(err).Str("ID", id.OpaqueId).Msg("Could not get readme Item")
|
||||
return nil
|
||||
}
|
||||
itemPath, err := g.getPathForResource(ctx, ID)
|
||||
itemPath, err := g.getPathForResource(ctx, id)
|
||||
if err != nil {
|
||||
g.logger.Error().Err(err).Str("ID", ID.OpaqueId).Msg("Could not get readme path")
|
||||
g.logger.Error().Err(err).Str("ID", id.OpaqueId).Msg("Could not get readme path")
|
||||
return nil
|
||||
}
|
||||
spaceItem.SpecialFolder = &libregraph.SpecialFolder{Name: libregraph.PtrString(itemName)}
|
||||
spaceItem.WebDavUrl = libregraph.PtrString(baseURL.String() + path.Join(space.Id.OpaqueId, *itemPath))
|
||||
webdavURL := *baseURL
|
||||
webdavURL.Path = path.Join(webdavURL.Path, space.Id.OpaqueId, itemPath)
|
||||
spaceItem.WebDavUrl = libregraph.PtrString(webdavURL.String())
|
||||
|
||||
return spaceItem
|
||||
}
|
||||
|
||||
@@ -194,6 +194,8 @@ func ldapConfigFromString(cfg config.LDAPDriver) map[string]interface{} {
|
||||
"bind_password": cfg.BindPassword,
|
||||
"user_base_dn": cfg.UserBaseDN,
|
||||
"group_base_dn": cfg.GroupBaseDN,
|
||||
"user_scope": cfg.UserScope,
|
||||
"group_scope": cfg.GroupScope,
|
||||
"user_filter": cfg.UserFilter,
|
||||
"group_filter": cfg.GroupFilter,
|
||||
"user_objectclass": cfg.UserObjectClass,
|
||||
|
||||
@@ -68,6 +68,8 @@ type LDAPDriver struct {
|
||||
BindPassword string `env:"LDAP_BIND_PASSWORD;GROUPS_LDAP_BIND_PASSWORD"`
|
||||
UserBaseDN string `env:"LDAP_USER_BASE_DN;GROUPS_LDAP_USER_BASE_DN"`
|
||||
GroupBaseDN string `env:"LDAP_GROUP_BASE_DN;GROUPS_LDAP_GROUP_BASE_DN"`
|
||||
UserScope string `env:"LDAP_USER_SCOPE;GROUPS_LDAP_USER_SCOPE"`
|
||||
GroupScope string `env:"LDAP_GROUP_SCOPE;GROUPS_LDAP_GROUP_SCOPE"`
|
||||
UserFilter string `env:"LDAP_USERFILTER;GROUPS_LDAP_USERFILTER"`
|
||||
GroupFilter string `env:"LDAP_GROUPFILTER;GROUPS_LDAP_USERFILTER"`
|
||||
UserObjectClass string `env:"LDAP_USER_OBJECTCLASS;GROUPS_LDAP_USER_OBJECTCLASS"`
|
||||
|
||||
@@ -37,31 +37,33 @@ func DefaultConfig() *config.Config {
|
||||
Driver: "ldap",
|
||||
Drivers: config.Drivers{
|
||||
LDAP: config.LDAPDriver{
|
||||
URI: "ldaps://localhost:9126",
|
||||
CACert: filepath.Join(defaults.BaseDataPath(), "ldap", "ldap.crt"),
|
||||
URI: "ldaps://localhost:9235",
|
||||
CACert: filepath.Join(defaults.BaseDataPath(), "idm", "ldap.crt"),
|
||||
Insecure: false,
|
||||
UserBaseDN: "dc=ocis,dc=test",
|
||||
GroupBaseDN: "dc=ocis,dc=test",
|
||||
LoginAttributes: []string{"cn", "mail"},
|
||||
UserBaseDN: "ou=users,o=libregraph-idm",
|
||||
GroupBaseDN: "ou=groups,o=libregraph-idm",
|
||||
UserScope: "sub",
|
||||
GroupScope: "sub",
|
||||
LoginAttributes: []string{"uid", "mail"},
|
||||
UserFilter: "",
|
||||
GroupFilter: "",
|
||||
UserObjectClass: "posixAccount",
|
||||
GroupObjectClass: "posixGroup",
|
||||
BindDN: "cn=reva,ou=sysusers,dc=ocis,dc=test",
|
||||
UserObjectClass: "inetOrgPerson",
|
||||
GroupObjectClass: "groupOfNames",
|
||||
BindDN: "uid=reva,ou=sysusers,o=libregraph-idm",
|
||||
BindPassword: "reva",
|
||||
IDP: "https://localhost:9200",
|
||||
UserSchema: config.LDAPUserSchema{
|
||||
ID: "ownclouduuid",
|
||||
Mail: "mail",
|
||||
DisplayName: "displayname",
|
||||
Username: "cn",
|
||||
Username: "uid",
|
||||
},
|
||||
GroupSchema: config.LDAPGroupSchema{
|
||||
ID: "cn",
|
||||
ID: "ownclouduuid",
|
||||
Mail: "mail",
|
||||
DisplayName: "cn",
|
||||
Groupname: "cn",
|
||||
Member: "cn",
|
||||
Member: "member",
|
||||
},
|
||||
},
|
||||
JSON: config.JSONDriver{},
|
||||
|
||||
@@ -27,7 +27,8 @@ type Config struct {
|
||||
|
||||
// Ldap defines the available LDAP configuration.
|
||||
type Ldap struct {
|
||||
URI string `yaml:"uri" env:"LDAP_URI;IDP_LDAP_URI"`
|
||||
URI string `yaml:"uri" env:"LDAP_URI;IDP_LDAP_URI"`
|
||||
TLSCACert string `yaml:"cacert" env:"LDAP_CACERT;IDP_LDAP_TLS_CACERT"`
|
||||
|
||||
BindDN string `yaml:"bind_dn" env:"LDAP_BIND_DN;IDP_LDAP_BIND_DN"`
|
||||
BindPassword string `yaml:"bind_password" env:"LDAP_BIND_PASSWORD;IDP_LDAP_BIND_PASSWORD"`
|
||||
|
||||
@@ -68,18 +68,19 @@ func DefaultConfig() *config.Config {
|
||||
DyamicClientSecretDurationSeconds: 0,
|
||||
},
|
||||
Ldap: config.Ldap{
|
||||
URI: "ldap://localhost:9125",
|
||||
BindDN: "cn=idp,ou=sysusers,dc=ocis,dc=test",
|
||||
URI: "ldaps://localhost:9235",
|
||||
TLSCACert: path.Join(defaults.BaseDataPath(), "idm", "ldap.crt"),
|
||||
BindDN: "uid=idp,ou=sysusers,o=libregraph-idm",
|
||||
BindPassword: "idp",
|
||||
BaseDN: "ou=users,dc=ocis,dc=test",
|
||||
BaseDN: "ou=users,o=libregraph-idm",
|
||||
Scope: "sub",
|
||||
LoginAttribute: "cn",
|
||||
LoginAttribute: "uid",
|
||||
EmailAttribute: "mail",
|
||||
NameAttribute: "displayName",
|
||||
UUIDAttribute: "uid",
|
||||
UUIDAttributeType: "text",
|
||||
Filter: "",
|
||||
ObjectClass: "posixAccount",
|
||||
ObjectClass: "inetOrgPerson",
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -142,6 +142,10 @@ func initLicoInternalEnvVars(ldap *config.Ldap) error {
|
||||
"LDAP_FILTER": filter,
|
||||
}
|
||||
|
||||
if ldap.TLSCACert != "" {
|
||||
defaults["LDAP_TLS_CACERT"] = ldap.TLSCACert
|
||||
}
|
||||
|
||||
for k, v := range defaults {
|
||||
if err := os.Setenv(k, v); err != nil {
|
||||
return fmt.Errorf("could not set env var %s=%s", k, v)
|
||||
|
||||
@@ -38,8 +38,7 @@ func DefaultConfig() *config.Config {
|
||||
Service: config.Service{
|
||||
Name: "ocs",
|
||||
},
|
||||
|
||||
AccountBackend: "accounts",
|
||||
AccountBackend: "cs3",
|
||||
Reva: &config.Reva{
|
||||
Address: "127.0.0.1:9142",
|
||||
},
|
||||
|
||||
@@ -43,7 +43,7 @@ func DefaultConfig() *config.Config {
|
||||
AllowedHTTPMethods: []string{"GET"},
|
||||
Enabled: true,
|
||||
},
|
||||
AccountBackend: "accounts",
|
||||
AccountBackend: "cs3",
|
||||
UserOIDCClaim: "email",
|
||||
UserCS3Claim: "mail",
|
||||
AutoprovisionAccounts: false,
|
||||
|
||||
@@ -44,35 +44,35 @@ func DefaultConfig() *config.Config {
|
||||
IDClaim: "preferred_username",
|
||||
},
|
||||
LDAP: config.LDAP{
|
||||
URI: "ldaps://localhost:9126",
|
||||
CACert: path.Join(defaults.BaseDataPath(), "ldap", "ldap.crt"),
|
||||
URI: "ldaps://localhost:9235",
|
||||
CACert: path.Join(defaults.BaseDataPath(), "idm", "ldap.crt"),
|
||||
Insecure: false,
|
||||
UserBaseDN: "dc=ocis,dc=test",
|
||||
GroupBaseDN: "dc=ocis,dc=test",
|
||||
UserBaseDN: "ou=users,o=libregraph-idm",
|
||||
GroupBaseDN: "ou=groups,o=libregraph-idm",
|
||||
UserScope: "sub",
|
||||
GroupScope: "sub",
|
||||
LoginAttributes: []string{"cn", "mail"},
|
||||
LoginAttributes: []string{"uid", "mail"},
|
||||
UserFilter: "",
|
||||
GroupFilter: "",
|
||||
UserObjectClass: "posixAccount",
|
||||
GroupObjectClass: "posixGroup",
|
||||
BindDN: "cn=reva,ou=sysusers,dc=ocis,dc=test",
|
||||
UserObjectClass: "inetOrgPerson",
|
||||
GroupObjectClass: "groupOfNames",
|
||||
BindDN: "uid=reva,ou=sysusers,o=libregraph-idm",
|
||||
BindPassword: "reva",
|
||||
IDP: defaultPublicURL,
|
||||
UserSchema: config.LDAPUserSchema{
|
||||
ID: "ownclouduuid",
|
||||
Mail: "mail",
|
||||
DisplayName: "displayname",
|
||||
Username: "cn",
|
||||
Username: "uid",
|
||||
UIDNumber: "uidnumber",
|
||||
GIDNumber: "gidnumber",
|
||||
},
|
||||
GroupSchema: config.LDAPGroupSchema{
|
||||
ID: "cn",
|
||||
ID: "ownclouduuid",
|
||||
Mail: "mail",
|
||||
DisplayName: "cn",
|
||||
Groupname: "cn",
|
||||
Member: "cn",
|
||||
Member: "member",
|
||||
GIDNumber: "gidnumber",
|
||||
},
|
||||
},
|
||||
|
||||
@@ -213,6 +213,8 @@ func ldapConfigFromString(cfg config.LDAPDriver) map[string]interface{} {
|
||||
"bind_password": cfg.BindPassword,
|
||||
"user_base_dn": cfg.UserBaseDN,
|
||||
"group_base_dn": cfg.GroupBaseDN,
|
||||
"user_scope": cfg.UserScope,
|
||||
"group_scope": cfg.GroupScope,
|
||||
"user_filter": cfg.UserFilter,
|
||||
"group_filter": cfg.GroupFilter,
|
||||
"user_objectclass": cfg.UserObjectClass,
|
||||
|
||||
@@ -68,6 +68,8 @@ type LDAPDriver struct {
|
||||
BindPassword string `env:"LDAP_BIND_PASSWORD;USERS_LDAP_BIND_PASSWORD"`
|
||||
UserBaseDN string `env:"LDAP_USER_BASE_DN;USERS_LDAP_USER_BASE_DN"`
|
||||
GroupBaseDN string `env:"LDAP_GROUP_BASE_DN;USERS_LDAP_GROUP_BASE_DN"`
|
||||
UserScope string `env:"LDAP_USER_SCOPE;USERS_LDAP_USER_SCOPE"`
|
||||
GroupScope string `env:"LDAP_GROUP_SCOPE;USERS_LDAP_GROUP_SCOPE"`
|
||||
UserFilter string `env:"LDAP_USERFILTER;USERS_LDAP_USERFILTER"`
|
||||
GroupFilter string `env:"LDAP_GROUPFILTER;USERS_LDAP_USERFILTER"`
|
||||
UserObjectClass string `env:"LDAP_USER_OBJECTCLASS;USERS_LDAP_USER_OBJECTCLASS"`
|
||||
|
||||
@@ -37,31 +37,33 @@ func DefaultConfig() *config.Config {
|
||||
Driver: "ldap",
|
||||
Drivers: config.Drivers{
|
||||
LDAP: config.LDAPDriver{
|
||||
URI: "ldaps://localhost:9126",
|
||||
CACert: filepath.Join(defaults.BaseDataPath(), "ldap", "ldap.crt"),
|
||||
URI: "ldaps://localhost:9235",
|
||||
CACert: filepath.Join(defaults.BaseDataPath(), "idm", "ldap.crt"),
|
||||
Insecure: false,
|
||||
UserBaseDN: "dc=ocis,dc=test",
|
||||
GroupBaseDN: "dc=ocis,dc=test",
|
||||
LoginAttributes: []string{"cn", "mail"},
|
||||
UserBaseDN: "ou=users,o=libregraph-idm",
|
||||
GroupBaseDN: "ou=groups,o=libregraph-idm",
|
||||
UserScope: "sub",
|
||||
GroupScope: "sub",
|
||||
LoginAttributes: []string{"uid", "mail"},
|
||||
UserFilter: "",
|
||||
GroupFilter: "",
|
||||
UserObjectClass: "posixAccount",
|
||||
GroupObjectClass: "posixGroup",
|
||||
BindDN: "cn=reva,ou=sysusers,dc=ocis,dc=test",
|
||||
UserObjectClass: "inetOrgPerson",
|
||||
GroupObjectClass: "groupOfNames",
|
||||
BindDN: "uid=reva,ou=sysusers,o=libregraph-idm",
|
||||
BindPassword: "reva",
|
||||
IDP: "https://localhost:9200",
|
||||
UserSchema: config.LDAPUserSchema{
|
||||
ID: "ownclouduuid",
|
||||
Mail: "mail",
|
||||
DisplayName: "displayname",
|
||||
Username: "cn",
|
||||
Username: "uid",
|
||||
},
|
||||
GroupSchema: config.LDAPGroupSchema{
|
||||
ID: "cn",
|
||||
ID: "ownclouduuid",
|
||||
Mail: "mail",
|
||||
DisplayName: "cn",
|
||||
Groupname: "cn",
|
||||
Member: "cn",
|
||||
Member: "member",
|
||||
},
|
||||
},
|
||||
JSON: config.JSONDriver{},
|
||||
|
||||
Reference in New Issue
Block a user