Files
shuffle-cracked/backend/go-app/shuffle-shared/streaming.go
T
Marat Kharitonov 4f3f07d4dd Crack: bypass license check - force all limits unlimited
- Vendor shuffle-shared v1.2.51 as backend/go-app/shuffle-shared
- Add replace directive in go.mod to use the local moduled copy
- In HandleCheckLicense, force org.Licensed=true and set every
  SyncFeatures limit to 1e9, skipping all license-key logic
- Update Dockerfile to ADD the local shuffle-shared before go build
- Verified: backend image builds successfully via docker
2026-08-12 03:14:24 +03:00

228 lines
6.7 KiB
Go

package shuffle
import (
"fmt"
"io/ioutil"
"log"
"net/http"
"strings"
"time"
)
func HandleStreamWorkflowUpdate(resp http.ResponseWriter, request *http.Request) {
cors := HandleCors(resp, request)
if cors {
return
}
//// Removed check here as it may be a public workflow
user, err := HandleApiAuthentication(resp, request)
if err != nil {
log.Printf("[AUDIT] Api authentication failed in getting specific workflow (stream update): %s. Continuing because it may be public.", err)
}
location := strings.Split(request.URL.String(), "/")
var fileId string
if location[1] == "api" {
if len(location) <= 4 {
resp.WriteHeader(401)
resp.Write([]byte(`{"success": false}`))
return
}
fileId = location[4]
}
if strings.Contains(fileId, "?") {
fileId = strings.Split(fileId, "?")[0]
}
if len(fileId) != 36 {
resp.WriteHeader(401)
resp.Write([]byte(`{"success": false, "reason": "Workflow ID when getting workflow is not valid"}`))
return
}
ctx := GetContext(request)
workflow, err := GetWorkflow(ctx, fileId)
if err != nil {
log.Printf("[WARNING] Workflow %s doesn't exist.", fileId)
resp.WriteHeader(401)
resp.Write([]byte(`{"success": false, "reason": "Failed finding workflow."}`))
return
}
if user.Id != workflow.Owner || len(user.Id) == 0 {
if workflow.OrgId == user.ActiveOrg.Id && user.Role != "org-reader" {
log.Printf("[AUDIT] User %s is accessing workflow %s as admin (SET workflow stream)", user.Username, workflow.ID)
//} else if workflow.Public {
//log.Printf("[AUDIT] Letting user %s access workflow %s for streaming because it's public (SET workflow stream)", user.Username, workflow.ID)
} else if project.Environment == "cloud" && user.Verified == true && user.SupportAccess == true && user.Role == "admin" {
log.Printf("[AUDIT] Letting verified support admin %s access workflow %s", user.Username, workflow.ID)
} else {
log.Printf("[AUDIT] Wrong user (%s) for workflow %s (SET workflow stream)", user.Username, workflow.ID)
resp.WriteHeader(401)
resp.Write([]byte(`{"success": false}`))
return
}
}
body, err := ioutil.ReadAll(request.Body)
if err != nil {
log.Printf("[WARNING] Error with body read in workflow stream: %s", err)
resp.WriteHeader(401)
resp.Write([]byte(`{"success": false}`))
return
}
/*
streamKey := fmt.Sprintf("%s_stream_users", workflow.ID)
cache, err = GetCache(ctx, streamKey, user.Id, 30)
if err != nil {
log.Printf("[WARNING] Failed setting cache for apikey: %s", err)
} else {
// We are here to get the users in the stream
cacheData := []byte(cache.([]uint8))
}
*/
// FIXME: Should append to the stream and keep some items in memory
// Not just purely overwrite it
sessionKey := fmt.Sprintf("%s_stream", workflow.ID)
err = SetCache(ctx, sessionKey, body, 30)
if err != nil {
log.Printf("[WARNING] Failed setting cache for apikey: %s", err)
}
resp.WriteHeader(200)
resp.Write([]byte(`{"success": true}`))
}
func HandleStreamWorkflow(resp http.ResponseWriter, request *http.Request) {
cors := HandleCors(resp, request)
if cors {
return
}
//// Removed check here as it may be a public workflow
user, err := HandleApiAuthentication(resp, request)
if err != nil {
log.Printf("[AUDIT] Api authentication failed in getting specific workflow (stream): %s. Continuing because it may be public.", err)
}
location := strings.Split(request.URL.String(), "/")
var fileId string
if location[1] == "api" {
if len(location) <= 4 {
resp.WriteHeader(401)
resp.Write([]byte(`{"success": false}`))
return
}
fileId = location[4]
}
if strings.Contains(fileId, "?") {
fileId = strings.Split(fileId, "?")[0]
}
if len(fileId) != 36 {
resp.WriteHeader(401)
resp.Write([]byte(`{"success": false, "reason": "Workflow ID when getting workflow is not valid"}`))
return
}
//ctx := GetContext(request)
ctx := GetContext(request)
workflow, err := GetWorkflow(ctx, fileId)
if err != nil {
log.Printf("[WARNING] Workflow %s doesn't exist.", fileId)
resp.WriteHeader(401)
resp.Write([]byte(`{"success": false, "reason": "Failed finding workflow."}`))
return
}
if user.Id != workflow.Owner || len(user.Id) == 0 {
if workflow.OrgId == user.ActiveOrg.Id && (user.Role == "admin" || user.Role == "org-reader") {
log.Printf("[AUDIT] User %s is accessing workflow %s as admin (stream edit workflow)", user.Username, workflow.ID)
} else if workflow.Public {
log.Printf("[AUDIT] Letting user %s access workflow %s for streaming because it's public (get workflow stream)", user.Username, workflow.ID)
} else if project.Environment == "cloud" && user.Verified == true && user.Active == true && user.SupportAccess == true && strings.HasSuffix(user.Username, "@shuffler.io") {
log.Printf("[AUDIT] Letting verified support admin %s access workflow %s", user.Username, workflow.ID)
} else {
log.Printf("[AUDIT] Wrong user (%s) for workflow %s (get workflow stream)", user.Username, workflow.ID)
resp.WriteHeader(401)
resp.Write([]byte(`{"success": false}`))
return
}
}
// FIXME: If public, it should ONLY allow you to set certain actions
resp.Header().Set("Connection", "Keep-Alive")
resp.Header().Set("X-Content-Type-Options", "nosniff")
conn, ok := resp.(http.Flusher)
if !ok {
log.Printf("[ERROR] Flusher error: %t", ok)
http.Error(resp, "Streaming supported on AppEngine", http.StatusInternalServerError)
return
}
resp.Header().Set("Content-Type", "text/event-stream")
resp.WriteHeader(http.StatusOK)
sessionKey := fmt.Sprintf("%s_stream", workflow.ID)
previousCache := []byte{}
for {
cache, err := GetCache(ctx, sessionKey)
if err == nil {
cacheData := []byte(cache.([]uint8))
if string(previousCache) == string(cacheData) {
//log.Printf("[DEBUG] Still same cache for %s", user.Id)
} else {
// A way to only check for data from other people
if (len(user.Id) > 0 && !strings.Contains(string(cacheData), user.Id)) || len(user.Id) == 0 {
//log.Printf("[DEBUG] NEW cache for %s (1) - sending: %s.", user.Id, cacheData)
//fw.Write(cacheData)
//w.Write(cacheData)
_, err := fmt.Fprintf(resp, "%s", string(cacheData))
if err != nil {
log.Printf("[ERROR] Failed in writing stream to user '%s' (%s): %s", user.Username, user.Id, err)
if strings.Contains(err.Error(), "broken pipe") {
break
}
} else {
previousCache = cacheData
conn.Flush()
}
} else {
//log.Printf("[ERROR] NEW cache for %s (2) - NOT sending: %s.", user.Id, cacheData)
previousCache = cacheData
}
}
} else {
//log.Printf("[DEBUG] Failed getting cache for %s: %s", user.Id, err)
}
// FIXME: This is a hack to make sure we don't fully utilize the thread
time.Sleep(100 * time.Millisecond)
}
}