mirror of
https://github.com/Kingsrook/qqq.git
synced 2025-07-18 05:01:07 +00:00
cehckpoint - adding security to openapi spec
This commit is contained in:
@ -75,7 +75,20 @@ public class PermissionsHelper
|
|||||||
warnAboutPermissionSubTypeForTables(permissionSubType);
|
warnAboutPermissionSubTypeForTables(permissionSubType);
|
||||||
QTableMetaData table = QContext.getQInstance().getTable(tableName);
|
QTableMetaData table = QContext.getQInstance().getTable(tableName);
|
||||||
|
|
||||||
commonCheckPermissionThrowing(getEffectivePermissionRules(table, QContext.getQInstance()), permissionSubType, table.getName(), actionInput);
|
commonCheckPermissionThrowing(getEffectivePermissionRules(table, QContext.getQInstance()), permissionSubType, table.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public static String getTablePermissionName(String tableName, TablePermissionSubType permissionSubType)
|
||||||
|
{
|
||||||
|
QInstance qInstance = QContext.getQInstance();
|
||||||
|
QPermissionRules rules = getEffectivePermissionRules(qInstance.getTable(tableName), qInstance);
|
||||||
|
String permissionBaseName = getEffectivePermissionBaseName(rules, tableName);
|
||||||
|
return (getPermissionName(permissionBaseName, permissionSubType));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -181,7 +194,7 @@ public class PermissionsHelper
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
commonCheckPermissionThrowing(effectivePermissionRules, PrivatePermissionSubType.HAS_ACCESS, process.getName(), actionInput);
|
commonCheckPermissionThrowing(effectivePermissionRules, PrivatePermissionSubType.HAS_ACCESS, process.getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -210,7 +223,7 @@ public class PermissionsHelper
|
|||||||
public static void checkAppPermissionThrowing(AbstractActionInput actionInput, String appName) throws QPermissionDeniedException
|
public static void checkAppPermissionThrowing(AbstractActionInput actionInput, String appName) throws QPermissionDeniedException
|
||||||
{
|
{
|
||||||
QAppMetaData app = QContext.getQInstance().getApp(appName);
|
QAppMetaData app = QContext.getQInstance().getApp(appName);
|
||||||
commonCheckPermissionThrowing(getEffectivePermissionRules(app, QContext.getQInstance()), PrivatePermissionSubType.HAS_ACCESS, app.getName(), actionInput);
|
commonCheckPermissionThrowing(getEffectivePermissionRules(app, QContext.getQInstance()), PrivatePermissionSubType.HAS_ACCESS, app.getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -239,7 +252,7 @@ public class PermissionsHelper
|
|||||||
public static void checkReportPermissionThrowing(AbstractActionInput actionInput, String reportName) throws QPermissionDeniedException
|
public static void checkReportPermissionThrowing(AbstractActionInput actionInput, String reportName) throws QPermissionDeniedException
|
||||||
{
|
{
|
||||||
QReportMetaData report = QContext.getQInstance().getReport(reportName);
|
QReportMetaData report = QContext.getQInstance().getReport(reportName);
|
||||||
commonCheckPermissionThrowing(getEffectivePermissionRules(report, QContext.getQInstance()), PrivatePermissionSubType.HAS_ACCESS, report.getName(), actionInput);
|
commonCheckPermissionThrowing(getEffectivePermissionRules(report, QContext.getQInstance()), PrivatePermissionSubType.HAS_ACCESS, report.getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -268,7 +281,7 @@ public class PermissionsHelper
|
|||||||
public static void checkWidgetPermissionThrowing(AbstractActionInput actionInput, String widgetName) throws QPermissionDeniedException
|
public static void checkWidgetPermissionThrowing(AbstractActionInput actionInput, String widgetName) throws QPermissionDeniedException
|
||||||
{
|
{
|
||||||
QWidgetMetaDataInterface widget = QContext.getQInstance().getWidget(widgetName);
|
QWidgetMetaDataInterface widget = QContext.getQInstance().getWidget(widgetName);
|
||||||
commonCheckPermissionThrowing(getEffectivePermissionRules(widget, QContext.getQInstance()), PrivatePermissionSubType.HAS_ACCESS, widget.getName(), actionInput);
|
commonCheckPermissionThrowing(getEffectivePermissionRules(widget, QContext.getQInstance()), PrivatePermissionSubType.HAS_ACCESS, widget.getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -524,7 +537,7 @@ public class PermissionsHelper
|
|||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
**
|
**
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
private static void commonCheckPermissionThrowing(QPermissionRules rules, PermissionSubType permissionSubType, String name, AbstractActionInput actionInput) throws QPermissionDeniedException
|
private static void commonCheckPermissionThrowing(QPermissionRules rules, PermissionSubType permissionSubType, String name) throws QPermissionDeniedException
|
||||||
{
|
{
|
||||||
PermissionSubType effectivePermissionSubType = getEffectivePermissionSubType(rules, permissionSubType);
|
PermissionSubType effectivePermissionSubType = getEffectivePermissionSubType(rules, permissionSubType);
|
||||||
String permissionBaseName = getEffectivePermissionBaseName(rules, name);
|
String permissionBaseName = getEffectivePermissionBaseName(rules, name);
|
||||||
|
@ -37,14 +37,19 @@ import com.kingsrook.qqq.api.model.openapi.ExampleWithListValue;
|
|||||||
import com.kingsrook.qqq.api.model.openapi.ExampleWithSingleValue;
|
import com.kingsrook.qqq.api.model.openapi.ExampleWithSingleValue;
|
||||||
import com.kingsrook.qqq.api.model.openapi.Info;
|
import com.kingsrook.qqq.api.model.openapi.Info;
|
||||||
import com.kingsrook.qqq.api.model.openapi.Method;
|
import com.kingsrook.qqq.api.model.openapi.Method;
|
||||||
|
import com.kingsrook.qqq.api.model.openapi.OAuth2;
|
||||||
|
import com.kingsrook.qqq.api.model.openapi.OAuth2Flow;
|
||||||
import com.kingsrook.qqq.api.model.openapi.OpenAPI;
|
import com.kingsrook.qqq.api.model.openapi.OpenAPI;
|
||||||
import com.kingsrook.qqq.api.model.openapi.Parameter;
|
import com.kingsrook.qqq.api.model.openapi.Parameter;
|
||||||
import com.kingsrook.qqq.api.model.openapi.Path;
|
import com.kingsrook.qqq.api.model.openapi.Path;
|
||||||
import com.kingsrook.qqq.api.model.openapi.Response;
|
import com.kingsrook.qqq.api.model.openapi.Response;
|
||||||
import com.kingsrook.qqq.api.model.openapi.Schema;
|
import com.kingsrook.qqq.api.model.openapi.Schema;
|
||||||
|
import com.kingsrook.qqq.api.model.openapi.SecurityScheme;
|
||||||
import com.kingsrook.qqq.api.model.openapi.Server;
|
import com.kingsrook.qqq.api.model.openapi.Server;
|
||||||
import com.kingsrook.qqq.api.model.openapi.Tag;
|
import com.kingsrook.qqq.api.model.openapi.Tag;
|
||||||
import com.kingsrook.qqq.backend.core.actions.AbstractQActionFunction;
|
import com.kingsrook.qqq.backend.core.actions.AbstractQActionFunction;
|
||||||
|
import com.kingsrook.qqq.backend.core.actions.permissions.PermissionsHelper;
|
||||||
|
import com.kingsrook.qqq.backend.core.actions.permissions.TablePermissionSubType;
|
||||||
import com.kingsrook.qqq.backend.core.context.QContext;
|
import com.kingsrook.qqq.backend.core.context.QContext;
|
||||||
import com.kingsrook.qqq.backend.core.exceptions.QException;
|
import com.kingsrook.qqq.backend.core.exceptions.QException;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.QInstance;
|
import com.kingsrook.qqq.backend.core.model.metadata.QInstance;
|
||||||
@ -93,9 +98,20 @@ public class GenerateOpenApiSpecAction extends AbstractQActionFunction<GenerateO
|
|||||||
|
|
||||||
LinkedHashMap<Integer, Response> componentResponses = new LinkedHashMap<>();
|
LinkedHashMap<Integer, Response> componentResponses = new LinkedHashMap<>();
|
||||||
LinkedHashMap<String, Schema> componentSchemas = new LinkedHashMap<>();
|
LinkedHashMap<String, Schema> componentSchemas = new LinkedHashMap<>();
|
||||||
|
LinkedHashMap<String, SecurityScheme> securitySchemes = new LinkedHashMap<>();
|
||||||
openAPI.setComponents(new Components()
|
openAPI.setComponents(new Components()
|
||||||
.withSchemas(componentSchemas)
|
.withSchemas(componentSchemas)
|
||||||
.withResponses(componentResponses)
|
.withResponses(componentResponses)
|
||||||
|
.withSecuritySchemes(securitySchemes)
|
||||||
|
);
|
||||||
|
|
||||||
|
LinkedHashMap<String, String> scopes = new LinkedHashMap<>();
|
||||||
|
securitySchemes.put("OAuth2", new OAuth2()
|
||||||
|
.withFlows(MapBuilder.of("authorizationCode", new OAuth2Flow()
|
||||||
|
.withAuthorizationUrl("https://nutrifresh-one-development.us.auth0.com/authorize")
|
||||||
|
.withTokenUrl("https://nutrifresh-one-development.us.auth0.com/oauth/token")
|
||||||
|
.withScopes(scopes)
|
||||||
|
))
|
||||||
);
|
);
|
||||||
|
|
||||||
componentSchemas.put("baseSearchResultFields", new Schema()
|
componentSchemas.put("baseSearchResultFields", new Schema()
|
||||||
@ -131,6 +147,12 @@ public class GenerateOpenApiSpecAction extends AbstractQActionFunction<GenerateO
|
|||||||
|
|
||||||
List<? extends QFieldMetaData> tableApiFields = new GetTableApiFieldsAction().execute(new GetTableApiFieldsInput().withTableName(tableName).withVersion(version)).getFields();
|
List<? extends QFieldMetaData> tableApiFields = new GetTableApiFieldsAction().execute(new GetTableApiFieldsInput().withTableName(tableName).withVersion(version)).getFields();
|
||||||
|
|
||||||
|
String tableReadPermissionName = PermissionsHelper.getTablePermissionName(tableName, TablePermissionSubType.READ);
|
||||||
|
if(StringUtils.hasContent(tableReadPermissionName))
|
||||||
|
{
|
||||||
|
scopes.put(tableReadPermissionName, "Permission to read the " + tableLabel + " table");
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////
|
////////////////////////
|
||||||
// tag for this table //
|
// tag for this table //
|
||||||
////////////////////////
|
////////////////////////
|
||||||
@ -224,7 +246,9 @@ public class GenerateOpenApiSpecAction extends AbstractQActionFunction<GenerateO
|
|||||||
.withContent(MapBuilder.of("application/json", new Content()
|
.withContent(MapBuilder.of("application/json", new Content()
|
||||||
.withSchema(new Schema().withRef("#/components/schemas/" + tableName + "SearchResult"))
|
.withSchema(new Schema().withRef("#/components/schemas/" + tableName + "SearchResult"))
|
||||||
))
|
))
|
||||||
);
|
).withSecurity(ListBuilder.of(MapBuilder.of(
|
||||||
|
"OAuth2", List.of(tableReadPermissionName)
|
||||||
|
)));
|
||||||
|
|
||||||
for(QFieldMetaData tableApiField : tableApiFields)
|
for(QFieldMetaData tableApiField : tableApiFields)
|
||||||
{
|
{
|
||||||
|
@ -23,6 +23,7 @@ package com.kingsrook.qqq.api.model.metadata;
|
|||||||
|
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import com.kingsrook.qqq.api.ApiMiddlewareType;
|
||||||
import com.kingsrook.qqq.api.model.APIVersion;
|
import com.kingsrook.qqq.api.model.APIVersion;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.QInstance;
|
import com.kingsrook.qqq.backend.core.model.metadata.QInstance;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.QMiddlewareInstanceMetaData;
|
import com.kingsrook.qqq.backend.core.model.metadata.QMiddlewareInstanceMetaData;
|
||||||
@ -40,6 +41,17 @@ public class ApiInstanceMetaData extends QMiddlewareInstanceMetaData
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Constructor
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public ApiInstanceMetaData()
|
||||||
|
{
|
||||||
|
setType(ApiMiddlewareType.NAME);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
**
|
**
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
@ -33,6 +33,7 @@ public class Components
|
|||||||
private Map<String, Example> examples;
|
private Map<String, Example> examples;
|
||||||
private Map<String, Schema> schemas;
|
private Map<String, Schema> schemas;
|
||||||
private Map<Integer, Response> responses;
|
private Map<Integer, Response> responses;
|
||||||
|
private Map<String, SecurityScheme> securitySchemes;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -127,4 +128,35 @@ public class Components
|
|||||||
return (this);
|
return (this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Getter for securitySchemes
|
||||||
|
*******************************************************************************/
|
||||||
|
public Map<String, SecurityScheme> getSecuritySchemes()
|
||||||
|
{
|
||||||
|
return (this.securitySchemes);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Setter for securitySchemes
|
||||||
|
*******************************************************************************/
|
||||||
|
public void setSecuritySchemes(Map<String, SecurityScheme> securitySchemes)
|
||||||
|
{
|
||||||
|
this.securitySchemes = securitySchemes;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Fluent setter for securitySchemes
|
||||||
|
*******************************************************************************/
|
||||||
|
public Components withSecuritySchemes(Map<String, SecurityScheme> securitySchemes)
|
||||||
|
{
|
||||||
|
this.securitySchemes = securitySchemes;
|
||||||
|
return (this);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -41,6 +41,8 @@ public class Method
|
|||||||
private List<Parameter> parameters;
|
private List<Parameter> parameters;
|
||||||
private Map<Integer, Response> responses;
|
private Map<Integer, Response> responses;
|
||||||
|
|
||||||
|
private List<Map<String, List<String>>> security;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
@ -303,4 +305,36 @@ public class Method
|
|||||||
this.responses.put(code, response);
|
this.responses.put(code, response);
|
||||||
return (this);
|
return (this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Getter for security
|
||||||
|
*******************************************************************************/
|
||||||
|
public List<Map<String, List<String>>> getSecurity()
|
||||||
|
{
|
||||||
|
return (this.security);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Setter for security
|
||||||
|
*******************************************************************************/
|
||||||
|
public void setSecurity(List<Map<String, List<String>>> security)
|
||||||
|
{
|
||||||
|
this.security = security;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Fluent setter for security
|
||||||
|
*******************************************************************************/
|
||||||
|
public Method withSecurity(List<Map<String, List<String>>> security)
|
||||||
|
{
|
||||||
|
this.security = security;
|
||||||
|
return (this);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,77 @@
|
|||||||
|
/*
|
||||||
|
* QQQ - Low-code Application Framework for Engineers.
|
||||||
|
* Copyright (C) 2021-2023. Kingsrook, LLC
|
||||||
|
* 651 N Broad St Ste 205 # 6917 | Middletown DE 19709 | United States
|
||||||
|
* contact@kingsrook.com
|
||||||
|
* https://github.com/Kingsrook/
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of the
|
||||||
|
* License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.kingsrook.qqq.api.model.openapi;
|
||||||
|
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public class OAuth2 extends SecurityScheme
|
||||||
|
{
|
||||||
|
private Map<String, OAuth2Flow> flows;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Constructor
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public OAuth2()
|
||||||
|
{
|
||||||
|
setType("oauth2");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Getter for flows
|
||||||
|
*******************************************************************************/
|
||||||
|
public Map<String, OAuth2Flow> getFlows()
|
||||||
|
{
|
||||||
|
return (this.flows);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Setter for flows
|
||||||
|
*******************************************************************************/
|
||||||
|
public void setFlows(Map<String, OAuth2Flow> flows)
|
||||||
|
{
|
||||||
|
this.flows = flows;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Fluent setter for flows
|
||||||
|
*******************************************************************************/
|
||||||
|
public OAuth2 withFlows(Map<String, OAuth2Flow> flows)
|
||||||
|
{
|
||||||
|
this.flows = flows;
|
||||||
|
return (this);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,130 @@
|
|||||||
|
/*
|
||||||
|
* QQQ - Low-code Application Framework for Engineers.
|
||||||
|
* Copyright (C) 2021-2023. Kingsrook, LLC
|
||||||
|
* 651 N Broad St Ste 205 # 6917 | Middletown DE 19709 | United States
|
||||||
|
* contact@kingsrook.com
|
||||||
|
* https://github.com/Kingsrook/
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of the
|
||||||
|
* License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.kingsrook.qqq.api.model.openapi;
|
||||||
|
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public class OAuth2Flow
|
||||||
|
{
|
||||||
|
private String authorizationUrl;
|
||||||
|
private String tokenUrl;
|
||||||
|
private Map<String, String> scopes;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Getter for authorizationUrl
|
||||||
|
*******************************************************************************/
|
||||||
|
public String getAuthorizationUrl()
|
||||||
|
{
|
||||||
|
return (this.authorizationUrl);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Setter for authorizationUrl
|
||||||
|
*******************************************************************************/
|
||||||
|
public void setAuthorizationUrl(String authorizationUrl)
|
||||||
|
{
|
||||||
|
this.authorizationUrl = authorizationUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Fluent setter for authorizationUrl
|
||||||
|
*******************************************************************************/
|
||||||
|
public OAuth2Flow withAuthorizationUrl(String authorizationUrl)
|
||||||
|
{
|
||||||
|
this.authorizationUrl = authorizationUrl;
|
||||||
|
return (this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Getter for tokenUrl
|
||||||
|
*******************************************************************************/
|
||||||
|
public String getTokenUrl()
|
||||||
|
{
|
||||||
|
return (this.tokenUrl);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Setter for tokenUrl
|
||||||
|
*******************************************************************************/
|
||||||
|
public void setTokenUrl(String tokenUrl)
|
||||||
|
{
|
||||||
|
this.tokenUrl = tokenUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Fluent setter for tokenUrl
|
||||||
|
*******************************************************************************/
|
||||||
|
public OAuth2Flow withTokenUrl(String tokenUrl)
|
||||||
|
{
|
||||||
|
this.tokenUrl = tokenUrl;
|
||||||
|
return (this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Getter for scopes
|
||||||
|
*******************************************************************************/
|
||||||
|
public Map<String, String> getScopes()
|
||||||
|
{
|
||||||
|
return (this.scopes);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Setter for scopes
|
||||||
|
*******************************************************************************/
|
||||||
|
public void setScopes(Map<String, String> scopes)
|
||||||
|
{
|
||||||
|
this.scopes = scopes;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Fluent setter for scopes
|
||||||
|
*******************************************************************************/
|
||||||
|
public OAuth2Flow withScopes(Map<String, String> scopes)
|
||||||
|
{
|
||||||
|
this.scopes = scopes;
|
||||||
|
return (this);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,63 @@
|
|||||||
|
/*
|
||||||
|
* QQQ - Low-code Application Framework for Engineers.
|
||||||
|
* Copyright (C) 2021-2023. Kingsrook, LLC
|
||||||
|
* 651 N Broad St Ste 205 # 6917 | Middletown DE 19709 | United States
|
||||||
|
* contact@kingsrook.com
|
||||||
|
* https://github.com/Kingsrook/
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of the
|
||||||
|
* License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.kingsrook.qqq.api.model.openapi;
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public class SecurityScheme
|
||||||
|
{
|
||||||
|
private String type;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Getter for type
|
||||||
|
*******************************************************************************/
|
||||||
|
public String getType()
|
||||||
|
{
|
||||||
|
return (this.type);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Setter for type
|
||||||
|
*******************************************************************************/
|
||||||
|
public void setType(String type)
|
||||||
|
{
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Fluent setter for type
|
||||||
|
*******************************************************************************/
|
||||||
|
public SecurityScheme withType(String type)
|
||||||
|
{
|
||||||
|
this.type = type;
|
||||||
|
return (this);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -26,6 +26,7 @@ import com.kingsrook.qqq.backend.core.context.QContext;
|
|||||||
import com.kingsrook.qqq.backend.core.logging.QLogger;
|
import com.kingsrook.qqq.backend.core.logging.QLogger;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.QInstance;
|
import com.kingsrook.qqq.backend.core.model.metadata.QInstance;
|
||||||
import com.kingsrook.qqq.backend.core.model.session.QSession;
|
import com.kingsrook.qqq.backend.core.model.session.QSession;
|
||||||
|
import com.kingsrook.qqq.backend.core.modules.backend.implementations.memory.MemoryRecordStore;
|
||||||
import org.junit.jupiter.api.AfterEach;
|
import org.junit.jupiter.api.AfterEach;
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
|
|
||||||
@ -39,6 +40,18 @@ public class BaseTest
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
@BeforeEach
|
||||||
|
@AfterEach
|
||||||
|
void baseBeforeAndAfterEach()
|
||||||
|
{
|
||||||
|
MemoryRecordStore.fullReset();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
**
|
**
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
@ -22,6 +22,10 @@
|
|||||||
package com.kingsrook.qqq.api;
|
package com.kingsrook.qqq.api;
|
||||||
|
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import com.kingsrook.qqq.api.model.APIVersion;
|
||||||
|
import com.kingsrook.qqq.api.model.metadata.ApiInstanceMetaData;
|
||||||
|
import com.kingsrook.qqq.api.model.metadata.tables.ApiTableMetaData;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.QBackendMetaData;
|
import com.kingsrook.qqq.backend.core.model.metadata.QBackendMetaData;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.QInstance;
|
import com.kingsrook.qqq.backend.core.model.metadata.QInstance;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.fields.DisplayFormat;
|
import com.kingsrook.qqq.backend.core.model.metadata.fields.DisplayFormat;
|
||||||
@ -39,6 +43,8 @@ public class TestUtils
|
|||||||
public static final String MEMORY_BACKEND_NAME = "memory";
|
public static final String MEMORY_BACKEND_NAME = "memory";
|
||||||
private static final String TABLE_NAME_PERSON = "person";
|
private static final String TABLE_NAME_PERSON = "person";
|
||||||
|
|
||||||
|
private static final String API_VERSION = "2023.Q1";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
@ -51,6 +57,11 @@ public class TestUtils
|
|||||||
qInstance.addBackend(defineMemoryBackend());
|
qInstance.addBackend(defineMemoryBackend());
|
||||||
qInstance.addTable(defineTablePerson());
|
qInstance.addTable(defineTablePerson());
|
||||||
|
|
||||||
|
qInstance.withMiddlewareMetaData(new ApiInstanceMetaData()
|
||||||
|
.withCurrentVersion(new APIVersion(API_VERSION))
|
||||||
|
.withSupportedVersions(List.of(new APIVersion(API_VERSION)))
|
||||||
|
);
|
||||||
|
|
||||||
return (qInstance);
|
return (qInstance);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -77,6 +88,7 @@ public class TestUtils
|
|||||||
.withName(TABLE_NAME_PERSON)
|
.withName(TABLE_NAME_PERSON)
|
||||||
.withLabel("Person")
|
.withLabel("Person")
|
||||||
.withBackendName(MEMORY_BACKEND_NAME)
|
.withBackendName(MEMORY_BACKEND_NAME)
|
||||||
|
.withMiddlewareMetaData(new ApiTableMetaData().withInitialVersion(API_VERSION))
|
||||||
.withPrimaryKeyField("id")
|
.withPrimaryKeyField("id")
|
||||||
.withField(new QFieldMetaData("id", QFieldType.INTEGER).withIsEditable(false))
|
.withField(new QFieldMetaData("id", QFieldType.INTEGER).withIsEditable(false))
|
||||||
.withField(new QFieldMetaData("createDate", QFieldType.DATE_TIME).withIsEditable(false))
|
.withField(new QFieldMetaData("createDate", QFieldType.DATE_TIME).withIsEditable(false))
|
||||||
|
@ -0,0 +1,107 @@
|
|||||||
|
/*
|
||||||
|
* QQQ - Low-code Application Framework for Engineers.
|
||||||
|
* Copyright (C) 2021-2023. Kingsrook, LLC
|
||||||
|
* 651 N Broad St Ste 205 # 6917 | Middletown DE 19709 | United States
|
||||||
|
* contact@kingsrook.com
|
||||||
|
* https://github.com/Kingsrook/
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of the
|
||||||
|
* License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.kingsrook.qqq.api.javalin;
|
||||||
|
|
||||||
|
|
||||||
|
import com.kingsrook.qqq.api.TestUtils;
|
||||||
|
import com.kingsrook.qqq.backend.core.exceptions.QInstanceValidationException;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.metadata.QInstance;
|
||||||
|
import com.kingsrook.qqq.backend.javalin.QJavalinImplementation;
|
||||||
|
import kong.unirest.HttpResponse;
|
||||||
|
import kong.unirest.Unirest;
|
||||||
|
import org.junit.jupiter.api.AfterAll;
|
||||||
|
import org.junit.jupiter.api.BeforeAll;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Unit test for QJavalinApiHandler
|
||||||
|
*******************************************************************************/
|
||||||
|
class QJavalinApiHandlerTest
|
||||||
|
{
|
||||||
|
private static final int PORT = 6263;
|
||||||
|
protected static final String BASE_URL = "http://localhost:" + PORT;
|
||||||
|
|
||||||
|
private static final String VERSION = "2023.Q1";
|
||||||
|
|
||||||
|
protected static QJavalinImplementation qJavalinImplementation;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
@BeforeAll
|
||||||
|
static void beforeAll() throws QInstanceValidationException
|
||||||
|
{
|
||||||
|
QInstance qInstance = TestUtils.defineInstance();
|
||||||
|
qJavalinImplementation = new QJavalinImplementation(qInstance);
|
||||||
|
qJavalinImplementation.startJavalinServer(PORT);
|
||||||
|
qJavalinImplementation.getJavalinService().routes(new QJavalinApiHandler(qInstance).getRoutes());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Before the class (all) runs, start a javalin server.
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
@AfterAll
|
||||||
|
public static void afterAll()
|
||||||
|
{
|
||||||
|
qJavalinImplementation.stopJavalinServer();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
@Test
|
||||||
|
void testSpec()
|
||||||
|
{
|
||||||
|
HttpResponse<String> response = Unirest.get(BASE_URL + "/api/" + VERSION + "/openapi.yaml").asString();
|
||||||
|
System.out.println(response.getBody());
|
||||||
|
assertThat(response.getBody())
|
||||||
|
.contains("""
|
||||||
|
title: "QQQ API"
|
||||||
|
""")
|
||||||
|
.contains("""
|
||||||
|
/person/query:
|
||||||
|
""")
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
@Test
|
||||||
|
void testQuery()
|
||||||
|
{
|
||||||
|
HttpResponse<String> response = Unirest.get(BASE_URL + "/api/" + VERSION + "/person/query").asString();
|
||||||
|
System.out.println(response.getBody());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -208,7 +208,7 @@ public class QJavalinImplementation
|
|||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
**
|
**
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
void startJavalinServer(int port)
|
public void startJavalinServer(int port)
|
||||||
{
|
{
|
||||||
// todo port from arg
|
// todo port from arg
|
||||||
// todo base path from arg? - and then potentially multiple instances too (chosen based on the root path??)
|
// todo base path from arg? - and then potentially multiple instances too (chosen based on the root path??)
|
||||||
@ -221,6 +221,16 @@ public class QJavalinImplementation
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public Javalin getJavalinService()
|
||||||
|
{
|
||||||
|
return (service);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
**
|
**
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
@ -277,7 +287,7 @@ public class QJavalinImplementation
|
|||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
**
|
**
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
void stopJavalinServer()
|
public void stopJavalinServer()
|
||||||
{
|
{
|
||||||
service.stop();
|
service.stop();
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user