Skip to content

Commit

Permalink
Added authentication injection for apps that are missing auth fields
Browse files Browse the repository at this point in the history
  • Loading branch information
frikky committed Nov 21, 2024
1 parent 569f4cb commit 3ab4161
Show file tree
Hide file tree
Showing 2 changed files with 121 additions and 62 deletions.
53 changes: 42 additions & 11 deletions db-connector.go
Original file line number Diff line number Diff line change
Expand Up @@ -3923,6 +3923,12 @@ func GetOrgByCreatorId(ctx context.Context, id string) (*Org, error) {
// Handles org grabbing and user / org migrations
func GetOrg(ctx context.Context, id string) (*Org, error) {
nameKey := "Organizations"


if id == "public" {
return &Org{}, errors.New("'public' org is used for single action without being logged in. Not relevant.")
}

cacheKey := fmt.Sprintf("%s_%s", nameKey, id)

curOrg := &Org{}
Expand Down Expand Up @@ -6461,15 +6467,6 @@ func GetPrioritizedApps(ctx context.Context, user User) ([]WorkflowApp, error) {
continue
}

//log.Printf("[INFO] Found duplicate app: %s (%s). Dedup index: %d", app.Name, app.ID, replaceIndex)
// If owner of dedup, don't change
/*
if dedupedApps[replaceIndex].Owner == user.Id {
log.Printf("[INFO] Owner of deduped app is user. Not replacing.")
continue
}
*/

// Check if one is referenceOrg not
if dedupedApps[replaceIndex].ReferenceOrg == user.ActiveOrg.Id {
continue
Expand All @@ -6481,7 +6478,6 @@ func GetPrioritizedApps(ctx context.Context, user User) ([]WorkflowApp, error) {
}

if app.Edited > dedupedApps[replaceIndex].Edited {
//log.Printf("[INFO] Replacing deduped app with newer app in get apps: %s", app.Name)
dedupedApps[replaceIndex] = app
continue
}
Expand All @@ -6494,12 +6490,32 @@ func GetPrioritizedApps(ctx context.Context, user User) ([]WorkflowApp, error) {
}

allApps = dedupedApps

for appIndex, app := range allApps {
requiredAuthFields := []WorkflowAppActionParameter{}
if app.Authentication.Required {
for _, param := range app.Authentication.Parameters {
requiredAuthFields = append(requiredAuthFields, WorkflowAppActionParameter{
Description: param.Description,
ID: param.ID,
Name: param.Name,
Example: param.Example,
Value: param.Value,
Multiline: param.Multiline,
Required: param.Required,
})
}
}

for actionIndex, action := range app.Actions {
lastRequiredIndex := -1
bodyIndex := -1

authFields := []string{}
for paramIndex, param := range action.Parameters {
if param.Configuration {
authFields = append(authFields, param.Name)
}

if param.Required {
lastRequiredIndex = paramIndex
}
Expand Down Expand Up @@ -6528,6 +6544,21 @@ func GetPrioritizedApps(ctx context.Context, user User) ([]WorkflowApp, error) {
if bodyIndex > -1 {
//log.Printf("[INFO] Moving body parameter to index %d after %d", lastRequiredIndex+1, bodyIndex)
}

if len(authFields) < len(requiredAuthFields) {
if app.Authentication.Type == "oauth2" || app.Authentication.Type == "oauth2-app" {
continue
}

if action.Name == "custom_action" {
continue
}

//log.Printf("[INFO] App %s' action %s has %d auth fields, but only %d required", app.Name, action.Name, len(authFields), len(requiredAuthFields))
for _, requiredField := range requiredAuthFields {
allApps[appIndex].Actions[actionIndex].Parameters = append(allApps[appIndex].Actions[actionIndex].Parameters, requiredField)
}
}
}
}

Expand Down
130 changes: 79 additions & 51 deletions shared.go
Original file line number Diff line number Diff line change
Expand Up @@ -8175,7 +8175,7 @@ func SaveWorkflow(resp http.ResponseWriter, request *http.Request) {

param = actionParam
if len(actionParam.Value) > 0 {
foundWithValue = true
foundWithValue = true
}

newParamsContains := false
Expand Down Expand Up @@ -17760,73 +17760,86 @@ func PrepareSingleAction(ctx context.Context, user User, fileId string, body []b
return workflowExecution, err
}

/*
// FIXME: Is this required? I don't think so
if app.Authentication.Required && len(action.AuthenticationId) == 0 {

if app.Authentication.Required && len(action.AuthenticationId) == 0 {

// Basic bypass check for valid headers just in case
authFound := false
for _, param := range action.Parameters {
if param.Name == "headers" || param.Name == "queries" || param.Name == "url" {
lowercased := strings.ToLower(param.Value)
if strings.Contains(lowercased, "auth") || strings.Contains(lowercased, "bearer") || strings.Contains(lowercased, "basic") || strings.Contains(lowercased, "api") {
authFound = true
break
// Basic bypass check for valid headers just in case
authFound := false
for _, param := range action.Parameters {
if param.Name == "headers" || param.Name == "queries" || param.Name == "url" {
lowercased := strings.ToLower(param.Value)
if strings.Contains(lowercased, "auth") || strings.Contains(lowercased, "bearer") || strings.Contains(lowercased, "basic") || strings.Contains(lowercased, "api") {
authFound = true
break
}
}
}
}

if !authFound {
log.Printf("[WARNING] Tried to execute SINGLE %s WITHOUT auth (missing)", app.Name)
if !authFound {
log.Printf("[WARNING] Tried to execute SINGLE %s WITHOUT auth (missing)", app.Name)

found := false
for _, param := range action.Parameters {
if param.Configuration {
found = true
break
found := false
for _, param := range action.Parameters {
if param.Configuration {
found = true
break
}
}
}

if !found {
return workflowExecution, errors.New("You must authenticate this API first")
if !found {
return workflowExecution, errors.New("You must authenticate this API first")
}
}
}
}
}
*/

// FIXME: We need to inject missing empty auth here
// This is NOT a good solution, but a good bypass
if app.Authentication.Required {
authFields := 0

foundFields := []string{}
for _, actionParam := range action.Parameters {
if actionParam.Configuration {
authFields += 1
foundFields = append(foundFields, actionParam.Name)
}
}

// Usually url
if authFields <= 2 {
//for _, param := range action.Parameters {
action.Parameters = append(action.Parameters, WorkflowAppActionParameter{
Name: "apikey",
Configuration: true,
})
if !ArrayContains(foundFields, "apikey") {
action.Parameters = append(action.Parameters, WorkflowAppActionParameter{
Name: "apikey",
Configuration: true,
})
}

action.Parameters = append(action.Parameters, WorkflowAppActionParameter{
Name: "access_token",
Configuration: true,
})
if !ArrayContains(foundFields, "access_token") {
action.Parameters = append(action.Parameters, WorkflowAppActionParameter{
Name: "access_token",
Configuration: true,
})
}

action.Parameters = append(action.Parameters, WorkflowAppActionParameter{
Name: "username_basic",
Configuration: true,
})
if !ArrayContains(foundFields, "username_basic") {
action.Parameters = append(action.Parameters, WorkflowAppActionParameter{
Name: "username_basic",
Configuration: true,
})
}

action.Parameters = append(action.Parameters, WorkflowAppActionParameter{
Name: "password_basic",
Configuration: true,
})
if !ArrayContains(foundFields, "password_basic") {
action.Parameters = append(action.Parameters, WorkflowAppActionParameter{
Name: "password_basic",
Configuration: true,
})
}
}
}


if runValidationAction {
log.Printf("[INFO] Running validation action for %s for org %s (%s)", app.Name, user.ActiveOrg.Name, user.ActiveOrg.Id)

Expand All @@ -17845,15 +17858,23 @@ func PrepareSingleAction(ctx context.Context, user User, fileId string, body []b
newParams := []WorkflowAppActionParameter{}

// Auth is handled in PrepareWorkflowExec, so this may not be needed

originalUrl := ""
for _, param := range action.Parameters {
newName := GetValidParameters([]string{param.Name})
if len(newName) > 0 {
param.Name = newName[0]
}

if strings.ToLower(param.Name) == "url" {
originalUrl = param.Value
}

newParams = append(newParams, param)
}

log.Printf("URL %#v", originalUrl)

action.Parameters = newParams

action.Sharing = app.Sharing
Expand Down Expand Up @@ -17910,6 +17931,16 @@ func PrepareSingleAction(ctx context.Context, user User, fileId string, body []b
log.Printf("[ERROR] Failed preparing single execution (%s): %s", workflowExecution.ExecutionId, err)
}

// Overwriting as auth may also do
if len(originalUrl) > 0 && len(workflowExecution.Workflow.Actions) > 0 {
for paramIndex, param := range workflowExecution.Workflow.Actions[0].Parameters {
if param.Name == "url" {
workflowExecution.Workflow.Actions[0].Parameters[paramIndex].Value = originalUrl
break
}
}
}

if user.ActiveOrg.Id != "" {
workflow.ExecutingOrg = user.ActiveOrg
workflowExecution.ExecutionOrg = user.ActiveOrg.Id
Expand Down Expand Up @@ -17977,7 +18008,7 @@ func HandleRetValidation(ctx context.Context, workflowExecution WorkflowExecutio
// Wait for validation to have ran
if newExecution.Workflow.Validation.ValidationRan {

// FIXME: Check the return here. If there is an issue with custom_action doesn't exist, we rebuild it in realtime
// FIXME: Check the return here. If there is an issue with custom_action doesn't exist, we rebuild it in realtime
if strings.Contains(returnBody.Result, "custom_action doesn't exist") {
log.Printf("[INFO] Custom action doesn't exist for action %s", newExecution.Results[relevantIndex].Action.ID)

Expand All @@ -17995,7 +18026,6 @@ func HandleRetValidation(ctx context.Context, workflowExecution WorkflowExecutio
}
}


go runAppRebuildFromSingleAction(newExecution.Results[relevantIndex].Action.AppID)

}
Expand Down Expand Up @@ -18035,15 +18065,14 @@ func runAppRebuildFromSingleAction(appId string) {
app, err := GetApp(ctx, appId, User{}, false)
if err != nil {
log.Printf("[WARNING] Error getting app (execute SINGLE app action): %s", appId)
return
return
}

if !app.Generated {
log.Printf("[INFO] App %s (%s) is not generated. Not rebuilding", app.Name, app.ID)
return
}


parsedApi, err := GetOpenApiDatastore(ctx, app.ID)
if err != nil {
log.Printf("[WARNING] Failed getting openapi data for app %s: %s", app.Name, err)
Expand All @@ -18059,7 +18088,6 @@ func runAppRebuildFromSingleAction(appId string) {

log.Printf("[INFO] Rebuilding app %s (%s) due to custom action not existing. Impersonating owner for the request to ensure ownership stays equal: %s (%s)", app.Name, app.ID, user.Username, user.Id)


parsedSwagger := map[string]interface{}{}
err = json.Unmarshal([]byte(parsedApi.Body), &parsedSwagger)
if err != nil {
Expand Down Expand Up @@ -18088,8 +18116,8 @@ func runAppRebuildFromSingleAction(appId string) {
requestDestination := fmt.Sprintf("%s/api/v1/verify_openapi", backendUrl)

request, err := http.NewRequest(
"POST",
requestDestination,
"POST",
requestDestination,
bytes.NewBuffer(newSwagger),
)

Expand Down Expand Up @@ -21914,9 +21942,9 @@ func PrepareWorkflowExecution(ctx context.Context, workflow Workflow, request *h
backendUrl := os.Getenv("BASE_URL")

/*
if len(os.Getenv("SHUFFLE_GCEPROJECT")) > 0 && len(os.Getenv("SHUFFLE_GCEPROJECT_LOCATION")) > 0 {
backendUrl = fmt.Sprintf("https://%s.%s.r.appspot.com", os.Getenv("SHUFFLE_GCEPROJECT"), os.Getenv("SHUFFLE_GCEPROJECT_LOCATION"))
}
if len(os.Getenv("SHUFFLE_GCEPROJECT")) > 0 && len(os.Getenv("SHUFFLE_GCEPROJECT_LOCATION")) > 0 {
backendUrl = fmt.Sprintf("https://%s.%s.r.appspot.com", os.Getenv("SHUFFLE_GCEPROJECT"), os.Getenv("SHUFFLE_GCEPROJECT_LOCATION"))
}
*/

if len(os.Getenv("SHUFFLE_CLOUDRUN_URL")) > 0 && strings.Contains(os.Getenv("SHUFFLE_CLOUDRUN_URL"), "http") {
Expand Down

0 comments on commit 3ab4161

Please sign in to comment.