mirror of
https://github.com/dbeaver/cloudbeaver.git
synced 2026-09-24 16:04:36 +08:00
#8 Users and roles model
This commit is contained in:
@@ -35,8 +35,36 @@
|
||||
</extension>
|
||||
|
||||
<extension point="io.cloudbeaver.service">
|
||||
<service id="navigator" label="Database navigator" description="Database navigator services" class="io.cloudbeaver.service.navigator.WebServiceBindingNavigator"/>
|
||||
<service id="sql" label="SQL processing" description="SQL processing and data read services" class="io.cloudbeaver.service.sql.WebServiceBindingSQL"/>
|
||||
<service id="navigator" label="Database navigator" description="Database navigator services" class="io.cloudbeaver.service.navigator.WebServiceBindingNavigator">
|
||||
<premission id="navigate" label="Navigate over database metadata"/>
|
||||
</service>
|
||||
<service id="sql" label="SQL processing" description="SQL processing and data read services" class="io.cloudbeaver.service.sql.WebServiceBindingSQL">
|
||||
<premission id="data.read" label="Data read"/>
|
||||
<premission id="data.update" label="Data update"/>
|
||||
<premission id="data.insert" label="Data insert"/>
|
||||
<premission id="data.delete" label="Data delete"/>
|
||||
<premission id="sql.execute" label="SQL execute"/>
|
||||
</service>
|
||||
|
||||
<authProvider>
|
||||
<propertyGroup label="%dataTransfer.processor.xlsx.propertyGroup.general.label">
|
||||
<property id="extension" label="%dataTransfer.processor.xlsx.property.extension.label" defaultValue="xlsx"/>
|
||||
|
||||
<property id="rownumber" label="%dataTransfer.processor.xlsx.property.rowNumber.name" type="boolean" description="%dataTransfer.processor.xlsx.property.rowNumber.description" defaultValue="yes" required="false"/>
|
||||
<property id="border" label="%dataTransfer.processor.xlsx.property.border.name" type="string" description="%dataTransfer.processor.xlsx.property.border.description" defaultValue="THIN" required="false" validValues="NONE,THIN,THICK"/>
|
||||
<property id="nullString" label="%dataTransfer.processor.xlsx.property.nullString.name" type="string" description="%dataTransfer.processor.xlsx.property.nullString.description" defaultValue="" required="false"/>
|
||||
<property id="header" label="%dataTransfer.processor.xlsx.property.header.name" type="boolean" description="%dataTransfer.processor.xlsx.property.header.description" defaultValue="true" required="true"/>
|
||||
<property id="headerfont" label="%dataTransfer.processor.xlsx.property.headerFont.name" type="string" description="%dataTransfer.processor.xlsx.property.headerFont.description" defaultValue="BOLD" required="false" validValues="NONE,BOLD,ITALIC,STRIKEOUT,UNDERLINE"/>
|
||||
<property id="trueString" label="%dataTransfer.processor.xlsx.property.boolStringTrue.name" type="string" description="%dataTransfer.processor.xlsx.property.boolStringTrue.description" defaultValue="true" required="false"/>
|
||||
<property id="falseString" label="%dataTransfer.processor.xlsx.property.boolStringFalse.name" type="string" description="%dataTransfer.processor.xlsx.property.boolStringFalse.description" defaultValue="false" required="false"/>
|
||||
<property id="exportSql" label="%dataTransfer.processor.xlsx.property.exportSql.name" type="boolean" description="%dataTransfer.processor.xlsx.property.exportSql.description" defaultValue="false" required="false"/>
|
||||
<property id="splitSqlText" label="%dataTransfer.processor.xlsx.property.splitSqlText.name" type="boolean" description="%dataTransfer.processor.xlsx.property.splitSqlText.description" defaultValue="false" required="false"/>
|
||||
<property id="splitByRowCount" label="%dataTransfer.processor.xlsx.property.splitByRowCount.name" type="integer" description="%dataTransfer.processor.xlsx.property.splitByRowCount.description" defaultValue="1048575" required="false"/>
|
||||
<property id="splitByColNum" label="%dataTransfer.processor.xlsx.property.splitByColNum.name" type="integer" description="%dataTransfer.processor.xlsx.property.splitByColNum.description" defaultValue="0" required="false"/>
|
||||
<property id="dateFormat" label="%dataTransfer.processor.xlsx.property.dateFormat.name" type="string" description="%dataTransfer.processor.xlsx.property.dateFormat.description" defaultValue="m/d/yy" required="false" validValues="m/d/yy,d-mmm-yy,d-mmm,mmm-yy,h:mm AM/PM,h:mm:ss AM/PM,h:mm,h:mm:ss,m/d/yy h:mm"/>
|
||||
</propertyGroup>
|
||||
|
||||
</authProvider>
|
||||
</extension>
|
||||
|
||||
</plugin>
|
||||
|
||||
@@ -18,6 +18,7 @@ package io.cloudbeaver.model.session;
|
||||
|
||||
import io.cloudbeaver.DBWebException;
|
||||
import io.cloudbeaver.WebServiceUtils;
|
||||
import io.cloudbeaver.model.user.WebUser;
|
||||
import io.cloudbeaver.server.CloudbeaverConstants;
|
||||
import io.cloudbeaver.server.CloudbeaverPlatform;
|
||||
import io.cloudbeaver.model.*;
|
||||
@@ -68,6 +69,7 @@ public class WebSession {
|
||||
private long createTime;
|
||||
private long lastAccessTime;
|
||||
|
||||
private WebUser user;
|
||||
private String locale;
|
||||
|
||||
private final List<WebConnectionInfo> connections = new ArrayList<>();
|
||||
@@ -126,6 +128,14 @@ public class WebSession {
|
||||
return lastAccessTime;
|
||||
}
|
||||
|
||||
public WebUser getUser() {
|
||||
return user;
|
||||
}
|
||||
|
||||
public void setUser(WebUser user) {
|
||||
this.user = user;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getLocale() {
|
||||
return locale;
|
||||
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* DBeaver - Universal Database Manager
|
||||
* Copyright (C) 2010-2020 DBeaver Corp and others
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.cloudbeaver.model.user;
|
||||
|
||||
import io.cloudbeaver.server.registry.WebAuthProviderDescriptor;
|
||||
import io.cloudbeaver.server.registry.WebPermissionDescriptor;
|
||||
import org.jkiss.dbeaver.Log;
|
||||
|
||||
/**
|
||||
* Web user.
|
||||
*/
|
||||
public class WebAuthProvider {
|
||||
|
||||
private static final Log log = Log.getLog(WebAuthProvider.class);
|
||||
|
||||
private final WebAuthProviderDescriptor descriptor;
|
||||
|
||||
public WebAuthProvider(WebAuthProviderDescriptor descriptor) {
|
||||
this.descriptor = descriptor;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return descriptor.getId();
|
||||
}
|
||||
|
||||
public String getLabel() {
|
||||
return descriptor.getLabel();
|
||||
}
|
||||
|
||||
public String getIcon() {
|
||||
return descriptor.getIcon();
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return descriptor.getDescription();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getId();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* DBeaver - Universal Database Manager
|
||||
* Copyright (C) 2010-2020 DBeaver Corp and others
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.cloudbeaver.model.user;
|
||||
|
||||
import io.cloudbeaver.server.registry.WebPermissionDescriptor;
|
||||
import org.jkiss.dbeaver.Log;
|
||||
|
||||
/**
|
||||
* Web user.
|
||||
*/
|
||||
public class WebPermission {
|
||||
|
||||
private static final Log log = Log.getLog(WebPermission.class);
|
||||
|
||||
private final WebPermissionDescriptor descriptor;
|
||||
|
||||
public WebPermission(WebPermissionDescriptor descriptor) {
|
||||
this.descriptor = descriptor;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return descriptor.getId();
|
||||
}
|
||||
|
||||
public String getLabel() {
|
||||
return descriptor.getLabel();
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return descriptor.getDescription();
|
||||
}
|
||||
|
||||
public String getProvider() {
|
||||
return descriptor.getService().getLabel();
|
||||
}
|
||||
|
||||
public String getCategory() {
|
||||
return descriptor.getCategory();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getId();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* DBeaver - Universal Database Manager
|
||||
* Copyright (C) 2010-2020 DBeaver Corp and others
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.cloudbeaver.model.user;
|
||||
|
||||
import org.jkiss.dbeaver.Log;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Web role.
|
||||
*/
|
||||
public class WebRole {
|
||||
|
||||
private static final Log log = Log.getLog(WebRole.class);
|
||||
|
||||
private String id;
|
||||
private String label;
|
||||
private String icon;
|
||||
private String description;
|
||||
|
||||
private Set<String> permissions = new LinkedHashSet<>();
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public String getLabel() {
|
||||
return label;
|
||||
}
|
||||
|
||||
public String getIcon() {
|
||||
return icon;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public Set<String> getPermissions() {
|
||||
return Collections.unmodifiableSet(permissions);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return id;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* DBeaver - Universal Database Manager
|
||||
* Copyright (C) 2010-2020 DBeaver Corp and others
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.cloudbeaver.model.user;
|
||||
|
||||
import org.jkiss.dbeaver.Log;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Web user.
|
||||
*/
|
||||
public class WebUser {
|
||||
|
||||
private static final Log log = Log.getLog(WebUser.class);
|
||||
|
||||
private String userName;
|
||||
|
||||
private Map<String, Object> metaParameters = new LinkedHashMap<>();
|
||||
private Map<String, Object> configurationParameters = new LinkedHashMap<>();
|
||||
|
||||
private Set<WebRole> roles = new LinkedHashSet<>();
|
||||
|
||||
private String activeAuthModel;
|
||||
private Map<String, Map<String, Object>> authCredentials = new HashMap<>();
|
||||
|
||||
public String[] getGrantedRoles() {
|
||||
return roles.stream().map(WebRole::getId).toArray(String[]::new);
|
||||
}
|
||||
|
||||
public String getUserName() {
|
||||
return userName;
|
||||
}
|
||||
|
||||
public Map<String, Object> getMetaParameters() {
|
||||
return Collections.unmodifiableMap(metaParameters);
|
||||
}
|
||||
|
||||
public Map<String, Object> getConfigurationParameters() {
|
||||
return Collections.unmodifiableMap(configurationParameters);
|
||||
}
|
||||
|
||||
public Set<WebRole> getRoles() {
|
||||
return Collections.unmodifiableSet(roles);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return userName;
|
||||
}
|
||||
}
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* DBeaver - Universal Database Manager
|
||||
* Copyright (C) 2010-2020 DBeaver Corp and others
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.cloudbeaver.model.user;
|
||||
|
||||
/**
|
||||
* Web user.
|
||||
*/
|
||||
public class WebUserCredentials {
|
||||
|
||||
}
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* DBeaver - Universal Database Manager
|
||||
* Copyright (C) 2010-2020 DBeaver Corp and others
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.cloudbeaver.server.registry;
|
||||
|
||||
import org.eclipse.core.runtime.IConfigurationElement;
|
||||
|
||||
/**
|
||||
* Auth service descriptor
|
||||
*/
|
||||
public class WebAuthProviderDescriptor {
|
||||
|
||||
private final IConfigurationElement cfg;
|
||||
|
||||
public WebAuthProviderDescriptor(IConfigurationElement cfg) {
|
||||
this.cfg = cfg;;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return cfg.getAttribute("id");
|
||||
}
|
||||
|
||||
public String getLabel() {
|
||||
return cfg.getAttribute("label");
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return cfg.getAttribute("description");
|
||||
}
|
||||
|
||||
public String getIcon() {
|
||||
return cfg.getAttribute("icon");
|
||||
}
|
||||
}
|
||||
+53
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* DBeaver - Universal Database Manager
|
||||
* Copyright (C) 2010-2020 DBeaver Corp and others
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.cloudbeaver.server.registry;
|
||||
|
||||
import org.eclipse.core.runtime.IConfigurationElement;
|
||||
|
||||
/**
|
||||
* Web connection info
|
||||
*/
|
||||
public class WebPermissionDescriptor {
|
||||
|
||||
private final WebServiceDescriptor service;
|
||||
private final IConfigurationElement cfg;
|
||||
|
||||
public WebPermissionDescriptor(WebServiceDescriptor service, IConfigurationElement cfg) {
|
||||
this.service = service;
|
||||
this.cfg = cfg;;
|
||||
}
|
||||
|
||||
public WebServiceDescriptor getService() {
|
||||
return service;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return cfg.getAttribute("id");
|
||||
}
|
||||
|
||||
public String getLabel() {
|
||||
return cfg.getAttribute("label");
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return cfg.getAttribute("description");
|
||||
}
|
||||
|
||||
public String getCategory() {
|
||||
return cfg.getAttribute("category");
|
||||
}
|
||||
}
|
||||
+12
@@ -22,6 +22,9 @@ import org.eclipse.core.runtime.IConfigurationElement;
|
||||
import org.jkiss.dbeaver.DBException;
|
||||
import org.jkiss.dbeaver.model.impl.AbstractContextDescriptor;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* WebServiceDescriptor
|
||||
*/
|
||||
@@ -35,6 +38,7 @@ public class WebServiceDescriptor extends AbstractContextDescriptor {
|
||||
private final ObjectType implClass;
|
||||
|
||||
private DBWServiceBinding instance;
|
||||
private final List<WebPermissionDescriptor> permissions = new ArrayList<>();
|
||||
|
||||
public WebServiceDescriptor(IConfigurationElement config)
|
||||
{
|
||||
@@ -43,6 +47,10 @@ public class WebServiceDescriptor extends AbstractContextDescriptor {
|
||||
this.label = config.getAttribute("label");
|
||||
this.description = config.getAttribute("description");
|
||||
this.implClass = new ObjectType(config.getAttribute("class"));
|
||||
|
||||
for (IConfigurationElement pc : config.getChildren("permission")) {
|
||||
permissions.add(new WebPermissionDescriptor(this, pc));
|
||||
}
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
@@ -57,6 +65,10 @@ public class WebServiceDescriptor extends AbstractContextDescriptor {
|
||||
return description;
|
||||
}
|
||||
|
||||
public List<WebPermissionDescriptor> getPermissions() {
|
||||
return permissions;
|
||||
}
|
||||
|
||||
public DBWServiceBinding getInstance()
|
||||
throws DBException
|
||||
{
|
||||
|
||||
+17
@@ -23,13 +23,16 @@ import org.eclipse.core.runtime.Platform;
|
||||
import org.jkiss.dbeaver.Log;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class WebServiceRegistry {
|
||||
|
||||
private static final Log log = Log.getLog(WebServiceRegistry.class);
|
||||
|
||||
private static final String TAG_SERVICE = "service"; //$NON-NLS-1$
|
||||
private static final String TAG_AUTH_MODEL = "authProvider"; //$NON-NLS-1$
|
||||
|
||||
private static WebServiceRegistry instance = null;
|
||||
|
||||
@@ -44,6 +47,8 @@ public class WebServiceRegistry {
|
||||
private final List<WebServiceDescriptor> webServices = new ArrayList<>();
|
||||
private DBWServiceBinding[] webServiceInstances;
|
||||
|
||||
private final Map<String, WebAuthProviderDescriptor> authProviders = new LinkedHashMap<>();
|
||||
|
||||
private WebServiceRegistry() {
|
||||
}
|
||||
|
||||
@@ -55,6 +60,9 @@ public class WebServiceRegistry {
|
||||
if (TAG_SERVICE.equals(ext.getName())) {
|
||||
this.webServices.add(
|
||||
new WebServiceDescriptor(ext));
|
||||
} else if (TAG_AUTH_MODEL.equals(ext.getName())) {
|
||||
WebAuthProviderDescriptor providerDescriptor = new WebAuthProviderDescriptor(ext);
|
||||
this.authProviders.put(providerDescriptor.getId(), providerDescriptor);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -94,4 +102,13 @@ public class WebServiceRegistry {
|
||||
public DBWServiceBinding[] getWebServiceInstances() {
|
||||
return webServiceInstances;
|
||||
}
|
||||
|
||||
public List<WebAuthProviderDescriptor> getAuthProviders() {
|
||||
return new ArrayList<>(authProviders.values());
|
||||
}
|
||||
|
||||
public WebAuthProviderDescriptor getAuthProvider(String id) {
|
||||
return authProviders.get(id);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
type AdminUserInfo {
|
||||
userName: ID!
|
||||
|
||||
metaParameters: Object!
|
||||
configurationParameters: Object!
|
||||
grantedRoles: [ID]!
|
||||
}
|
||||
|
||||
@@ -13,9 +15,10 @@ type AdminRoleInfo {
|
||||
|
||||
type AdminPermissionInfo {
|
||||
id: ID!
|
||||
|
||||
label: [String]
|
||||
description: [String]
|
||||
|
||||
provider: String!
|
||||
category: String
|
||||
}
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ type AuthCredentialInfo {
|
||||
order: Int
|
||||
}
|
||||
|
||||
type AuthModelInfo {
|
||||
type AuthProviderInfo {
|
||||
id: ID!
|
||||
label: String!
|
||||
icon: ID
|
||||
@@ -30,12 +30,12 @@ type UserAuthInfo {
|
||||
|
||||
extend type Query {
|
||||
|
||||
authLogin(model: ID!, credentials: Object!): UserAuthInfo
|
||||
authLogin(provider: ID!, credentials: Object!): UserAuthInfo
|
||||
|
||||
authLogout: Boolean
|
||||
|
||||
sessionUser: UserAuthInfo
|
||||
|
||||
authModels: [AuthModelInfo]!
|
||||
authModels: [AuthProviderInfo]!
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user