#26: Added initial version of app authentication
This commit is contained in:
@@ -475,6 +475,7 @@ func generateYaml(swagger *openapi3.Swagger, newmd5 string) (*openapi3.Swagger,
|
||||
api.Authentication.Parameters[0].Description = securitySchemes["BearerAuth"].Value.Description
|
||||
api.Authentication.Parameters[0].Name = securitySchemes["BearerAuth"].Value.Name
|
||||
api.Authentication.Parameters[0].In = securitySchemes["BearerAuth"].Value.In
|
||||
api.Authentication.Parameters[0].Schema.Type = securitySchemes["BearerAuth"].Value.Scheme
|
||||
api.Authentication.Parameters[0].Scheme = securitySchemes["BearerAuth"].Value.Scheme
|
||||
//log.Printf("HANDLE BEARER AUTH")
|
||||
extraParameters = append(extraParameters, WorkflowAppActionParameter{
|
||||
@@ -492,6 +493,7 @@ func generateYaml(swagger *openapi3.Swagger, newmd5 string) (*openapi3.Swagger,
|
||||
api.Authentication.Parameters[0].Description = securitySchemes["ApiKeyAuth"].Value.Description
|
||||
api.Authentication.Parameters[0].Name = securitySchemes["ApiKeyAuth"].Value.Name
|
||||
api.Authentication.Parameters[0].In = securitySchemes["ApiKeyAuth"].Value.In
|
||||
api.Authentication.Parameters[0].Schema.Type = securitySchemes["ApiKeyAuth"].Value.Scheme
|
||||
api.Authentication.Parameters[0].Scheme = securitySchemes["ApiKeyAuth"].Value.Scheme
|
||||
//log.Printf("HANDLE APIKEY AUTH")
|
||||
extraParameters = append(extraParameters, WorkflowAppActionParameter{
|
||||
@@ -509,6 +511,7 @@ func generateYaml(swagger *openapi3.Swagger, newmd5 string) (*openapi3.Swagger,
|
||||
api.Authentication.Parameters[0].Description = securitySchemes["BasicAuth"].Value.Description
|
||||
api.Authentication.Parameters[0].Name = securitySchemes["BasicAuth"].Value.Name
|
||||
api.Authentication.Parameters[0].In = securitySchemes["BasicAuth"].Value.In
|
||||
api.Authentication.Parameters[0].Schema.Type = securitySchemes["BasicAuth"].Value.Scheme
|
||||
api.Authentication.Parameters[0].Scheme = securitySchemes["BasicAuth"].Value.Scheme
|
||||
extraParameters = append(extraParameters, WorkflowAppActionParameter{
|
||||
Name: "username",
|
||||
|
||||
@@ -6452,6 +6452,10 @@ func init() {
|
||||
r.HandleFunc("/api/v1/apps", setNewWorkflowApp).Methods("PUT", "OPTIONS")
|
||||
r.HandleFunc("/api/v1/apps/search", getSpecificApps).Methods("POST", "OPTIONS")
|
||||
|
||||
r.HandleFunc("/api/v1/apps/authentication", getAppAuthentication).Methods("GET", "OPTIONS")
|
||||
r.HandleFunc("/api/v1/apps/authentication", addAppAuthentication).Methods("PUT", "OPTIONS")
|
||||
r.HandleFunc("/api/v1/apps/authentication/{appauthId}", deleteAppAuthentication).Methods("DELETE", "OPTIONS")
|
||||
|
||||
// Legacy app things
|
||||
r.HandleFunc("/api/v1/workflows/apps/validate", validateAppInput).Methods("POST", "OPTIONS")
|
||||
r.HandleFunc("/api/v1/workflows/apps", getWorkflowApps).Methods("GET", "OPTIONS")
|
||||
|
||||
+336
-24
@@ -77,6 +77,21 @@ type Org struct {
|
||||
Id string `json:"id"`
|
||||
}
|
||||
|
||||
type AppAuthenticationStorage struct {
|
||||
Active bool `json:"active" datastore:"active"`
|
||||
Label string `json:"label" datastore:"label"`
|
||||
Id string `json:"id" datastore:"id"`
|
||||
App WorkflowApp `json:"app" datastore:"app"`
|
||||
Fields []AuthenticationStore `json:"fields" datastore:"fields"`
|
||||
Usage []AuthenticationUsage `json:"usage" datastore:"usage"`
|
||||
}
|
||||
|
||||
type AuthenticationUsage struct {
|
||||
WorkflowId string `json:"workflow_id" datastore:"workflow_id"`
|
||||
Nodes []string `json:"nodes" datastore:"nodes"`
|
||||
}
|
||||
|
||||
// An app inside Shuffle
|
||||
type WorkflowApp struct {
|
||||
Name string `json:"name" yaml:"name" required:true datastore:"name"`
|
||||
IsValid bool `json:"is_valid" yaml:"is_valid" required:true datastore:"is_valid"`
|
||||
@@ -146,7 +161,9 @@ type WorkflowAppAction struct {
|
||||
ID string `json:"id" datastore:"id" yaml:"id,omitempty"`
|
||||
Schema SchemaDefinition `json:"schema" datastore:"schema" yaml:"schema"`
|
||||
} `json:"returns" datastore:"returns"`
|
||||
Example string `json:"example" datastore:"example" yaml:"example"`
|
||||
AuthenticationId string `json:"authentication_id" datastore:"authentication_id"`
|
||||
Example string `json:"example" datastore:"example" yaml:"example"`
|
||||
AuthNotRequired bool `json:"auth_not_required" datastore:"auth_not_required" yaml:"auth_not_required"`
|
||||
}
|
||||
|
||||
// FIXME: Generate a callback authentication ID?
|
||||
@@ -202,8 +219,10 @@ type Action struct {
|
||||
X float64 `json:"x" datastore:"x"`
|
||||
Y float64 `json:"y" datastore:"y"`
|
||||
} `json:"position"`
|
||||
Priority int `json:"priority" datastore:"priority"`
|
||||
Example string `json:"example" datastore:"example"`
|
||||
Priority int `json:"priority" datastore:"priority"`
|
||||
AuthenticationId string `json:"authentication_id" datastore:"authentication_id"`
|
||||
Example string `json:"example" datastore:"example"`
|
||||
AuthNotRequired bool `json:"auth_not_required" datastore:"auth_not_required" yaml:"auth_not_required"`
|
||||
}
|
||||
|
||||
// Added environment for location to execute
|
||||
@@ -304,15 +323,16 @@ type Authentication struct {
|
||||
}
|
||||
|
||||
type AuthenticationParams struct {
|
||||
Description string `json:"description" datastore:"description" yaml:"description"`
|
||||
ID string `json:"id" datastore:"id" yaml:"id"`
|
||||
Name string `json:"name" datastore:"name" yaml:"name"`
|
||||
Example string `json:"example" datastore:"example" yaml:"example"`
|
||||
Value string `json:"value,omitempty" datastore:"value" yaml:"value"`
|
||||
Multiline bool `json:"multiline" datastore:"multiline" yaml:"multiline"`
|
||||
Required bool `json:"required" datastore:"required" yaml:"required"`
|
||||
In string `json:"in" datastore:"in" yaml:"in"`
|
||||
Scheme string `json:"scheme" datastore:"scheme" yaml:"scheme"`
|
||||
Description string `json:"description" datastore:"description" yaml:"description"`
|
||||
ID string `json:"id" datastore:"id" yaml:"id"`
|
||||
Name string `json:"name" datastore:"name" yaml:"name"`
|
||||
Example string `json:"example" datastore:"example" yaml:"example"`
|
||||
Value string `json:"value,omitempty" datastore:"value" yaml:"value"`
|
||||
Multiline bool `json:"multiline" datastore:"multiline" yaml:"multiline"`
|
||||
Required bool `json:"required" datastore:"required" yaml:"required"`
|
||||
In string `json:"in" datastore:"in" yaml:"in"`
|
||||
Schema SchemaDefinition `json:"schema" datastore:"schema" yaml:"schema"`
|
||||
Scheme string `json:"scheme" datastore:"scheme" yaml:"scheme"` // Deprecated
|
||||
}
|
||||
|
||||
type AuthenticationStore struct {
|
||||
@@ -1473,8 +1493,10 @@ func saveWorkflow(resp http.ResponseWriter, request *http.Request) {
|
||||
// FIXME - this shouldn't be necessary with proper API checks
|
||||
newActions := []Action{}
|
||||
allNodes := []string{}
|
||||
//log.Println("Pre")
|
||||
|
||||
//log.Printf("Action: %#v", action.Authentication)
|
||||
for _, action := range workflow.Actions {
|
||||
log.Printf("Auth: %s", action.AuthenticationId)
|
||||
allNodes = append(allNodes, action.ID)
|
||||
|
||||
if action.Environment == "" {
|
||||
@@ -1685,6 +1707,9 @@ func saveWorkflow(resp http.ResponseWriter, request *http.Request) {
|
||||
for _, param := range curappaction.Parameters {
|
||||
found := false
|
||||
|
||||
// FIXME: Check if the name exists in authentication.parameters and doesn't use the auth required field
|
||||
// If it does, the auth should be saved somehow.
|
||||
|
||||
// Handles check for parameter exists + value not empty in used fields
|
||||
for _, actionParam := range action.Parameters {
|
||||
if actionParam.Name == param.Name {
|
||||
@@ -2970,6 +2995,46 @@ func setWorkflow(ctx context.Context, workflow Workflow, id string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func deleteAppAuthentication(resp http.ResponseWriter, request *http.Request) {
|
||||
cors := handleCors(resp, request)
|
||||
if cors {
|
||||
return
|
||||
}
|
||||
|
||||
user, userErr := handleApiAuthentication(resp, request)
|
||||
if userErr != nil {
|
||||
log.Printf("Api authentication failed in edit workflow: %s", userErr)
|
||||
resp.WriteHeader(401)
|
||||
resp.Write([]byte(`{"success": false}`))
|
||||
return
|
||||
}
|
||||
|
||||
if user.Role != "admin" {
|
||||
log.Printf("Need to be admin to delete appauth")
|
||||
resp.WriteHeader(401)
|
||||
resp.Write([]byte(`{"success": false}`))
|
||||
return
|
||||
}
|
||||
|
||||
location := strings.Split(request.URL.String(), "/")
|
||||
log.Printf("%#v", location)
|
||||
var fileId string
|
||||
if location[1] == "api" {
|
||||
if len(location) <= 4 {
|
||||
resp.WriteHeader(401)
|
||||
resp.Write([]byte(`{"success": false}`))
|
||||
return
|
||||
}
|
||||
|
||||
fileId = location[4]
|
||||
}
|
||||
|
||||
log.Printf("ID: %s", fileId)
|
||||
|
||||
resp.WriteHeader(200)
|
||||
resp.Write([]byte(`{"success": true}`))
|
||||
}
|
||||
|
||||
func deleteWorkflowApp(resp http.ResponseWriter, request *http.Request) {
|
||||
cors := handleCors(resp, request)
|
||||
if cors {
|
||||
@@ -3194,6 +3259,195 @@ func getWorkflowAppConfig(resp http.ResponseWriter, request *http.Request) {
|
||||
resp.Write(data)
|
||||
}
|
||||
|
||||
func addAppAuthentication(resp http.ResponseWriter, request *http.Request) {
|
||||
cors := handleCors(resp, request)
|
||||
if cors {
|
||||
return
|
||||
}
|
||||
|
||||
// FIXME - need to be logged in?
|
||||
_, userErr := handleApiAuthentication(resp, request)
|
||||
if userErr != nil {
|
||||
log.Printf("Api authentication failed in get all apps: %s", userErr)
|
||||
resp.WriteHeader(401)
|
||||
resp.Write([]byte(`{"success": false}`))
|
||||
return
|
||||
}
|
||||
|
||||
body, err := ioutil.ReadAll(request.Body)
|
||||
if err != nil {
|
||||
log.Printf("Error with body read: %s", err)
|
||||
resp.WriteHeader(401)
|
||||
resp.Write([]byte(`{"success": false}`))
|
||||
return
|
||||
}
|
||||
|
||||
var appAuth AppAuthenticationStorage
|
||||
err = json.Unmarshal(body, &appAuth)
|
||||
if err != nil {
|
||||
log.Printf("Failed unmarshaling (appauth): %s", err)
|
||||
resp.WriteHeader(401)
|
||||
resp.Write([]byte(`{"success": false}`))
|
||||
return
|
||||
}
|
||||
|
||||
if len(appAuth.Id) == 0 {
|
||||
appAuth.Id = uuid.NewV4().String()
|
||||
}
|
||||
|
||||
ctx := context.Background()
|
||||
if len(appAuth.Label) == 0 {
|
||||
resp.WriteHeader(409)
|
||||
resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Label can't be empty"}`)))
|
||||
return
|
||||
}
|
||||
|
||||
if len(appAuth.App.ID) != 36 {
|
||||
log.Printf("Bad ID for app: %s", appAuth.App.ID)
|
||||
resp.WriteHeader(409)
|
||||
resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "App has to be defined"}`)))
|
||||
return
|
||||
}
|
||||
|
||||
app, err := getApp(ctx, appAuth.App.ID)
|
||||
if err != nil {
|
||||
log.Printf("Failed finding app %s while setting auth.", appAuth.App.ID)
|
||||
resp.WriteHeader(409)
|
||||
resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "%s"}`, err)))
|
||||
return
|
||||
}
|
||||
|
||||
// Check if the items are correct
|
||||
for _, field := range appAuth.Fields {
|
||||
found := false
|
||||
for _, param := range app.Authentication.Parameters {
|
||||
if field.Key == param.Name {
|
||||
found = true
|
||||
}
|
||||
}
|
||||
|
||||
if !found {
|
||||
log.Printf("Failed finding field %s in appauth fields", field.Key)
|
||||
resp.WriteHeader(409)
|
||||
resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "All auth fields required"}`)))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
err = setWorkflowAppAuthDatastore(ctx, appAuth, appAuth.Id)
|
||||
if err != nil {
|
||||
log.Printf("Failed setting up app auth %s: %s", appAuth.Id, err)
|
||||
resp.WriteHeader(409)
|
||||
resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "%s"}`, err)))
|
||||
return
|
||||
}
|
||||
|
||||
resp.WriteHeader(200)
|
||||
resp.Write([]byte(`{"success": true}`))
|
||||
}
|
||||
|
||||
func getAppAuthentication(resp http.ResponseWriter, request *http.Request) {
|
||||
cors := handleCors(resp, request)
|
||||
if cors {
|
||||
return
|
||||
}
|
||||
|
||||
_, userErr := handleApiAuthentication(resp, request)
|
||||
if userErr != nil {
|
||||
log.Printf("Api authentication failed in get all apps: %s", userErr)
|
||||
resp.WriteHeader(401)
|
||||
resp.Write([]byte(`{"success": false}`))
|
||||
return
|
||||
}
|
||||
|
||||
// FIXME: Auth to get the right ones only
|
||||
//if user.Role != "admin" {
|
||||
// log.Printf("User isn't admin")
|
||||
// resp.WriteHeader(401)
|
||||
// resp.Write([]byte(`{"success": false}`))
|
||||
// return
|
||||
//}
|
||||
ctx := context.Background()
|
||||
allAuths, err := getAllWorkflowAppAuth(ctx)
|
||||
if userErr != nil {
|
||||
log.Printf("Api authentication failed in get all app auth: %s", userErr)
|
||||
resp.WriteHeader(401)
|
||||
resp.Write([]byte(`{"success": false}`))
|
||||
return
|
||||
}
|
||||
|
||||
if len(allAuths) == 0 {
|
||||
resp.WriteHeader(200)
|
||||
resp.Write([]byte(`{"success": true, "data": []}`))
|
||||
return
|
||||
}
|
||||
|
||||
newbody, err := json.Marshal(allAuths)
|
||||
if err != nil {
|
||||
log.Printf("Failed unmarshalling all app auths: %s", err)
|
||||
resp.WriteHeader(401)
|
||||
resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Failed unpacking workflow app auth"}`)))
|
||||
return
|
||||
}
|
||||
|
||||
data := fmt.Sprintf(`{"success": true, "data": %s}`, string(newbody))
|
||||
|
||||
resp.WriteHeader(200)
|
||||
resp.Write([]byte(data))
|
||||
|
||||
/*
|
||||
data := `{
|
||||
"success": true,
|
||||
"data": [
|
||||
{
|
||||
"app": {
|
||||
"name": "thehive",
|
||||
"description": "what",
|
||||
"app_version": "1.0.0",
|
||||
"id": "4f97da9d-1caf-41cc-aa13-67104d8d825c",
|
||||
"large_image": "asd"
|
||||
},
|
||||
"fields": {
|
||||
"apikey": "hello",
|
||||
"url": "url"
|
||||
},
|
||||
"usage": [{
|
||||
"workflow_id": "asd",
|
||||
"nodes": [{
|
||||
"node_id": ""
|
||||
}]
|
||||
}],
|
||||
"label": "Original",
|
||||
"id": "4f97da9d-1caf-41cc-aa13-67104d8d825d",
|
||||
"active": true
|
||||
},
|
||||
{
|
||||
"app": {
|
||||
"name": "thehive",
|
||||
"description": "what",
|
||||
"app_version": "1.0.0",
|
||||
"id": "4f97da9d-1caf-41cc-aa13-67104d8d825c",
|
||||
"large_image": "asd"
|
||||
},
|
||||
"fields": {
|
||||
"apikey": "hello",
|
||||
"url": "url"
|
||||
},
|
||||
"usage": [{
|
||||
"workflow_id": "asd",
|
||||
"nodes": [{
|
||||
"node_id": ""
|
||||
}]
|
||||
}],
|
||||
"label": "Number 2",
|
||||
"id": "4f97da9d-1caf-41cc-aa13-67104d8d825d",
|
||||
"active": true
|
||||
}
|
||||
]
|
||||
}`
|
||||
*/
|
||||
}
|
||||
|
||||
func getWorkflowApps(resp http.ResponseWriter, request *http.Request) {
|
||||
cors := handleCors(resp, request)
|
||||
if cors {
|
||||
@@ -4208,20 +4462,54 @@ func iterateAppGithubFolders(fs billy.Filesystem, dir []os.FileInfo, extra strin
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
if workflowapp.Name == "thehive" {
|
||||
for _, action := range workflowapp.Actions {
|
||||
if len(action.Returns.Example) > 0 {
|
||||
log.Printf("ACTION: %#v", action)
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
if skip {
|
||||
continue
|
||||
}
|
||||
|
||||
// Fixes (appends) authentication parameters if they're required
|
||||
if workflowapp.Authentication.Required {
|
||||
log.Printf("Checking authentication fields and appending for %s!", workflowapp.Name)
|
||||
// FIXME:
|
||||
// Might require reflection into the python code to append the fields as well
|
||||
for index, action := range workflowapp.Actions {
|
||||
if action.AuthNotRequired {
|
||||
log.Printf("Skipping auth setup: %s", action.Name)
|
||||
continue
|
||||
}
|
||||
|
||||
// 1. Check if authentication params exists at all
|
||||
// 2. Check if they're present in the action
|
||||
// 3. Add them IF they DONT exist
|
||||
// 4. Fix python code with reflection (FIXME)
|
||||
appendParams := []WorkflowAppActionParameter{}
|
||||
for _, fieldname := range workflowapp.Authentication.Parameters {
|
||||
found := false
|
||||
for _, param := range action.Parameters {
|
||||
if param.Name == fieldname.Name {
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if !found {
|
||||
appendParams = append(appendParams, WorkflowAppActionParameter{
|
||||
Name: fieldname.Name,
|
||||
Description: fieldname.Description,
|
||||
Example: fieldname.Example,
|
||||
Required: fieldname.Required,
|
||||
Schema: fieldname.Schema,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
if len(appendParams) > 0 {
|
||||
log.Printf("Appending %d params to the START of %s", len(appendParams), action.Name)
|
||||
workflowapp.Actions[index].Parameters = append(appendParams, workflowapp.Actions[index].Parameters...)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
err = checkWorkflowApp(workflowapp)
|
||||
if err != nil {
|
||||
log.Printf("%s for app %s:%s", err, workflowapp.Name, workflowapp.AppVersion)
|
||||
@@ -4270,7 +4558,7 @@ func iterateAppGithubFolders(fs billy.Filesystem, dir []os.FileInfo, extra strin
|
||||
if len(tags) > 0 {
|
||||
log.Printf("Successfully built image %s", tags[0])
|
||||
} else {
|
||||
log.Printf("Successfully built image docker img")
|
||||
log.Printf("Successfully built Docker image")
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4473,6 +4761,30 @@ func getAllWorkflowApps(ctx context.Context) ([]WorkflowApp, error) {
|
||||
return allworkflowapps, nil
|
||||
}
|
||||
|
||||
func getAllWorkflowAppAuth(ctx context.Context) ([]AppAuthenticationStorage, error) {
|
||||
var allworkflowapps []AppAuthenticationStorage
|
||||
q := datastore.NewQuery("workflowappauth")
|
||||
|
||||
_, err := dbclient.GetAll(ctx, q, &allworkflowapps)
|
||||
if err != nil {
|
||||
return []AppAuthenticationStorage{}, err
|
||||
}
|
||||
|
||||
return allworkflowapps, nil
|
||||
}
|
||||
|
||||
func setWorkflowAppAuthDatastore(ctx context.Context, workflowappauth AppAuthenticationStorage, id string) error {
|
||||
key := datastore.NameKey("workflowappauth", id, nil)
|
||||
|
||||
// New struct, to not add body, author etc
|
||||
if _, err := dbclient.Put(ctx, key, &workflowappauth); err != nil {
|
||||
log.Printf("Error adding workflow app: %s", err)
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Hmm, so I guess this should use uuid :(
|
||||
// Consistency PLX
|
||||
func setWorkflowAppDatastore(ctx context.Context, workflowapp WorkflowApp, id string) error {
|
||||
|
||||
+194
-3
@@ -33,10 +33,13 @@ const Admin = (props) => {
|
||||
const [curTab, setCurTab] = React.useState(0);
|
||||
const [users, setUsers] = React.useState([]);
|
||||
const [environments, setEnvironments] = React.useState([]);
|
||||
const [authentication, setAuthentication] = React.useState([]);
|
||||
const [schedules, setSchedules] = React.useState([])
|
||||
const [selectedUser, setSelectedUser] = React.useState({})
|
||||
const [newPassword, setNewPassword] = React.useState("");
|
||||
const [selectedUserModalOpen, setSelectedUserModalOpen] = React.useState(false)
|
||||
const [selectedAuthentication, setSelectedAuthentcation] = React.useState({})
|
||||
const [selectedAuthenticationModalOpen, setSelectedAuthenticationModalOpen] = React.useState(false)
|
||||
|
||||
const alert = useAlert()
|
||||
|
||||
@@ -253,6 +256,35 @@ const Admin = (props) => {
|
||||
});
|
||||
}
|
||||
|
||||
const getAppAuthentication = () => {
|
||||
fetch(globalUrl+"/api/v1/apps/authentication", {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'Accept': 'application/json',
|
||||
},
|
||||
credentials: "include",
|
||||
})
|
||||
.then((response) => {
|
||||
if (response.status !== 200) {
|
||||
console.log("Status not 200 for apps :O!")
|
||||
return
|
||||
}
|
||||
|
||||
return response.json()
|
||||
})
|
||||
.then((responseJson) => {
|
||||
if (responseJson.success) {
|
||||
setAuthentication(responseJson.data)
|
||||
} else {
|
||||
alert.error("Failed getting authentications")
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
alert.error(error.toString())
|
||||
});
|
||||
}
|
||||
|
||||
const getEnvironments = () => {
|
||||
fetch(globalUrl+"/api/v1/getenvironments", {
|
||||
method: 'GET',
|
||||
@@ -393,6 +425,70 @@ const Admin = (props) => {
|
||||
});
|
||||
}
|
||||
|
||||
const editAuthenticationModal =
|
||||
<Dialog modal
|
||||
open={selectedAuthenticationModalOpen}
|
||||
onClose={() => {setSelectedAuthenticationModalOpen(false)}}
|
||||
PaperProps={{
|
||||
style: {
|
||||
backgroundColor: surfaceColor,
|
||||
color: "white",
|
||||
minWidth: "800px",
|
||||
minHeight: "320px",
|
||||
},
|
||||
}}
|
||||
>
|
||||
<DialogTitle><span style={{color: "white"}}>Edit authentication</span></DialogTitle>
|
||||
<DialogContent>
|
||||
<div style={{display: "flex"}}>
|
||||
<TextField
|
||||
style={{backgroundColor: inputColor, flex: 3}}
|
||||
InputProps={{
|
||||
style:{
|
||||
height: 50,
|
||||
color: "white",
|
||||
},
|
||||
}}
|
||||
color="primary"
|
||||
required
|
||||
fullWidth={true}
|
||||
placeholder="New password"
|
||||
type="password"
|
||||
id="standard-required"
|
||||
autoComplete="password"
|
||||
margin="normal"
|
||||
variant="outlined"
|
||||
onChange={e => setNewPassword(e.target.value)}
|
||||
/>
|
||||
<Button
|
||||
style={{maxHeight: 50, flex: 1}}
|
||||
variant="outlined"
|
||||
color="primary"
|
||||
onClick={() => onPasswordChange()}
|
||||
>
|
||||
Submit
|
||||
</Button>
|
||||
</div>
|
||||
<Divider style={{marginTop: 20, marginBottom: 20, backgroundColor: inputColor}}/>
|
||||
<Button
|
||||
style={{}}
|
||||
variant="outlined"
|
||||
color="primary"
|
||||
onClick={() => deleteUser(selectedUser)}
|
||||
>
|
||||
{selectedUser.active ? "Deactivate" : "Activate"}
|
||||
</Button>
|
||||
<Button
|
||||
style={{}}
|
||||
variant="outlined"
|
||||
color="primary"
|
||||
onClick={() => generateApikey(selectedUser.id)}
|
||||
>
|
||||
Get new API key
|
||||
</Button>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
|
||||
const editUserModal =
|
||||
<Dialog modal
|
||||
open={selectedUserModalOpen}
|
||||
@@ -660,7 +756,7 @@ const Admin = (props) => {
|
||||
</div>
|
||||
: null
|
||||
|
||||
const schedulesView = curTab === 2 ?
|
||||
const schedulesView = curTab === 3 ?
|
||||
<div>
|
||||
<h2>
|
||||
Schedules
|
||||
@@ -708,7 +804,97 @@ const Admin = (props) => {
|
||||
</div>
|
||||
: null
|
||||
|
||||
const environmentView = curTab === 1 ?
|
||||
const authenticationView = curTab === 1 ?
|
||||
<div>
|
||||
<h2>
|
||||
Authentication
|
||||
</h2>
|
||||
<Divider style={{marginTop: 20, marginBottom: 20, backgroundColor: inputColor}}/>
|
||||
<List>
|
||||
<ListItem>
|
||||
<ListItemText
|
||||
primary="Icon"
|
||||
style={{minWidth: 150, maxWidth: 150}}
|
||||
/>
|
||||
<ListItemText
|
||||
primary="Label"
|
||||
style={{minWidth: 150, maxWidth: 150}}
|
||||
/>
|
||||
<ListItemText
|
||||
primary="App Name"
|
||||
style={{minWidth: 150, maxWidth: 150}}
|
||||
/>
|
||||
<ListItemText
|
||||
primary="Fields"
|
||||
style={{minWidth: 320, maxWidth: 320, overflow: "hidden"}}
|
||||
/>
|
||||
<ListItemText
|
||||
primary="Workflow usage"
|
||||
style={{minWidth: 320, maxWidth: 320, overflow: "hidden"}}
|
||||
/>
|
||||
<ListItemText
|
||||
primary="Actions (TBD)"
|
||||
/>
|
||||
</ListItem>
|
||||
{authentication === undefined ? null : authentication.map(data => {
|
||||
return (
|
||||
<ListItem>
|
||||
<ListItemText
|
||||
primary=<img alt="" src={data.app.large_image} style={{maxWidth: 50,}} />
|
||||
style={{minWidth: 150, maxWidth: 150}}
|
||||
/>
|
||||
<ListItemText
|
||||
primary={data.label}
|
||||
style={{minWidth: 150, maxWidth: 150}}
|
||||
/>
|
||||
<ListItemText
|
||||
primary={data.app.name}
|
||||
style={{minWidth: 150, maxWidth: 150}}
|
||||
/>
|
||||
<ListItemText
|
||||
primary={data.fields.map(data => {
|
||||
return data.key
|
||||
}).join(", ")}
|
||||
style={{minWidth: 320, maxWidth: 320, overflow: "hidden"}}
|
||||
/>
|
||||
<ListItemText
|
||||
primary={data.usage.length}
|
||||
style={{minWidth: 320, maxWidth: 320, overflow: "hidden"}}
|
||||
/>
|
||||
<ListItemText>
|
||||
<Button
|
||||
style={{}}
|
||||
variant="contained"
|
||||
color="primary"
|
||||
disabled={true}
|
||||
onClick={() => {
|
||||
setSelectedAuthentcation(data)
|
||||
setSelectedAuthenticationModalOpen(true)
|
||||
}}
|
||||
>
|
||||
Edit
|
||||
</Button>
|
||||
<Button
|
||||
style={{}}
|
||||
variant="contained"
|
||||
color="primary"
|
||||
disabled={true}
|
||||
onClick={() => {
|
||||
setSelectedAuthentcation(data)
|
||||
setSelectedAuthenticationModalOpen(true)
|
||||
}}
|
||||
>
|
||||
Delete
|
||||
</Button>
|
||||
</ListItemText>
|
||||
</ListItem>
|
||||
)
|
||||
})}
|
||||
</List>
|
||||
</div>
|
||||
: null
|
||||
|
||||
const environmentView = curTab === 2 ?
|
||||
<div>
|
||||
<h2>
|
||||
Environments
|
||||
@@ -737,8 +923,10 @@ const Admin = (props) => {
|
||||
|
||||
const setConfig = (event, newValue) => {
|
||||
if (newValue === 1) {
|
||||
getEnvironments()
|
||||
getAppAuthentication()
|
||||
} else if (newValue === 2) {
|
||||
getEnvironments()
|
||||
} else if (newValue === 3) {
|
||||
getSchedules()
|
||||
}
|
||||
|
||||
@@ -757,10 +945,12 @@ const Admin = (props) => {
|
||||
aria-label="disabled tabs example"
|
||||
>
|
||||
<Tab label="Users" />
|
||||
<Tab label="App Authentication"/>
|
||||
<Tab label="Environments"/>
|
||||
<Tab label="Schedules"/>
|
||||
</Tabs>
|
||||
<div style={{marginBottom: 10}}/>
|
||||
{authenticationView}
|
||||
{usersView}
|
||||
{environmentView}
|
||||
{schedulesView}
|
||||
@@ -771,6 +961,7 @@ const Admin = (props) => {
|
||||
<div>
|
||||
{modalView}
|
||||
{editUserModal}
|
||||
{editAuthenticationModal}
|
||||
{data}
|
||||
</div>
|
||||
)
|
||||
|
||||
+293
-77
@@ -37,6 +37,7 @@ import { useBeforeunload } from 'react-beforeunload';
|
||||
|
||||
import ArrowUpwardIcon from '@material-ui/icons/ArrowUpward';
|
||||
import CachedIcon from '@material-ui/icons/Cached';
|
||||
import AddIcon from '@material-ui/icons/Add';
|
||||
import DirectionsRunIcon from '@material-ui/icons/DirectionsRun';
|
||||
import PolymerIcon from '@material-ui/icons/Polymer';
|
||||
import CreateIcon from '@material-ui/icons/Create';
|
||||
@@ -117,7 +118,7 @@ const AngularWorkflow = (props) => {
|
||||
const [executionText, setExecutionText] = React.useState("");
|
||||
const [executionRequestStarted, setExecutionRequestStarted] = React.useState(false);
|
||||
|
||||
const [appAuthentication, setAppAuthentication] = React.useState({});
|
||||
const [appAuthentication, setAppAuthentication] = React.useState([]);
|
||||
const [variablesModalOpen, setVariablesModalOpen] = React.useState(false);
|
||||
const [executionVariablesModalOpen, setExecutionVariablesModalOpen] = React.useState(false);
|
||||
const [authenticationModalOpen, setAuthenticationModalOpen] = React.useState(false);
|
||||
@@ -127,7 +128,7 @@ const AngularWorkflow = (props) => {
|
||||
const [newVariableValue, setNewVariableValue] = React.useState("");
|
||||
const [workflowDone, setWorkflowDone] = React.useState(false)
|
||||
const [localFirstrequest, setLocalFirstrequest] = React.useState(true)
|
||||
const [requiresAuthentication, setRequiresAuthentication] = React.useState(true)
|
||||
const [requiresAuthentication, setRequiresAuthentication] = React.useState(false)
|
||||
const [rightSideBarOpen, setRightSideBarOpen] = React.useState(false)
|
||||
const [showSkippedActions, setShowSkippedActions] = React.useState(false)
|
||||
|
||||
@@ -193,6 +194,37 @@ const AngularWorkflow = (props) => {
|
||||
}
|
||||
})
|
||||
|
||||
const setNewAppAuth = (appAuthData) => {
|
||||
console.log("DAta: ", appAuthData)
|
||||
fetch(globalUrl+"/api/v1/apps/authentication", {
|
||||
method: 'PUT',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'Accept': 'application/json',
|
||||
},
|
||||
body: JSON.stringify(appAuthData),
|
||||
credentials: "include",
|
||||
})
|
||||
.then((response) => {
|
||||
if (response.status !== 200) {
|
||||
console.log("Status not 200 for setting app auth :O!")
|
||||
}
|
||||
|
||||
return response.json()
|
||||
})
|
||||
.then((responseJson) => {
|
||||
if (!responseJson.success) {
|
||||
alert.error("Failed to set app auth: "+responseJson.reason)
|
||||
} else {
|
||||
setAuthenticationModalOpen(false)
|
||||
alert.success("Successfully saved workflow")
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
alert.error(error.toString())
|
||||
})
|
||||
}
|
||||
|
||||
const getWorkflowExecution = (id) => {
|
||||
fetch(globalUrl+"/api/v1/workflows/"+id+"/executions", {
|
||||
method: 'GET',
|
||||
@@ -723,6 +755,35 @@ const AngularWorkflow = (props) => {
|
||||
return data
|
||||
}
|
||||
|
||||
const getAppAuthentication = () => {
|
||||
fetch(globalUrl+"/api/v1/apps/authentication", {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'Accept': 'application/json',
|
||||
},
|
||||
credentials: "include",
|
||||
})
|
||||
.then((response) => {
|
||||
if (response.status !== 200) {
|
||||
console.log("Status not 200 for apps :O!")
|
||||
return
|
||||
}
|
||||
|
||||
return response.json()
|
||||
})
|
||||
.then((responseJson) => {
|
||||
if (responseJson.success) {
|
||||
setAppAuthentication(responseJson.data)
|
||||
} else {
|
||||
alert.error("Failed getting authentications")
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
alert.error(error.toString())
|
||||
});
|
||||
}
|
||||
|
||||
const getApps = () => {
|
||||
fetch(globalUrl+"/api/v1/workflows/apps", {
|
||||
method: 'GET',
|
||||
@@ -747,6 +808,7 @@ const AngularWorkflow = (props) => {
|
||||
//tmpapps = tmpapps.concat(responseJson)
|
||||
setApps(responseJson)
|
||||
setFilteredApps(responseJson)
|
||||
getAppAuthentication()
|
||||
})
|
||||
.catch(error => {
|
||||
alert.error(error.toString())
|
||||
@@ -831,9 +893,9 @@ const AngularWorkflow = (props) => {
|
||||
// FIXME - unselect
|
||||
//console.log(cy.elements('[_id!="${data._id}"]`))
|
||||
// Does it choose the wrong action?
|
||||
const curaction = workflow.actions.find(a => a.id === data.id)
|
||||
var curaction = workflow.actions.find(a => a.id === data.id)
|
||||
if (!curaction || curaction === undefined) {
|
||||
//console.log("Action not found error")
|
||||
//alert.error("Action not found. Please remake it.")
|
||||
return
|
||||
}
|
||||
|
||||
@@ -848,11 +910,41 @@ const AngularWorkflow = (props) => {
|
||||
env = environments[0]
|
||||
}
|
||||
|
||||
setSelectedApp(curapp)
|
||||
setSelectedAction(curaction)
|
||||
setSelectedActionEnvironment(env)
|
||||
setSelectedActionName(curaction.name)
|
||||
setRequiresAuthentication(curapp.authentication.required)
|
||||
|
||||
// Setup auth here :)
|
||||
const authenticationOptions = []
|
||||
var findAuthId = ""
|
||||
if (curaction.authentication_id !== null && curaction.authentication_id !== undefined && curaction.authentication_id.length > 0) {
|
||||
findAuthId = curaction.authentication_id
|
||||
}
|
||||
|
||||
for (var key in appAuthentication) {
|
||||
var item = appAuthentication[key]
|
||||
|
||||
const newfields = {}
|
||||
for (var filterkey in item.fields) {
|
||||
newfields[item.fields[filterkey].key] = item.fields[filterkey].value
|
||||
}
|
||||
|
||||
item.fields = newfields
|
||||
if (item.app.name === curapp.name) {
|
||||
authenticationOptions.push(item)
|
||||
if (item.id === findAuthId) {
|
||||
curaction.selectedAuthentication = item
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
curaction.authentication = authenticationOptions
|
||||
if (curaction.selectedAuthentication === null || curaction.selectedAuthentication === undefined || curaction.selectedAuthentication.length === "") {
|
||||
curaction.selectedAuthentication = {}
|
||||
}
|
||||
|
||||
setSelectedApp(curapp)
|
||||
setSelectedAction(curaction)
|
||||
} else if (data.type === "TRIGGER") {
|
||||
//console.log("Should handle trigger "+data.triggertype)
|
||||
//console.log(data)
|
||||
@@ -1130,6 +1222,7 @@ const AngularWorkflow = (props) => {
|
||||
setFirstrequest(false)
|
||||
getWorkflow()
|
||||
getApps()
|
||||
getAppAuthentication()
|
||||
getEnvironments()
|
||||
getWorkflowExecution(props.match.params.key)
|
||||
return
|
||||
@@ -2280,10 +2373,6 @@ const AngularWorkflow = (props) => {
|
||||
|
||||
useEffect(() => {
|
||||
if (selectedActionParameters !== null && selectedActionParameters.length === 0) {
|
||||
if (requiresAuthentication) {
|
||||
console.log("ADD AUTHENTICATION FIELDS")
|
||||
}
|
||||
|
||||
if (selectedAction.parameters !== null && selectedAction.parameters.length > 0) {
|
||||
setSelectedActionParameters(selectedAction.parameters)
|
||||
}
|
||||
@@ -2493,6 +2582,16 @@ const AngularWorkflow = (props) => {
|
||||
data.variant = "STATIC_VALUE"
|
||||
}
|
||||
|
||||
if (!selectedAction.auth_not_required && selectedAction.selectedAuthentication !== undefined && selectedAction.selectedAuthentication.fields !== undefined) {
|
||||
if (selectedAction.selectedAuthentication.fields[data.name] !== undefined) {
|
||||
// FIXME - this should be skipped in the frontend
|
||||
selectedActionParameters[count].value = selectedAction.selectedAuthentication.fields[data.name]
|
||||
selectedAction.parameters[count].value = selectedAction.selectedAuthentication.fields[data.name]
|
||||
setSelectedAction(selectedAction)
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
var staticcolor = "inherit"
|
||||
var actioncolor = "inherit"
|
||||
var varcolor = "inherit"
|
||||
@@ -2935,7 +3034,65 @@ const AngularWorkflow = (props) => {
|
||||
placeholder={selectedAction.label}
|
||||
onChange={selectedNameChange}
|
||||
/>
|
||||
{environments !== undefined && environments !== null && environments.length > 0 ?
|
||||
{selectedAction.authentication.length === 0 && requiresAuthentication ?
|
||||
<div style={{marginTop: 15}}>
|
||||
Authentication (reusable):
|
||||
<Tooltip color="primary" title={"Add authentication option"} placement="top">
|
||||
<Button color="primary" style={{}} variant="text" onClick={() => {
|
||||
setAuthenticationModalOpen(true)
|
||||
}}>
|
||||
<AddIcon />
|
||||
</Button>
|
||||
</Tooltip>
|
||||
</div>
|
||||
: null}
|
||||
{selectedAction.authentication.length > 0 ?
|
||||
<div style={{marginTop: "20px"}}>
|
||||
Authentication
|
||||
<div style={{display: "flex"}}>
|
||||
<Select
|
||||
value={selectedAction.selectedAuthentication}
|
||||
SelectDisplayProps={{
|
||||
style: {
|
||||
marginLeft: 10,
|
||||
}
|
||||
}}
|
||||
fullWidth
|
||||
onChange={(e) => {
|
||||
console.log("CHOSE AN AUTHENTICATION OPTION: ", e.target.value)
|
||||
selectedAction.selectedAuthentication = e.target.value
|
||||
selectedAction.authentication_id = e.target.value.id
|
||||
setSelectedAction(selectedAction)
|
||||
setUpdate("update auth")
|
||||
}}
|
||||
style={{backgroundColor: inputColor, color: "white", height: "50px"}}
|
||||
>
|
||||
{selectedAction.authentication.map(data => (
|
||||
<MenuItem key={data.id} style={{backgroundColor: inputColor, color: "white"}} value={data}>
|
||||
{data.label} - ({data.app.app_version})
|
||||
</MenuItem>
|
||||
))}
|
||||
</Select>
|
||||
|
||||
{/*
|
||||
|
||||
<Button fullWidth style={{margin: "auto", marginTop: "10px",}} color="primary" variant="contained" onClick={() => setAuthenticationModalOpen(true)}>
|
||||
AUTHENTICATE
|
||||
</Button>
|
||||
curaction.authentication = authenticationOptions
|
||||
if (curaction.selectedAuthentication === null || curaction.selectedAuthentication === undefined || curaction.selectedAuthentication.length === "")
|
||||
*/}
|
||||
<Tooltip color="primary" title={"Add authentication option"} placement="top">
|
||||
<Button color="primary" style={{}} variant="text" onClick={() => {
|
||||
setAuthenticationModalOpen(true)
|
||||
}}>
|
||||
<AddIcon />
|
||||
</Button>
|
||||
</Tooltip>
|
||||
</div>
|
||||
</div>
|
||||
: null}
|
||||
{environments !== undefined && environments !== null && environments.length > 1 ?
|
||||
<div style={{marginTop: "20px"}}>
|
||||
Environment
|
||||
<Select
|
||||
@@ -2997,13 +3154,6 @@ const AngularWorkflow = (props) => {
|
||||
</Select>
|
||||
</div>
|
||||
: null}
|
||||
{/*requiresAuthentication ?
|
||||
<div style={{marginTop: "20px"}}>
|
||||
<Button fullWidth style={{margin: "auto", marginTop: "10px",}} color="primary" variant="contained" onClick={() => setAuthenticationModalOpen(true)}>
|
||||
AUTHENTICATE
|
||||
</Button>
|
||||
</div>
|
||||
: null*/}
|
||||
<Divider style={{marginTop: "20px", height: "1px", width: "100%", backgroundColor: "rgb(91, 96, 100)"}}/>
|
||||
<div style={{flex: "6", marginTop: "20px"}}>
|
||||
<div style={{marginBottom: 5}}>
|
||||
@@ -3033,7 +3183,7 @@ const AngularWorkflow = (props) => {
|
||||
newActionname = newActionname.replace("_", " ")
|
||||
newActionname = newActionname.charAt(0).toUpperCase()+newActionname.substring(1)
|
||||
return (
|
||||
<MenuItem style={{maxWidth: 400, overflowX: "hidden", backgroundColor: inputColor, color: "white"}} value={data.name}>
|
||||
<MenuItem key={data.name} style={{maxWidth: 400, overflowX: "hidden", backgroundColor: inputColor, color: "white"}} value={data.name}>
|
||||
{newActionname}
|
||||
|
||||
</MenuItem>
|
||||
@@ -5243,52 +5393,136 @@ const AngularWorkflow = (props) => {
|
||||
: null
|
||||
|
||||
|
||||
const AuthenticationData = () => {
|
||||
console.log("AUTH: ", selectedApp.authentication)
|
||||
const [tmpVar, setTmpVar] = React.useState("")
|
||||
const AuthenticationData = (props) => {
|
||||
const selectedApp = props.app
|
||||
|
||||
const [authenticationOption, setAuthenticationOptions] = React.useState({
|
||||
app: JSON.parse(JSON.stringify(selectedApp)),
|
||||
fields: {},
|
||||
label: "",
|
||||
usage: [{
|
||||
workflow_id: workflow.id,
|
||||
}],
|
||||
id: uuid.v4(),
|
||||
active: true,
|
||||
})
|
||||
|
||||
if (selectedApp.authentication === undefined) {
|
||||
return null
|
||||
}
|
||||
|
||||
if (selectedApp.authentication.parameters.length === undefined ||
|
||||
selectedApp.authentication.parameters.length === 0) {
|
||||
if (selectedApp.authentication.parameters.length === undefined || selectedApp.authentication.parameters.length === 0) {
|
||||
return null
|
||||
}
|
||||
|
||||
// Yes, it should be possible to have more than one, but.. :)
|
||||
// This data should be written to a KMS, then have the ID point back
|
||||
const currentAuth = selectedApp.authentication.parameters[0]
|
||||
if (currentAuth.scheme.toLowerCase() === "bearer") {
|
||||
return <div>
|
||||
Insert your API token for {selectedApp.name}
|
||||
<TextField
|
||||
style={{backgroundColor: inputColor}}
|
||||
InputProps={{
|
||||
style:{
|
||||
color: "white",
|
||||
height: "50px",
|
||||
fontSize: "1em",
|
||||
},
|
||||
}}
|
||||
fullWidth
|
||||
type="password"
|
||||
color="primary"
|
||||
placeholder="Bearer token"
|
||||
onChange={(event) => {
|
||||
setTmpVar(event.target.value)
|
||||
}}
|
||||
onBlur={() => {
|
||||
selectedApp.authentication.parameters[0].value = tmpVar
|
||||
setSelectedApp(selectedApp)
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
authenticationOption.app.actions = []
|
||||
|
||||
for (var key in selectedApp.authentication.parameters) {
|
||||
if (authenticationOption.fields[selectedApp.authentication.parameters[key].name] === undefined) {
|
||||
authenticationOption.fields[selectedApp.authentication.parameters[key].name] = ""
|
||||
}
|
||||
}
|
||||
|
||||
const handleSubmitCheck = () => {
|
||||
console.log(authenticationOption)
|
||||
if (authenticationOption.label.length === 0) {
|
||||
alert.info("Label can't be empty")
|
||||
}
|
||||
|
||||
for (var key in selectedApp.authentication.parameters) {
|
||||
if (authenticationOption.fields[selectedApp.authentication.parameters[key].name].length === 0) {
|
||||
alert.info("Field "+selectedApp.authentication.parameters[key].name+" can't be empty")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
selectedAction.authentication_id = authenticationOption.id
|
||||
selectedAction.selectedAuthentication = authenticationOption
|
||||
selectedAction.authentication.push(authenticationOption)
|
||||
setSelectedAction(selectedAction)
|
||||
|
||||
var newFields = []
|
||||
for (const key in authenticationOption.fields) {
|
||||
const value = authenticationOption.fields[key]
|
||||
newFields.push({
|
||||
key: key,
|
||||
value: value,
|
||||
})
|
||||
}
|
||||
|
||||
authenticationOption.fields = newFields
|
||||
setNewAppAuth(authenticationOption)
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
NOT IMPLEMENTED <div/>
|
||||
Unknown auth: {currentAuth.scheme}
|
||||
<DialogContent>
|
||||
<a href="https://shuffler.io/docs/apps#authentication" style={{textDecoration: "none", color: "#f85a3e"}}>What is this?</a>
|
||||
These are required fields for authenticating with TheHive
|
||||
<div style={{marginTop: 15}}/>
|
||||
{selectedApp.link.length > 0 ? <EndpointData /> : null}
|
||||
Label (to remember it)
|
||||
<TextField
|
||||
style={{backgroundColor: inputColor}}
|
||||
InputProps={{
|
||||
style:{
|
||||
color: "white",
|
||||
marginLeft: "5px",
|
||||
maxWidth: "95%",
|
||||
height: "50px",
|
||||
fontSize: "1em",
|
||||
},
|
||||
}}
|
||||
fullWidth
|
||||
color="primary"
|
||||
placeholder={"Auth july 2020"}
|
||||
onChange={(event) => {
|
||||
authenticationOption.label = event.target.value
|
||||
}}
|
||||
/>
|
||||
<Divider style={{marginTop: 15, marginBottom: 15}}/>
|
||||
<div style={{}}/>
|
||||
{selectedApp.authentication.parameters.map((data, index) => {
|
||||
return (
|
||||
<div key={index} style={{marginTop: 10}}>
|
||||
{data.name}
|
||||
<TextField
|
||||
style={{backgroundColor: inputColor}}
|
||||
InputProps={{
|
||||
style:{
|
||||
color: "white",
|
||||
marginLeft: "5px",
|
||||
maxWidth: "95%",
|
||||
height: "50px",
|
||||
fontSize: "1em",
|
||||
},
|
||||
}}
|
||||
fullWidth
|
||||
type={data.example !== undefined && data.example.includes("***") ? "password" : "text"}
|
||||
color="primary"
|
||||
placeholder={data.example}
|
||||
onChange={(event) => {
|
||||
authenticationOption.fields[data.name] = event.target.value
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
})}
|
||||
</DialogContent>
|
||||
<DialogActions>
|
||||
<Button
|
||||
style={{borderRadius: "0px"}}
|
||||
onClick={() => {
|
||||
setAuthenticationModalOpen(false)
|
||||
}} color="primary">
|
||||
Cancel
|
||||
</Button>
|
||||
<Button style={{borderRadius: "0px"}} onClick={() => {
|
||||
handleSubmitCheck()
|
||||
}} color="primary">
|
||||
Submit
|
||||
</Button>
|
||||
</DialogActions>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -5328,40 +5562,22 @@ const AngularWorkflow = (props) => {
|
||||
|
||||
// This whole part is redundant. Made it part of Arguments instead.
|
||||
const authenticationModal = authenticationModalOpen ?
|
||||
<Dialog modal
|
||||
<Dialog
|
||||
open={authenticationModalOpen}
|
||||
onClose={() => {
|
||||
setAuthenticationModalOpen(false)
|
||||
setAppAuthentication({})
|
||||
//setAuthenticationModalOpen(false)
|
||||
}}
|
||||
PaperProps={{
|
||||
style: {
|
||||
backgroundColor: surfaceColor,
|
||||
color: "white",
|
||||
minWidth: "800px",
|
||||
minWidth: 600,
|
||||
padding: 15,
|
||||
},
|
||||
}}
|
||||
>
|
||||
<DialogTitle><div style={{color: "white"}}>Authentication for {selectedApp.name}</div></DialogTitle>
|
||||
<DialogContent>
|
||||
<a href="https://shuffler.io/docs/apps#authentication" style={{textDecoration: "none", color: "#f85a3e"}}>What is this?</a>
|
||||
<div />
|
||||
{selectedApp.link.length > 0 ? <EndpointData /> : null}
|
||||
<div style={{marginTop: 15, marginBottom: 15, }}/>
|
||||
<AuthenticationData />
|
||||
</DialogContent>
|
||||
<DialogActions>
|
||||
<Button
|
||||
style={{borderRadius: "0px"}}
|
||||
onClick={() => {
|
||||
setAuthenticationModalOpen(false)
|
||||
}} color="primary">
|
||||
Cancel
|
||||
</Button>
|
||||
<Button style={{borderRadius: "0px"}} onClick={() => {setAuthenticationModalOpen(false)}} color="primary">
|
||||
Submit
|
||||
</Button>
|
||||
</DialogActions>
|
||||
<AuthenticationData app={selectedApp} />
|
||||
</Dialog> : null
|
||||
|
||||
const loadedCheck = isLoaded && isLoggedIn && workflowDone ?
|
||||
|
||||
@@ -289,8 +289,8 @@ const Apps = (props) => {
|
||||
<Paper square style={paperAppStyle} onClick={() => {
|
||||
if (selectedApp.id !== data.id) {
|
||||
setSelectedApp(data)
|
||||
console.log(data)
|
||||
if (data.actions !== undefined && data.actions !== null && data.actions.length > 0) {
|
||||
console.log(data.actions[0])
|
||||
setSelectedAction(data.actions[0])
|
||||
} else {
|
||||
setSelectedAction({})
|
||||
|
||||
Reference in New Issue
Block a user