mirror of
https://github.com/sasjs/server.git
synced 2025-12-10 19:34:34 +00:00
chore: docs finalized for stp and others
This commit is contained in:
@@ -151,6 +151,28 @@ components:
|
||||
- tree
|
||||
type: object
|
||||
additionalProperties: false
|
||||
ExecuteReturnJsonResponse:
|
||||
properties:
|
||||
status:
|
||||
type: string
|
||||
log:
|
||||
type: string
|
||||
result:
|
||||
type: string
|
||||
message:
|
||||
type: string
|
||||
required:
|
||||
- status
|
||||
type: object
|
||||
additionalProperties: false
|
||||
ExecuteReturnJsonPayload:
|
||||
properties:
|
||||
_program:
|
||||
type: string
|
||||
description: 'Location of SAS program'
|
||||
example: /Public/somefolder/some.file
|
||||
type: object
|
||||
additionalProperties: false
|
||||
UserResponse:
|
||||
properties:
|
||||
id:
|
||||
@@ -402,7 +424,7 @@ paths:
|
||||
examples:
|
||||
'Example 1':
|
||||
value: {status: failure, message: 'Deployment failed!'}
|
||||
description: 'Creates/updates files within SASjs Drive using provided payload.'
|
||||
summary: 'Creates/updates files within SASjs Drive using provided payload.'
|
||||
tags:
|
||||
- Drive
|
||||
security:
|
||||
@@ -437,7 +459,7 @@ paths:
|
||||
examples:
|
||||
'Example 1':
|
||||
value: {status: failure, message: 'File request failed.'}
|
||||
description: 'Get file from SASjs Drive'
|
||||
summary: 'Get file from SASjs Drive'
|
||||
tags:
|
||||
- Drive
|
||||
security:
|
||||
@@ -450,6 +472,7 @@ paths:
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
example: /Public/somefolder/some.file
|
||||
patch:
|
||||
operationId: UpdateFile
|
||||
responses:
|
||||
@@ -471,7 +494,7 @@ paths:
|
||||
examples:
|
||||
'Example 1':
|
||||
value: {status: failure, message: 'File request failed.'}
|
||||
description: 'Modify a file in SASjs Drive'
|
||||
summary: 'Modify a file in SASjs Drive'
|
||||
tags:
|
||||
- Drive
|
||||
security:
|
||||
@@ -494,13 +517,68 @@ paths:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/GetFileTreeResponse'
|
||||
description: 'Fetch file tree within SASjs Drive.'
|
||||
summary: 'Fetch file tree within SASjs Drive.'
|
||||
tags:
|
||||
- Drive
|
||||
security:
|
||||
-
|
||||
bearerAuth: []
|
||||
parameters: []
|
||||
/SASjsApi/client/execute:
|
||||
get:
|
||||
operationId: ExecuteReturnRaw
|
||||
responses:
|
||||
'200':
|
||||
description: Ok
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: string
|
||||
description: "Trigger a SAS program using it's location in the _program parameter.\nEnable debugging using the _debug parameter.\nAdditional URL parameters are turned into SAS macro variables.\nAny files provided are placed into the session and\ncorresponding _WEBIN_XXX variables are created."
|
||||
summary: 'Execute Stored Program, return raw content'
|
||||
tags:
|
||||
- STP
|
||||
security:
|
||||
-
|
||||
bearerAuth: []
|
||||
parameters:
|
||||
-
|
||||
in: query
|
||||
name: _program
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
example: /Public/somefolder/some.file
|
||||
post:
|
||||
operationId: ExecuteReturnJson
|
||||
responses:
|
||||
'200':
|
||||
description: Ok
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ExecuteReturnJsonResponse'
|
||||
description: "Trigger a SAS program using it's location in the _program parameter.\nEnable debugging using the _debug parameter.\nAdditional URL parameters are turned into SAS macro variables.\nAny files provided are placed into the session and\ncorresponding _WEBIN_XXX variables are created."
|
||||
summary: 'Execute Stored Program, return JSON'
|
||||
tags:
|
||||
- STP
|
||||
security:
|
||||
-
|
||||
bearerAuth: []
|
||||
parameters:
|
||||
-
|
||||
in: query
|
||||
name: _program
|
||||
required: false
|
||||
schema:
|
||||
type: string
|
||||
example: /Public/somefolder/some.file
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ExecuteReturnJsonPayload'
|
||||
/SASjsApi/user:
|
||||
get:
|
||||
operationId: GetAllUsers
|
||||
@@ -516,7 +594,7 @@ paths:
|
||||
examples:
|
||||
'Example 1':
|
||||
value: [{id: 123, username: johnusername, displayName: John}, {id: 456, username: starkusername, displayName: Stark}]
|
||||
description: 'Get list of all users (username, displayname). All users can request this.'
|
||||
summary: 'Get list of all users (username, displayname). All users can request this.'
|
||||
tags:
|
||||
- User
|
||||
security:
|
||||
@@ -535,7 +613,7 @@ paths:
|
||||
examples:
|
||||
'Example 1':
|
||||
value: {id: 1234, displayName: 'John Snow', username: johnSnow01, isAdmin: false, isActive: true}
|
||||
description: 'Create user with the following attributes: UserId, UserName, Password, isAdmin, isActive. Admin only task.'
|
||||
summary: 'Create user with the following attributes: UserId, UserName, Password, isAdmin, isActive. Admin only task.'
|
||||
tags:
|
||||
- User
|
||||
security:
|
||||
@@ -558,7 +636,7 @@ paths:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/UserDetailsResponse'
|
||||
description: 'Get user properties - such as group memberships, userName, displayName.'
|
||||
summary: 'Get user properties - such as group memberships, userName, displayName.'
|
||||
tags:
|
||||
- User
|
||||
security:
|
||||
@@ -586,7 +664,7 @@ paths:
|
||||
examples:
|
||||
'Example 1':
|
||||
value: {id: 1234, displayName: 'John Snow', username: johnSnow01, isAdmin: false, isActive: true}
|
||||
description: 'Update user properties - such as displayName. Can be performed either by admins, or the user in question.'
|
||||
summary: 'Update user properties - such as displayName. Can be performed either by admins, or the user in question.'
|
||||
tags:
|
||||
- User
|
||||
security:
|
||||
@@ -613,7 +691,7 @@ paths:
|
||||
responses:
|
||||
'204':
|
||||
description: 'No content'
|
||||
description: 'Delete a user. Can be performed either by admins, or the user in question.'
|
||||
summary: 'Delete a user. Can be performed either by admins, or the user in question.'
|
||||
tags:
|
||||
- User
|
||||
security:
|
||||
@@ -653,7 +731,7 @@ paths:
|
||||
examples:
|
||||
'Example 1':
|
||||
value: [{groupId: 123, name: DCGroup, description: 'This group represents Data Controller Users'}]
|
||||
description: 'Get list of all groups (groupName and groupDescription). All users can request this.'
|
||||
summary: 'Get list of all groups (groupName and groupDescription). All users can request this.'
|
||||
tags:
|
||||
- Group
|
||||
security:
|
||||
@@ -672,7 +750,7 @@ paths:
|
||||
examples:
|
||||
'Example 1':
|
||||
value: {groupId: 123, name: DCGroup, description: 'This group represents Data Controller Users', isActive: true, users: []}
|
||||
description: 'Create a new group. Admin only.'
|
||||
summary: 'Create a new group. Admin only.'
|
||||
tags:
|
||||
- Group
|
||||
security:
|
||||
@@ -695,7 +773,7 @@ paths:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/GroupDetailsResponse'
|
||||
description: 'Get list of members of a group (userName). All users can request this.'
|
||||
summary: 'Get list of members of a group (userName). All users can request this.'
|
||||
tags:
|
||||
- Group
|
||||
security:
|
||||
@@ -716,7 +794,7 @@ paths:
|
||||
responses:
|
||||
'204':
|
||||
description: 'No content'
|
||||
description: 'Delete a group. Admin task only.'
|
||||
summary: 'Delete a group. Admin task only.'
|
||||
tags:
|
||||
- Group
|
||||
security:
|
||||
@@ -745,7 +823,7 @@ paths:
|
||||
examples:
|
||||
'Example 1':
|
||||
value: {groupId: 123, name: DCGroup, description: 'This group represents Data Controller Users', isActive: true, users: []}
|
||||
description: 'Add a user to a group. Admin task only.'
|
||||
summary: 'Add a user to a group. Admin task only.'
|
||||
tags:
|
||||
- Group
|
||||
security:
|
||||
@@ -782,7 +860,7 @@ paths:
|
||||
examples:
|
||||
'Example 1':
|
||||
value: {groupId: 123, name: DCGroup, description: 'This group represents Data Controller Users', isActive: true, users: []}
|
||||
description: 'Remove a user to a group. Admin task only.'
|
||||
summary: 'Remove a user to a group. Admin task only.'
|
||||
tags:
|
||||
- Group
|
||||
security:
|
||||
@@ -820,7 +898,7 @@ paths:
|
||||
examples:
|
||||
'Example 1':
|
||||
value: {clientId: someFormattedClientID1234, clientSecret: someRandomCryptoString}
|
||||
description: 'Create client with the following attributes: ClientId, ClientSecret. Admin only task.'
|
||||
summary: 'Create client with the following attributes: ClientId, ClientSecret. Admin only task.'
|
||||
tags:
|
||||
- Client
|
||||
security:
|
||||
@@ -846,7 +924,7 @@ paths:
|
||||
examples:
|
||||
'Example 1':
|
||||
value: {code: someRandomCryptoString}
|
||||
description: 'Accept a valid username/password, plus a CLIENT_ID, and return an AUTH_CODE'
|
||||
summary: 'Accept a valid username/password, plus a CLIENT_ID, and return an AUTH_CODE'
|
||||
tags:
|
||||
- Auth
|
||||
security: []
|
||||
@@ -870,7 +948,7 @@ paths:
|
||||
examples:
|
||||
'Example 1':
|
||||
value: {accessToken: someRandomCryptoString, refreshToken: someRandomCryptoString}
|
||||
description: 'Accepts client/auth code and returns access/refresh tokens'
|
||||
summary: 'Accepts client/auth code and returns access/refresh tokens'
|
||||
tags:
|
||||
- Auth
|
||||
security: []
|
||||
@@ -894,7 +972,7 @@ paths:
|
||||
examples:
|
||||
'Example 1':
|
||||
value: {accessToken: someRandomCryptoString, refreshToken: someRandomCryptoString}
|
||||
description: 'Returns new access/refresh tokens'
|
||||
summary: 'Returns new access/refresh tokens'
|
||||
tags:
|
||||
- Auth
|
||||
security:
|
||||
@@ -907,7 +985,7 @@ paths:
|
||||
responses:
|
||||
'204':
|
||||
description: 'No content'
|
||||
description: 'Logout terminate access/refresh tokens and returns nothing'
|
||||
summary: 'Logout terminate access/refresh tokens and returns nothing'
|
||||
tags:
|
||||
- Auth
|
||||
security:
|
||||
@@ -933,3 +1011,6 @@ tags:
|
||||
-
|
||||
name: Group
|
||||
description: 'Operations about group'
|
||||
-
|
||||
name: STP
|
||||
description: 'Operations about STP'
|
||||
|
||||
@@ -19,7 +19,7 @@ export default class AuthController {
|
||||
delete AuthController.authCodes[userId][clientId]
|
||||
|
||||
/**
|
||||
* Accept a valid username/password, plus a CLIENT_ID, and return an AUTH_CODE
|
||||
* @summary Accept a valid username/password, plus a CLIENT_ID, and return an AUTH_CODE
|
||||
*
|
||||
*/
|
||||
@Example<AuthorizeResponse>({
|
||||
@@ -33,7 +33,7 @@ export default class AuthController {
|
||||
}
|
||||
|
||||
/**
|
||||
* Accepts client/auth code and returns access/refresh tokens
|
||||
* @summary Accepts client/auth code and returns access/refresh tokens
|
||||
*
|
||||
*/
|
||||
@Example<TokenResponse>({
|
||||
@@ -46,7 +46,7 @@ export default class AuthController {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns new access/refresh tokens
|
||||
* @summary Returns new access/refresh tokens
|
||||
*
|
||||
*/
|
||||
@Example<TokenResponse>({
|
||||
@@ -62,7 +62,7 @@ export default class AuthController {
|
||||
}
|
||||
|
||||
/**
|
||||
* Logout terminate access/refresh tokens and returns nothing
|
||||
* @summary Logout terminate access/refresh tokens and returns nothing
|
||||
*
|
||||
*/
|
||||
@Security('bearerAuth')
|
||||
|
||||
@@ -7,7 +7,7 @@ import Client, { ClientPayload } from '../model/Client'
|
||||
@Tags('Client')
|
||||
export default class ClientController {
|
||||
/**
|
||||
* Create client with the following attributes: ClientId, ClientSecret. Admin only task.
|
||||
* @summary Create client with the following attributes: ClientId, ClientSecret. Admin only task.
|
||||
*
|
||||
*/
|
||||
@Example<ClientPayload>({
|
||||
|
||||
@@ -13,7 +13,7 @@ import {
|
||||
import { fileExists, readFile, createFile } from '@sasjs/utils'
|
||||
import { createFileTree, ExecutionController, getTreeExample } from '.'
|
||||
|
||||
import { FileTree, isFileQuery, isFileTree, TreeNode } from '../types'
|
||||
import { FileTree, isFileTree, TreeNode } from '../types'
|
||||
import path from 'path'
|
||||
import { getTmpFilesFolderPath } from '../utils'
|
||||
|
||||
@@ -77,7 +77,7 @@ const execDeployErrorResponse: DeployResponse = {
|
||||
@Tags('Drive')
|
||||
export class DriveController {
|
||||
/**
|
||||
* Creates/updates files within SASjs Drive using provided payload.
|
||||
* @summary Creates/updates files within SASjs Drive using provided payload.
|
||||
*
|
||||
*/
|
||||
@Example<DeployResponse>(successDeployResponse)
|
||||
@@ -89,8 +89,9 @@ export class DriveController {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get file from SASjs Drive
|
||||
*
|
||||
* @summary Get file from SASjs Drive
|
||||
* @query filePath Location of SAS program
|
||||
* @example filePath "/Public/somefolder/some.file"
|
||||
*/
|
||||
@Example<GetFileResponse>({
|
||||
status: 'success',
|
||||
@@ -106,7 +107,7 @@ export class DriveController {
|
||||
}
|
||||
|
||||
/**
|
||||
* Modify a file in SASjs Drive
|
||||
* @summary Modify a file in SASjs Drive
|
||||
*
|
||||
*/
|
||||
@Example<UpdateFileResponse>({
|
||||
@@ -124,7 +125,7 @@ export class DriveController {
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch file tree within SASjs Drive.
|
||||
* @summary Fetch file tree within SASjs Drive.
|
||||
*
|
||||
*/
|
||||
@Get('/filetree')
|
||||
|
||||
@@ -33,7 +33,7 @@ interface GroupDetailsResponse {
|
||||
@Tags('Group')
|
||||
export default class GroupController {
|
||||
/**
|
||||
* Get list of all groups (groupName and groupDescription). All users can request this.
|
||||
* @summary Get list of all groups (groupName and groupDescription). All users can request this.
|
||||
*
|
||||
*/
|
||||
@Example<GroupResponse[]>([
|
||||
@@ -49,7 +49,7 @@ export default class GroupController {
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new group. Admin only.
|
||||
* @summary Create a new group. Admin only.
|
||||
*
|
||||
*/
|
||||
@Example<GroupDetailsResponse>({
|
||||
@@ -67,7 +67,7 @@ export default class GroupController {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get list of members of a group (userName). All users can request this.
|
||||
* @summary Get list of members of a group (userName). All users can request this.
|
||||
* @param groupId The group's identifier
|
||||
* @example groupId 1234
|
||||
*/
|
||||
@@ -79,7 +79,7 @@ export default class GroupController {
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a user to a group. Admin task only.
|
||||
* @summary Add a user to a group. Admin task only.
|
||||
* @param groupId The group's identifier
|
||||
* @example groupId "1234"
|
||||
* @param userId The user's identifier
|
||||
@@ -101,7 +101,7 @@ export default class GroupController {
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a user to a group. Admin task only.
|
||||
* @summary Remove a user to a group. Admin task only.
|
||||
* @param groupId The group's identifier
|
||||
* @example groupId "1234"
|
||||
* @param userId The user's identifier
|
||||
@@ -123,7 +123,7 @@ export default class GroupController {
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a group. Admin task only.
|
||||
* @summary Delete a group. Admin task only.
|
||||
* @param groupId The group's identifier
|
||||
* @example groupId 1234
|
||||
*/
|
||||
|
||||
151
api/src/controllers/stp.ts
Normal file
151
api/src/controllers/stp.ts
Normal file
@@ -0,0 +1,151 @@
|
||||
import express from 'express'
|
||||
import path from 'path'
|
||||
import {
|
||||
Request,
|
||||
Security,
|
||||
Route,
|
||||
Tags,
|
||||
Example,
|
||||
Post,
|
||||
Body,
|
||||
Get,
|
||||
Query
|
||||
} from 'tsoa'
|
||||
import { ExecutionController } from '.'
|
||||
import { PreProgramVars } from '../types'
|
||||
import { getTmpFilesFolderPath, makeFilesNamesMap } from '../utils'
|
||||
|
||||
interface ExecuteReturnJsonPayload {
|
||||
/**
|
||||
* Location of SAS program
|
||||
* @example "/Public/somefolder/some.file"
|
||||
*/
|
||||
_program?: string
|
||||
}
|
||||
interface ExecuteReturnJsonResponse {
|
||||
status: string
|
||||
log?: string
|
||||
result?: string
|
||||
message?: string
|
||||
}
|
||||
|
||||
@Security('bearerAuth')
|
||||
@Route('SASjsApi/client')
|
||||
@Tags('STP')
|
||||
export default class STPController {
|
||||
/**
|
||||
* Trigger a SAS program using it's location in the _program parameter.
|
||||
* Enable debugging using the _debug parameter.
|
||||
* Additional URL parameters are turned into SAS macro variables.
|
||||
* Any files provided are placed into the session and
|
||||
* corresponding _WEBIN_XXX variables are created.
|
||||
* @summary Execute Stored Program, return raw content
|
||||
* @query _program Location of SAS program
|
||||
* @example _program "/Public/somefolder/some.file"
|
||||
*/
|
||||
@Get('/execute')
|
||||
public async executeReturnRaw(
|
||||
@Request() request: express.Request,
|
||||
@Query() _program: string
|
||||
): Promise<string> {
|
||||
return executeReturnRaw(request, _program)
|
||||
}
|
||||
/**
|
||||
* Trigger a SAS program using it's location in the _program parameter.
|
||||
* Enable debugging using the _debug parameter.
|
||||
* Additional URL parameters are turned into SAS macro variables.
|
||||
* Any files provided are placed into the session and
|
||||
* corresponding _WEBIN_XXX variables are created.
|
||||
* @summary Execute Stored Program, return JSON
|
||||
* @query _program Location of SAS program
|
||||
* @example _program "/Public/somefolder/some.file"
|
||||
*/
|
||||
@Post('/execute')
|
||||
public async executeReturnJson(
|
||||
@Request() request: express.Request,
|
||||
@Body() body: ExecuteReturnJsonPayload,
|
||||
@Query() _program?: string
|
||||
): Promise<ExecuteReturnJsonResponse> {
|
||||
const program = _program ?? body._program
|
||||
return executeReturnJson(request, program!)
|
||||
}
|
||||
}
|
||||
|
||||
const executeReturnRaw = async (
|
||||
req: express.Request,
|
||||
_program: string
|
||||
): Promise<string> => {
|
||||
const sasCodePath =
|
||||
path
|
||||
.join(getTmpFilesFolderPath(), _program)
|
||||
.replace(new RegExp('/', 'g'), path.sep) + '.sas'
|
||||
|
||||
try {
|
||||
const result = await new ExecutionController().execute(
|
||||
sasCodePath,
|
||||
getPreProgramVariables(req),
|
||||
undefined,
|
||||
undefined,
|
||||
{
|
||||
...req.query
|
||||
}
|
||||
)
|
||||
|
||||
return result as string
|
||||
} catch (err) {
|
||||
throw {
|
||||
code: 400,
|
||||
status: 'failure',
|
||||
message: 'Job execution failed.',
|
||||
...(typeof err === 'object' ? err : { details: err })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const executeReturnJson = async (
|
||||
req: any,
|
||||
_program: string
|
||||
): Promise<ExecuteReturnJsonResponse> => {
|
||||
const sasCodePath =
|
||||
path
|
||||
.join(getTmpFilesFolderPath(), _program)
|
||||
.replace(new RegExp('/', 'g'), path.sep) + '.sas'
|
||||
|
||||
const filesNamesMap = req.files?.length ? makeFilesNamesMap(req.files) : null
|
||||
|
||||
try {
|
||||
const jsonResult: any = await new ExecutionController().execute(
|
||||
sasCodePath,
|
||||
getPreProgramVariables(req),
|
||||
undefined,
|
||||
req.sasSession,
|
||||
{ ...req.query, ...req.body },
|
||||
{ filesNamesMap: filesNamesMap },
|
||||
true
|
||||
)
|
||||
return {
|
||||
status: 'success',
|
||||
result: jsonResult.result,
|
||||
log: jsonResult.log
|
||||
}
|
||||
} catch (err) {
|
||||
throw {
|
||||
status: 'failure',
|
||||
message: 'Job execution failed.',
|
||||
...(typeof err === 'object' ? err : { details: err })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const getPreProgramVariables = (req: any): PreProgramVars => {
|
||||
const host = req.get('host')
|
||||
const protocol = req.protocol + '://'
|
||||
const { user, accessToken } = req
|
||||
return {
|
||||
username: user.username,
|
||||
userId: user.userId,
|
||||
displayName: user.displayName,
|
||||
serverUrl: protocol + host,
|
||||
accessToken
|
||||
}
|
||||
}
|
||||
@@ -34,7 +34,7 @@ interface UserDetailsResponse {
|
||||
@Tags('User')
|
||||
export default class UserController {
|
||||
/**
|
||||
* Get list of all users (username, displayname). All users can request this.
|
||||
* @summary Get list of all users (username, displayname). All users can request this.
|
||||
*
|
||||
*/
|
||||
@Example<UserResponse[]>([
|
||||
@@ -55,7 +55,7 @@ export default class UserController {
|
||||
}
|
||||
|
||||
/**
|
||||
* Create user with the following attributes: UserId, UserName, Password, isAdmin, isActive. Admin only task.
|
||||
* @summary Create user with the following attributes: UserId, UserName, Password, isAdmin, isActive. Admin only task.
|
||||
*
|
||||
*/
|
||||
@Example<UserDetailsResponse>({
|
||||
@@ -73,7 +73,7 @@ export default class UserController {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get user properties - such as group memberships, userName, displayName.
|
||||
* @summary Get user properties - such as group memberships, userName, displayName.
|
||||
* @param userId The user's identifier
|
||||
* @example userId 1234
|
||||
*/
|
||||
@@ -83,7 +83,7 @@ export default class UserController {
|
||||
}
|
||||
|
||||
/**
|
||||
* Update user properties - such as displayName. Can be performed either by admins, or the user in question.
|
||||
* @summary Update user properties - such as displayName. Can be performed either by admins, or the user in question.
|
||||
* @param userId The user's identifier
|
||||
* @example userId "1234"
|
||||
*/
|
||||
@@ -103,7 +103,7 @@ export default class UserController {
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a user. Can be performed either by admins, or the user in question.
|
||||
* @summary Delete a user. Can be performed either by admins, or the user in question.
|
||||
* @param userId The user's identifier
|
||||
* @example userId 1234
|
||||
*/
|
||||
|
||||
@@ -1,13 +1,6 @@
|
||||
import express from 'express'
|
||||
import path from 'path'
|
||||
import { ExecutionController } from '../../controllers'
|
||||
import { DriveController } from '../../controllers/drive'
|
||||
import { isFileQuery } from '../../types'
|
||||
import {
|
||||
getFileDriveValidation,
|
||||
getTmpFilesFolderPath,
|
||||
updateFileDriveValidation
|
||||
} from '../../utils'
|
||||
import { getFileDriveValidation, updateFileDriveValidation } from '../../utils'
|
||||
|
||||
const driveRouter = express.Router()
|
||||
|
||||
|
||||
@@ -1,39 +1,26 @@
|
||||
import express from 'express'
|
||||
import { isExecutionQuery, PreProgramVars } from '../../types'
|
||||
import path from 'path'
|
||||
import { getTmpFilesFolderPath, makeFilesNamesMap } from '../../utils'
|
||||
import { ExecutionController, FileUploadController } from '../../controllers'
|
||||
import { executeProgramRawValidation } from '../../utils'
|
||||
import STPController from '../../controllers/stp'
|
||||
import { FileUploadController } from '../../controllers'
|
||||
|
||||
const stpRouter = express.Router()
|
||||
|
||||
const fileUploadController = new FileUploadController()
|
||||
const controller = new STPController()
|
||||
|
||||
stpRouter.get('/execute', async (req, res) => {
|
||||
if (isExecutionQuery(req.query)) {
|
||||
let sasCodePath =
|
||||
path
|
||||
.join(getTmpFilesFolderPath(), req.query._program)
|
||||
.replace(new RegExp('/', 'g'), path.sep) + '.sas'
|
||||
const { error, value: query } = executeProgramRawValidation(req.query)
|
||||
if (error) return res.status(400).send(error.details[0].message)
|
||||
|
||||
await new ExecutionController()
|
||||
.execute(sasCodePath, getPreProgramVariables(req), undefined, undefined, {
|
||||
...req.query
|
||||
})
|
||||
.then((result: {}) => {
|
||||
res.status(200).send(result)
|
||||
})
|
||||
.catch((err: {} | string) => {
|
||||
res.status(400).send({
|
||||
status: 'failure',
|
||||
message: 'Job execution failed.',
|
||||
...(typeof err === 'object' ? err : { details: err })
|
||||
})
|
||||
})
|
||||
} else {
|
||||
res.status(400).send({
|
||||
status: 'failure',
|
||||
message: `Please provide the location of SAS code`
|
||||
})
|
||||
try {
|
||||
const response = await controller.executeReturnRaw(req, query._program)
|
||||
res.send(response)
|
||||
} catch (err: any) {
|
||||
const statusCode = err.code
|
||||
|
||||
delete err.code
|
||||
|
||||
res.status(statusCode).send(err)
|
||||
}
|
||||
})
|
||||
|
||||
@@ -42,68 +29,27 @@ stpRouter.post(
|
||||
fileUploadController.preuploadMiddleware,
|
||||
fileUploadController.getMulterUploadObject().any(),
|
||||
async (req: any, res: any) => {
|
||||
let _program
|
||||
if (isExecutionQuery(req.query)) {
|
||||
_program = req.query._program
|
||||
} else if (isExecutionQuery(req.body)) {
|
||||
_program = req.body._program
|
||||
}
|
||||
const { error: errQ, value: query } = executeProgramRawValidation(req.query)
|
||||
if (errQ) return res.status(400).send(errQ.details[0].message)
|
||||
|
||||
if (_program) {
|
||||
let sasCodePath =
|
||||
path
|
||||
.join(getTmpFilesFolderPath(), _program)
|
||||
.replace(new RegExp('/', 'g'), path.sep) + '.sas'
|
||||
const { error: errB, value: body } = executeProgramRawValidation(req.body)
|
||||
if (errB) return res.status(400).send(errB.details[0].message)
|
||||
|
||||
let filesNamesMap = null
|
||||
try {
|
||||
const response = await controller.executeReturnJson(
|
||||
req,
|
||||
query,
|
||||
body?._program
|
||||
)
|
||||
res.send(response)
|
||||
} catch (err: any) {
|
||||
const statusCode = err.code
|
||||
|
||||
if (req.files && req.files.length > 0) {
|
||||
filesNamesMap = makeFilesNamesMap(req.files)
|
||||
}
|
||||
delete err.code
|
||||
|
||||
await new ExecutionController()
|
||||
.execute(
|
||||
sasCodePath,
|
||||
getPreProgramVariables(req),
|
||||
undefined,
|
||||
req.sasSession,
|
||||
{ ...req.query, ...req.body },
|
||||
{ filesNamesMap: filesNamesMap },
|
||||
true
|
||||
)
|
||||
.then((result: {}) => {
|
||||
res.status(200).send({
|
||||
status: 'success',
|
||||
...result
|
||||
})
|
||||
})
|
||||
.catch((err: {} | string) => {
|
||||
res.status(400).send({
|
||||
status: 'failure',
|
||||
message: 'Job execution failed.',
|
||||
...(typeof err === 'object' ? err : { details: err })
|
||||
})
|
||||
})
|
||||
} else {
|
||||
res.status(400).send({
|
||||
status: 'failure',
|
||||
message: `Please provide the location of SAS code`
|
||||
})
|
||||
res.status(statusCode).send(err)
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
const getPreProgramVariables = (req: any): PreProgramVars => {
|
||||
const host = req.get('host')
|
||||
const protocol = req.protocol + '://'
|
||||
const { user, accessToken } = req
|
||||
return {
|
||||
username: user.username,
|
||||
userId: user.userId,
|
||||
displayName: user.displayName,
|
||||
serverUrl: protocol + host,
|
||||
accessToken
|
||||
}
|
||||
}
|
||||
|
||||
export default stpRouter
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
import express from 'express'
|
||||
import { isExecutionQuery } from '../../types'
|
||||
import path from 'path'
|
||||
import { getTmpFilesFolderPath, getWebBuildFolderPath } from '../../utils'
|
||||
import { ExecutionController } from '../../controllers'
|
||||
import { getWebBuildFolderPath } from '../../utils'
|
||||
|
||||
const webRouter = express.Router()
|
||||
|
||||
|
||||
@@ -76,3 +76,10 @@ export const updateFileDriveValidation = (data: any): Joi.ValidationResult =>
|
||||
filePath: Joi.string().required(),
|
||||
fileContent: Joi.string().required()
|
||||
}).validate(data)
|
||||
|
||||
export const executeProgramRawValidation = (data: any): Joi.ValidationResult =>
|
||||
Joi.object({
|
||||
_program: Joi.string().required
|
||||
})
|
||||
.pattern(/\w\d/, Joi.string())
|
||||
.validate(data)
|
||||
|
||||
@@ -30,6 +30,10 @@
|
||||
{
|
||||
"name": "Group",
|
||||
"description": "Operations about group"
|
||||
},
|
||||
{
|
||||
"name": "STP",
|
||||
"description": "Operations about STP"
|
||||
}
|
||||
],
|
||||
"yaml": true,
|
||||
|
||||
@@ -1,782 +0,0 @@
|
||||
components:
|
||||
examples: {}
|
||||
headers: {}
|
||||
parameters: {}
|
||||
requestBodies: {}
|
||||
responses: {}
|
||||
schemas:
|
||||
MemberType.folder:
|
||||
enum:
|
||||
- folder
|
||||
type: string
|
||||
FolderMember:
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
type:
|
||||
$ref: '#/components/schemas/MemberType.folder'
|
||||
members:
|
||||
items:
|
||||
anyOf:
|
||||
-
|
||||
$ref: '#/components/schemas/FolderMember'
|
||||
-
|
||||
$ref: '#/components/schemas/ServiceMember'
|
||||
type: array
|
||||
required:
|
||||
- name
|
||||
- type
|
||||
- members
|
||||
type: object
|
||||
additionalProperties: false
|
||||
MemberType.service:
|
||||
enum:
|
||||
- service
|
||||
type: string
|
||||
ServiceMember:
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
type:
|
||||
$ref: '#/components/schemas/MemberType.service'
|
||||
code:
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
- type
|
||||
- code
|
||||
type: object
|
||||
additionalProperties: false
|
||||
FileTree:
|
||||
properties:
|
||||
members:
|
||||
items:
|
||||
anyOf:
|
||||
-
|
||||
$ref: '#/components/schemas/FolderMember'
|
||||
-
|
||||
$ref: '#/components/schemas/ServiceMember'
|
||||
type: array
|
||||
required:
|
||||
- members
|
||||
type: object
|
||||
additionalProperties: false
|
||||
DeployResponse:
|
||||
properties:
|
||||
status:
|
||||
type: string
|
||||
message:
|
||||
type: string
|
||||
example:
|
||||
$ref: '#/components/schemas/FileTree'
|
||||
required:
|
||||
- status
|
||||
- message
|
||||
type: object
|
||||
additionalProperties: false
|
||||
DeployPayload:
|
||||
properties:
|
||||
appLoc:
|
||||
type: string
|
||||
fileTree:
|
||||
$ref: '#/components/schemas/FileTree'
|
||||
required:
|
||||
- fileTree
|
||||
type: object
|
||||
additionalProperties: false
|
||||
UserResponse:
|
||||
properties:
|
||||
id:
|
||||
type: number
|
||||
format: double
|
||||
username:
|
||||
type: string
|
||||
displayName:
|
||||
type: string
|
||||
required:
|
||||
- id
|
||||
- username
|
||||
- displayName
|
||||
type: object
|
||||
additionalProperties: false
|
||||
UserDetailsResponse:
|
||||
properties:
|
||||
id:
|
||||
type: number
|
||||
format: double
|
||||
displayName:
|
||||
type: string
|
||||
username:
|
||||
type: string
|
||||
isActive:
|
||||
type: boolean
|
||||
isAdmin:
|
||||
type: boolean
|
||||
required:
|
||||
- id
|
||||
- displayName
|
||||
- username
|
||||
- isActive
|
||||
- isAdmin
|
||||
type: object
|
||||
additionalProperties: false
|
||||
UserPayload:
|
||||
properties:
|
||||
displayName:
|
||||
type: string
|
||||
description: 'Display name for user'
|
||||
example: 'John Snow'
|
||||
username:
|
||||
type: string
|
||||
description: 'Username for user'
|
||||
example: johnSnow01
|
||||
password:
|
||||
type: string
|
||||
description: 'Password for user'
|
||||
isAdmin:
|
||||
type: boolean
|
||||
description: 'Account should be admin or not, defaults to false'
|
||||
example: 'false'
|
||||
isActive:
|
||||
type: boolean
|
||||
description: 'Account should be active or not, defaults to true'
|
||||
example: 'true'
|
||||
required:
|
||||
- displayName
|
||||
- username
|
||||
- password
|
||||
type: object
|
||||
additionalProperties: false
|
||||
GroupResponse:
|
||||
properties:
|
||||
groupId:
|
||||
type: number
|
||||
format: double
|
||||
name:
|
||||
type: string
|
||||
description:
|
||||
type: string
|
||||
required:
|
||||
- groupId
|
||||
- name
|
||||
- description
|
||||
type: object
|
||||
additionalProperties: false
|
||||
GroupDetailsResponse:
|
||||
properties:
|
||||
groupId:
|
||||
type: number
|
||||
format: double
|
||||
name:
|
||||
type: string
|
||||
description:
|
||||
type: string
|
||||
isActive:
|
||||
type: boolean
|
||||
users:
|
||||
items:
|
||||
$ref: '#/components/schemas/UserResponse'
|
||||
type: array
|
||||
required:
|
||||
- groupId
|
||||
- name
|
||||
- description
|
||||
- isActive
|
||||
- users
|
||||
type: object
|
||||
additionalProperties: false
|
||||
GroupPayload:
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
description: 'Name of the group'
|
||||
example: DCGroup
|
||||
description:
|
||||
type: string
|
||||
description: 'Description of the group'
|
||||
example: 'This group represents Data Controller Users'
|
||||
isActive:
|
||||
type: boolean
|
||||
description: 'Group should be active or not, defaults to true'
|
||||
example: 'true'
|
||||
required:
|
||||
- name
|
||||
- description
|
||||
type: object
|
||||
additionalProperties: false
|
||||
ClientPayload:
|
||||
properties:
|
||||
clientId:
|
||||
type: string
|
||||
description: 'Client ID'
|
||||
example: someFormattedClientID1234
|
||||
clientSecret:
|
||||
type: string
|
||||
description: 'Client Secret'
|
||||
example: someRandomCryptoString
|
||||
required:
|
||||
- clientId
|
||||
- clientSecret
|
||||
type: object
|
||||
additionalProperties: false
|
||||
AuthorizeResponse:
|
||||
properties:
|
||||
code:
|
||||
type: string
|
||||
description: 'Authorization code'
|
||||
example: someRandomCryptoString
|
||||
required:
|
||||
- code
|
||||
type: object
|
||||
additionalProperties: false
|
||||
AuthorizePayload:
|
||||
properties:
|
||||
username:
|
||||
type: string
|
||||
description: 'Username for user'
|
||||
example: secretuser
|
||||
password:
|
||||
type: string
|
||||
description: 'Password for user'
|
||||
example: secretpassword
|
||||
clientId:
|
||||
type: string
|
||||
description: 'Client ID'
|
||||
example: clientID1
|
||||
required:
|
||||
- username
|
||||
- password
|
||||
- clientId
|
||||
type: object
|
||||
additionalProperties: false
|
||||
TokenResponse:
|
||||
properties:
|
||||
accessToken:
|
||||
type: string
|
||||
description: 'Access Token'
|
||||
example: someRandomCryptoString
|
||||
refreshToken:
|
||||
type: string
|
||||
description: 'Refresh Token'
|
||||
example: someRandomCryptoString
|
||||
required:
|
||||
- accessToken
|
||||
- refreshToken
|
||||
type: object
|
||||
additionalProperties: false
|
||||
TokenPayload:
|
||||
properties:
|
||||
clientId:
|
||||
type: string
|
||||
description: 'Client ID'
|
||||
example: clientID1
|
||||
code:
|
||||
type: string
|
||||
description: 'Authorization code'
|
||||
example: someRandomCryptoString
|
||||
required:
|
||||
- clientId
|
||||
- code
|
||||
type: object
|
||||
additionalProperties: false
|
||||
InfoJWT:
|
||||
properties:
|
||||
clientId:
|
||||
type: string
|
||||
userId:
|
||||
type: number
|
||||
format: double
|
||||
required:
|
||||
- clientId
|
||||
- userId
|
||||
type: object
|
||||
additionalProperties: false
|
||||
securitySchemes:
|
||||
bearerAuth:
|
||||
type: http
|
||||
scheme: bearer
|
||||
bearerFormat: JWT
|
||||
info:
|
||||
title: server
|
||||
version: 0.0.1
|
||||
description: 'SASjs server'
|
||||
contact:
|
||||
name: 'Analytium Ltd'
|
||||
openapi: 3.0.0
|
||||
paths:
|
||||
/SASjsApi/drive/deploy:
|
||||
post:
|
||||
operationId: Deploy
|
||||
responses:
|
||||
'200':
|
||||
description: Ok
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/DeployResponse'
|
||||
examples:
|
||||
'Example 1':
|
||||
value: {status: success, message: 'Files deployed successfully to @sasjs/server.'}
|
||||
'400':
|
||||
description: 'Invalid Format'
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/DeployResponse'
|
||||
examples:
|
||||
'Example 1':
|
||||
value: {status: failure, message: 'Provided not supported data format.'}
|
||||
'500':
|
||||
description: 'Execution Error'
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/DeployResponse'
|
||||
examples:
|
||||
'Example 1':
|
||||
value: {status: failure, message: 'Deployment failed!'}
|
||||
description: 'Creates/updates files within SASjs Drive using provided payload.'
|
||||
tags:
|
||||
- Drive
|
||||
security:
|
||||
-
|
||||
bearerAuth: []
|
||||
parameters: []
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/DeployPayload'
|
||||
/SASjsApi/user:
|
||||
get:
|
||||
operationId: GetAllUsers
|
||||
responses:
|
||||
'200':
|
||||
description: Ok
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
items:
|
||||
$ref: '#/components/schemas/UserResponse'
|
||||
type: array
|
||||
examples:
|
||||
'Example 1':
|
||||
value: [{id: 123, username: johnusername, displayName: John}, {id: 456, username: starkusername, displayName: Stark}]
|
||||
description: 'Get list of all users (username, displayname). All users can request this.'
|
||||
tags:
|
||||
- User
|
||||
security:
|
||||
-
|
||||
bearerAuth: []
|
||||
parameters: []
|
||||
post:
|
||||
operationId: CreateUser
|
||||
responses:
|
||||
'200':
|
||||
description: Ok
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/UserDetailsResponse'
|
||||
examples:
|
||||
'Example 1':
|
||||
value: {id: 1234, displayName: 'John Snow', username: johnSnow01, isAdmin: false, isActive: true}
|
||||
description: 'Create user with the following attributes: UserId, UserName, Password, isAdmin, isActive. Admin only task.'
|
||||
tags:
|
||||
- User
|
||||
security:
|
||||
-
|
||||
bearerAuth: []
|
||||
parameters: []
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/UserPayload'
|
||||
'/SASjsApi/user/{userId}':
|
||||
get:
|
||||
operationId: GetUser
|
||||
responses:
|
||||
'200':
|
||||
description: Ok
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/UserDetailsResponse'
|
||||
description: 'Get user properties - such as group memberships, userName, displayName.'
|
||||
tags:
|
||||
- User
|
||||
security:
|
||||
-
|
||||
bearerAuth: []
|
||||
parameters:
|
||||
-
|
||||
description: 'The user''s identifier'
|
||||
in: path
|
||||
name: userId
|
||||
required: true
|
||||
schema:
|
||||
format: double
|
||||
type: number
|
||||
example: 1234
|
||||
patch:
|
||||
operationId: UpdateUser
|
||||
responses:
|
||||
'200':
|
||||
description: Ok
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/UserDetailsResponse'
|
||||
examples:
|
||||
'Example 1':
|
||||
value: {id: 1234, displayName: 'John Snow', username: johnSnow01, isAdmin: false, isActive: true}
|
||||
description: 'Update user properties - such as displayName. Can be performed either by admins, or the user in question.'
|
||||
tags:
|
||||
- User
|
||||
security:
|
||||
-
|
||||
bearerAuth: []
|
||||
parameters:
|
||||
-
|
||||
description: 'The user''s identifier'
|
||||
in: path
|
||||
name: userId
|
||||
required: true
|
||||
schema:
|
||||
format: double
|
||||
type: number
|
||||
example: '1234'
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/UserPayload'
|
||||
delete:
|
||||
operationId: DeleteUser
|
||||
responses:
|
||||
'204':
|
||||
description: 'No content'
|
||||
description: 'Delete a user. Can be performed either by admins, or the user in question.'
|
||||
tags:
|
||||
- User
|
||||
security:
|
||||
-
|
||||
bearerAuth: []
|
||||
parameters:
|
||||
-
|
||||
description: 'The user''s identifier'
|
||||
in: path
|
||||
name: userId
|
||||
required: true
|
||||
schema:
|
||||
format: double
|
||||
type: number
|
||||
example: 1234
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
properties:
|
||||
password:
|
||||
type: string
|
||||
type: object
|
||||
/SASjsApi/group:
|
||||
get:
|
||||
operationId: GetAllGroups
|
||||
responses:
|
||||
'200':
|
||||
description: Ok
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
items:
|
||||
$ref: '#/components/schemas/GroupResponse'
|
||||
type: array
|
||||
examples:
|
||||
'Example 1':
|
||||
value: [{groupId: 123, name: DCGroup, description: 'This group represents Data Controller Users'}]
|
||||
description: 'Get list of all groups (groupName and groupDescription). All users can request this.'
|
||||
tags:
|
||||
- Group
|
||||
security:
|
||||
-
|
||||
bearerAuth: []
|
||||
parameters: []
|
||||
post:
|
||||
operationId: CreateGroup
|
||||
responses:
|
||||
'200':
|
||||
description: Ok
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/GroupDetailsResponse'
|
||||
examples:
|
||||
'Example 1':
|
||||
value: {groupId: 123, name: DCGroup, description: 'This group represents Data Controller Users', isActive: true, users: []}
|
||||
description: 'Create a new group. Admin only.'
|
||||
tags:
|
||||
- Group
|
||||
security:
|
||||
-
|
||||
bearerAuth: []
|
||||
parameters: []
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/GroupPayload'
|
||||
'/SASjsApi/group/{groupId}':
|
||||
get:
|
||||
operationId: GetGroup
|
||||
responses:
|
||||
'200':
|
||||
description: Ok
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/GroupDetailsResponse'
|
||||
description: 'Get list of members of a group (userName). All users can request this.'
|
||||
tags:
|
||||
- Group
|
||||
security:
|
||||
-
|
||||
bearerAuth: []
|
||||
parameters:
|
||||
-
|
||||
description: 'The group''s identifier'
|
||||
in: path
|
||||
name: groupId
|
||||
required: true
|
||||
schema:
|
||||
format: double
|
||||
type: number
|
||||
example: 1234
|
||||
delete:
|
||||
operationId: DeleteGroup
|
||||
responses:
|
||||
'204':
|
||||
description: 'No content'
|
||||
description: 'Delete a group. Admin task only.'
|
||||
tags:
|
||||
- Group
|
||||
security:
|
||||
-
|
||||
bearerAuth: []
|
||||
parameters:
|
||||
-
|
||||
description: 'The group''s identifier'
|
||||
in: path
|
||||
name: groupId
|
||||
required: true
|
||||
schema:
|
||||
format: double
|
||||
type: number
|
||||
example: 1234
|
||||
'/SASjsApi/group/{groupId}/{userId}':
|
||||
post:
|
||||
operationId: AddUserToGroup
|
||||
responses:
|
||||
'200':
|
||||
description: Ok
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/GroupDetailsResponse'
|
||||
examples:
|
||||
'Example 1':
|
||||
value: {groupId: 123, name: DCGroup, description: 'This group represents Data Controller Users', isActive: true, users: []}
|
||||
description: 'Add a user to a group. Admin task only.'
|
||||
tags:
|
||||
- Group
|
||||
security:
|
||||
-
|
||||
bearerAuth: []
|
||||
parameters:
|
||||
-
|
||||
description: 'The group''s identifier'
|
||||
in: path
|
||||
name: groupId
|
||||
required: true
|
||||
schema:
|
||||
format: double
|
||||
type: number
|
||||
example: '1234'
|
||||
-
|
||||
description: 'The user''s identifier'
|
||||
in: path
|
||||
name: userId
|
||||
required: true
|
||||
schema:
|
||||
format: double
|
||||
type: number
|
||||
example: '6789'
|
||||
delete:
|
||||
operationId: RemoveUserFromGroup
|
||||
responses:
|
||||
'200':
|
||||
description: Ok
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/GroupDetailsResponse'
|
||||
examples:
|
||||
'Example 1':
|
||||
value: {groupId: 123, name: DCGroup, description: 'This group represents Data Controller Users', isActive: true, users: []}
|
||||
description: 'Remove a user to a group. Admin task only.'
|
||||
tags:
|
||||
- Group
|
||||
security:
|
||||
-
|
||||
bearerAuth: []
|
||||
parameters:
|
||||
-
|
||||
description: 'The group''s identifier'
|
||||
in: path
|
||||
name: groupId
|
||||
required: true
|
||||
schema:
|
||||
format: double
|
||||
type: number
|
||||
example: '1234'
|
||||
-
|
||||
description: 'The user''s identifier'
|
||||
in: path
|
||||
name: userId
|
||||
required: true
|
||||
schema:
|
||||
format: double
|
||||
type: number
|
||||
example: '6789'
|
||||
/SASjsApi/client:
|
||||
post:
|
||||
operationId: CreateClient
|
||||
responses:
|
||||
'200':
|
||||
description: Ok
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ClientPayload'
|
||||
examples:
|
||||
'Example 1':
|
||||
value: {clientId: someFormattedClientID1234, clientSecret: someRandomCryptoString}
|
||||
description: 'Create client with the following attributes: ClientId, ClientSecret. Admin only task.'
|
||||
tags:
|
||||
- Client
|
||||
security:
|
||||
-
|
||||
bearerAuth: []
|
||||
parameters: []
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ClientPayload'
|
||||
/SASjsApi/auth/authorize:
|
||||
post:
|
||||
operationId: Authorize
|
||||
responses:
|
||||
'200':
|
||||
description: Ok
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/AuthorizeResponse'
|
||||
examples:
|
||||
'Example 1':
|
||||
value: {code: someRandomCryptoString}
|
||||
description: 'Accept a valid username/password, plus a CLIENT_ID, and return an AUTH_CODE'
|
||||
tags:
|
||||
- Auth
|
||||
security: []
|
||||
parameters: []
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/AuthorizePayload'
|
||||
/SASjsApi/auth/token:
|
||||
post:
|
||||
operationId: Token
|
||||
responses:
|
||||
'200':
|
||||
description: Ok
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/TokenResponse'
|
||||
examples:
|
||||
'Example 1':
|
||||
value: {accessToken: someRandomCryptoString, refreshToken: someRandomCryptoString}
|
||||
description: 'Accepts client/auth code and returns access/refresh tokens'
|
||||
tags:
|
||||
- Auth
|
||||
security: []
|
||||
parameters: []
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/TokenPayload'
|
||||
/SASjsApi/auth/refresh:
|
||||
post:
|
||||
operationId: Refresh
|
||||
responses:
|
||||
'200':
|
||||
description: Ok
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/TokenResponse'
|
||||
examples:
|
||||
'Example 1':
|
||||
value: {accessToken: someRandomCryptoString, refreshToken: someRandomCryptoString}
|
||||
description: 'Returns new access/refresh tokens'
|
||||
tags:
|
||||
- Auth
|
||||
security:
|
||||
-
|
||||
bearerAuth: []
|
||||
parameters: []
|
||||
/SASjsApi/auth/logout:
|
||||
post:
|
||||
operationId: Logout
|
||||
responses:
|
||||
'204':
|
||||
description: 'No content'
|
||||
description: 'Logout terminate access/refresh tokens and returns nothing'
|
||||
tags:
|
||||
- Auth
|
||||
security:
|
||||
-
|
||||
bearerAuth: []
|
||||
parameters: []
|
||||
servers:
|
||||
-
|
||||
url: /
|
||||
tags:
|
||||
-
|
||||
name: User
|
||||
description: 'Operations about users'
|
||||
-
|
||||
name: Client
|
||||
description: 'Operations about clients'
|
||||
-
|
||||
name: Auth
|
||||
description: 'Operations about auth'
|
||||
-
|
||||
name: Drive
|
||||
description: 'Operations about drive'
|
||||
-
|
||||
name: Group
|
||||
description: 'Operations about group'
|
||||
@@ -1 +1 @@
|
||||
CLIENT_ID=<place clientId here>
|
||||
REACT_APP_CLIENT_ID=<place clientId here>
|
||||
Reference in New Issue
Block a user