+40
-226
@@ -2422,7 +2422,7 @@ func checkAdminLogin(resp http.ResponseWriter, request *http.Request) {
|
||||
}
|
||||
|
||||
if count == 0 {
|
||||
log.Printf("No users - redirecting for management user")
|
||||
log.Printf("[WARNING] No users - redirecting for management user")
|
||||
resp.WriteHeader(200)
|
||||
resp.Write([]byte(fmt.Sprintf(`{"success": true, "reason": "stay"}`)))
|
||||
return
|
||||
@@ -2555,12 +2555,12 @@ func getApikey(ctx context.Context, apikey string) (User, error) {
|
||||
var users []User
|
||||
_, err := dbclient.GetAll(ctx, q, &users)
|
||||
if err != nil {
|
||||
log.Printf("Error getting users apikey (getapikey): %s", err)
|
||||
log.Printf("[ERROR] Error getting users apikey (getapikey): %s", err)
|
||||
return User{}, err
|
||||
}
|
||||
|
||||
if len(users) == 0 {
|
||||
log.Printf("No users found for apikey %s", apikey)
|
||||
log.Printf("[WARNING] No users found for apikey %s", apikey)
|
||||
return User{}, err
|
||||
}
|
||||
|
||||
@@ -2577,28 +2577,6 @@ func getSession(ctx context.Context, thissession string) (*session, error) {
|
||||
return curUser, nil
|
||||
}
|
||||
|
||||
// ListBooks returns a list of books, ordered by title.
|
||||
func getFile(ctx context.Context, id string) (*File, error) {
|
||||
key := datastore.NameKey("Files", id, nil)
|
||||
curFile := &File{}
|
||||
if err := dbclient.Get(ctx, key, curFile); err != nil {
|
||||
return &File{}, err
|
||||
}
|
||||
|
||||
return curFile, nil
|
||||
}
|
||||
|
||||
func setFile(ctx context.Context, file File) error {
|
||||
// clear session_token and API_token for user
|
||||
k := datastore.NameKey("Files", file.Id, nil)
|
||||
if _, err := dbclient.Put(ctx, k, &file); err != nil {
|
||||
log.Println(err)
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ListBooks returns a list of books, ordered by title.
|
||||
func getOrg(ctx context.Context, id string) (*Org, error) {
|
||||
key := datastore.NameKey("Organizations", id, nil)
|
||||
@@ -6552,7 +6530,7 @@ func handleAppHotload(location string, forceUpdate bool) error {
|
||||
}
|
||||
|
||||
//log.Printf("Reading app folder: %#v", dir)
|
||||
err = iterateAppGithubFolders(fs, dir, "", "", forceUpdate)
|
||||
_, _, err = iterateAppGithubFolders(fs, dir, "", "", forceUpdate)
|
||||
if err != nil {
|
||||
log.Printf("Err: %s", err)
|
||||
return err
|
||||
@@ -6835,7 +6813,7 @@ func remoteOrgJobHandler(org Org, interval int) error {
|
||||
|
||||
respBody, err := ioutil.ReadAll(newresp.Body)
|
||||
if err != nil {
|
||||
log.Printf("Failed body read in job sync: %s", err)
|
||||
log.Printf("[ERROR] Failed body read in job sync: %s", err)
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -6843,7 +6821,7 @@ func remoteOrgJobHandler(org Org, interval int) error {
|
||||
|
||||
err = remoteOrgJobController(org, respBody)
|
||||
if err != nil {
|
||||
log.Printf("Failed job controller run: %s", err)
|
||||
log.Printf("[ERROR] Failed job controller run for %s: %s", respBody, err)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
@@ -7141,37 +7119,39 @@ func runInit(ctx context.Context) {
|
||||
}
|
||||
}
|
||||
|
||||
fileq := datastore.NewQuery("Files").Limit(1)
|
||||
count, err := dbclient.Count(ctx, fileq)
|
||||
log.Printf("FILECOUNT: %d", count)
|
||||
if err == nil && count < 10 {
|
||||
basepath := "."
|
||||
filename := "testfile.txt"
|
||||
fileId := uuid.NewV4().String()
|
||||
log.Printf("Creating new file reference %s because none exist!", fileId)
|
||||
workflowId := "2cf1169d-b460-41de-8c36-28b2092866f8"
|
||||
downloadPath := fmt.Sprintf("%s/%s/%s/%s", basepath, activeOrgs[0].Id, workflowId, fileId)
|
||||
/*
|
||||
fileq := datastore.NewQuery("Files").Limit(1)
|
||||
count, err := dbclient.Count(ctx, fileq)
|
||||
log.Printf("FILECOUNT: %d", count)
|
||||
if err == nil && count < 10 {
|
||||
basepath := "."
|
||||
filename := "testfile.txt"
|
||||
fileId := uuid.NewV4().String()
|
||||
log.Printf("Creating new file reference %s because none exist!", fileId)
|
||||
workflowId := "2cf1169d-b460-41de-8c36-28b2092866f8"
|
||||
downloadPath := fmt.Sprintf("%s/%s/%s/%s", basepath, activeOrgs[0].Id, workflowId, fileId)
|
||||
|
||||
timeNow := time.Now().Unix()
|
||||
newFile := File{
|
||||
Id: fileId,
|
||||
CreatedAt: timeNow,
|
||||
UpdatedAt: timeNow,
|
||||
Description: "Created by system for testing",
|
||||
Status: "active",
|
||||
Filename: filename,
|
||||
OrgId: activeOrgs[0].Id,
|
||||
WorkflowId: workflowId,
|
||||
DownloadPath: downloadPath,
|
||||
}
|
||||
timeNow := time.Now().Unix()
|
||||
newFile := File{
|
||||
Id: fileId,
|
||||
CreatedAt: timeNow,
|
||||
UpdatedAt: timeNow,
|
||||
Description: "Created by system for testing",
|
||||
Status: "active",
|
||||
Filename: filename,
|
||||
OrgId: activeOrgs[0].Id,
|
||||
WorkflowId: workflowId,
|
||||
DownloadPath: downloadPath,
|
||||
}
|
||||
|
||||
err = setFile(ctx, newFile)
|
||||
if err != nil {
|
||||
log.Printf("Failed setting file: %s", err)
|
||||
} else {
|
||||
log.Printf("Created file %s in init", newFile.DownloadPath)
|
||||
err = setFile(ctx, newFile)
|
||||
if err != nil {
|
||||
log.Printf("Failed setting file: %s", err)
|
||||
} else {
|
||||
log.Printf("Created file %s in init", newFile.DownloadPath)
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
var allworkflowapps []AppAuthenticationStorage
|
||||
q = datastore.NewQuery("workflowappauth")
|
||||
@@ -7934,172 +7914,6 @@ func handleCloudSetup(resp http.ResponseWriter, request *http.Request) {
|
||||
resp.Write(respBody)
|
||||
}
|
||||
|
||||
type File struct {
|
||||
Id string `json:"id" datastore:"id"`
|
||||
Type string `json:"type" datastore:"type"`
|
||||
CreatedAt int64 `json:"created_at" datastore:"created_at"`
|
||||
UpdatedAt int64 `json:"updated_at" datastore:"updated_at"`
|
||||
Description string `json:"description" datastore:"description"`
|
||||
ExpiresAt string `json:"expires_at" datastore:"expires_at"`
|
||||
Status string `json:"status" datastore:"status"`
|
||||
Filename string `json:"filename" datastore:"filename"`
|
||||
URL string `json:"url" datastore:"org"`
|
||||
OrgId string `json:"org_id" datastore:"org_id"`
|
||||
WorkflowId string `json:"workflow_id" datastore:"workflow_id"`
|
||||
Workflows []string `json:"workflows" datastore:"workflows"`
|
||||
DownloadPath string `json:"download_path" datastore:"download_path"`
|
||||
}
|
||||
|
||||
func handleGetFileContent(resp http.ResponseWriter, request *http.Request) {
|
||||
cors := handleCors(resp, request)
|
||||
if cors {
|
||||
return
|
||||
}
|
||||
|
||||
var fileId string
|
||||
location := strings.Split(request.URL.String(), "/")
|
||||
if location[1] == "api" {
|
||||
if len(location) <= 4 {
|
||||
log.Printf("Path too short: %d", len(location))
|
||||
resp.WriteHeader(401)
|
||||
resp.Write([]byte(`{"success": false}`))
|
||||
return
|
||||
}
|
||||
|
||||
fileId = location[4]
|
||||
}
|
||||
|
||||
log.Printf("\n\nUser is trying to get file %s\n\n", fileId)
|
||||
|
||||
// 1. Check user directly
|
||||
// 2. Check workflow execution authorization
|
||||
setOrgId := false
|
||||
user, err := handleApiAuthentication(resp, request)
|
||||
if err != nil {
|
||||
// r.HandleFunc("/api/v1/files/{fileId}/content", handleGetFileContent).Methods("GET", "OPTIONS")
|
||||
log.Printf("INITIAL Api authentication failed in file download: %s", err)
|
||||
executionId, ok := request.URL.Query()["execution_id"]
|
||||
if ok && len(executionId) > 0 {
|
||||
ctx := context.Background()
|
||||
workflowExecution, err := getWorkflowExecution(ctx, executionId[0])
|
||||
if err != nil {
|
||||
log.Printf("Couldn't find execution ID %s", executionId[0])
|
||||
resp.WriteHeader(401)
|
||||
resp.Write([]byte(`{"success": false}`))
|
||||
return
|
||||
}
|
||||
|
||||
apikey := request.Header.Get("Authorization")
|
||||
if !strings.HasPrefix(apikey, "Bearer ") {
|
||||
log.Printf("Apikey doesn't start with bearer (2)")
|
||||
resp.WriteHeader(401)
|
||||
resp.Write([]byte(`{"success": false}`))
|
||||
return
|
||||
}
|
||||
|
||||
apikeyCheck := strings.Split(apikey, " ")
|
||||
if len(apikeyCheck) != 2 {
|
||||
log.Printf("Invalid format for apikey (2)")
|
||||
resp.WriteHeader(401)
|
||||
resp.Write([]byte(`{"success": false}`))
|
||||
return
|
||||
}
|
||||
|
||||
// This is annoying af and is done because of maxlength lol
|
||||
newApikey := apikeyCheck[1]
|
||||
if newApikey != workflowExecution.Authorization {
|
||||
log.Printf("Bad apikey for execution %s. %s vs %s", executionId[0], apikey, workflowExecution.Authorization)
|
||||
resp.WriteHeader(401)
|
||||
resp.Write([]byte(`{"success": false}`))
|
||||
return
|
||||
}
|
||||
|
||||
log.Printf("Authorization is correct for execution %s! %s vs %s", executionId, apikey, workflowExecution.Authorization)
|
||||
setOrgId = true
|
||||
} else {
|
||||
|
||||
resp.WriteHeader(401)
|
||||
resp.Write([]byte(`{"success": false}`))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// 1. Verify if the user has access to the file: org_id and workflow
|
||||
|
||||
log.Printf("Should get file %s", fileId)
|
||||
ctx := context.Background()
|
||||
file, err := getFile(ctx, fileId)
|
||||
if err != nil {
|
||||
log.Printf("File %s not found: %s", fileId, err)
|
||||
resp.WriteHeader(401)
|
||||
resp.Write([]byte(`{"success": false}`))
|
||||
return
|
||||
}
|
||||
|
||||
// This is a workaround for file grabs from an app
|
||||
if setOrgId == true {
|
||||
user.ActiveOrg.Id = file.OrgId
|
||||
}
|
||||
|
||||
found := false
|
||||
if file.OrgId == user.ActiveOrg.Id {
|
||||
found = true
|
||||
} else {
|
||||
for _, item := range user.Orgs {
|
||||
if item == file.OrgId {
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if !found {
|
||||
log.Printf("User %s doesn't have access to %s", user.Username, fileId)
|
||||
resp.WriteHeader(401)
|
||||
resp.Write([]byte(`{"success": false}`))
|
||||
return
|
||||
}
|
||||
|
||||
// Fixme: More auth: org and workflow!
|
||||
downloadPath := file.DownloadPath
|
||||
log.Printf("Downloadpath: %s", downloadPath)
|
||||
Openfile, err := os.Open(downloadPath)
|
||||
defer Openfile.Close() //Close after function return
|
||||
if err != nil {
|
||||
//File not found, send 404
|
||||
http.Error(resp, "File not found.", 404)
|
||||
return
|
||||
}
|
||||
|
||||
//File is found, create and send the correct headers
|
||||
//Get the Content-Type of the file
|
||||
//Create a buffer to store the header of the file in
|
||||
FileHeader := make([]byte, 512)
|
||||
//Copy the headers into the FileHeader buffer
|
||||
Openfile.Read(FileHeader)
|
||||
//Get content type of file
|
||||
FileContentType := http.DetectContentType(FileHeader)
|
||||
|
||||
//Get the file size
|
||||
FileStat, _ := Openfile.Stat() //Get info from file
|
||||
FileSize := strconv.FormatInt(FileStat.Size(), 10) //Get file size as a string
|
||||
|
||||
//Send the headers
|
||||
resp.Header().Set("Content-Disposition", "attachment; filename="+fileId)
|
||||
resp.Header().Set("Content-Type", FileContentType)
|
||||
resp.Header().Set("Content-Length", FileSize)
|
||||
|
||||
//Send the file
|
||||
//We read 512 bytes from the file already, so we reset the offset back to 0
|
||||
Openfile.Seek(0, 0)
|
||||
io.Copy(resp, Openfile) //'Copy' the file to the client
|
||||
return
|
||||
|
||||
//log.Printf("Should download file %s", downloadPath)
|
||||
//resp.WriteHeader(200)
|
||||
//resp.Write([]byte("OK"))
|
||||
}
|
||||
|
||||
func initHandlers() {
|
||||
var err error
|
||||
ctx := context.Background()
|
||||
@@ -8233,10 +8047,10 @@ func initHandlers() {
|
||||
// https://developer.box.com/reference/get-files-id-content/
|
||||
// 1. Creating the "get file" option. Make it possible to run this in the frontend.
|
||||
r.HandleFunc("/api/v1/files/{fileId}/content", handleGetFileContent).Methods("GET", "OPTIONS")
|
||||
//r.HandleFunc("/api/v1/files/create", handleGetFile).Methods("POST", "OPTIONS")
|
||||
//r.HandleFunc("/api/v1/files/upload", handleGetFile).Methods("POST", "OPTIONS")
|
||||
//r.HandleFunc("/api/v1/files/{fileId}", handleGetFile).Methods("GET", "OPTIONS")
|
||||
//r.HandleFunc("/api/v1/files/{fileId}", handleGetFile).Methods("DELETE", "OPTIONS")
|
||||
r.HandleFunc("/api/v1/files/create", handleCreateFile).Methods("POST", "OPTIONS")
|
||||
r.HandleFunc("/api/v1/files/{fileId}/upload", handleUploadFile).Methods("POST", "OPTIONS")
|
||||
r.HandleFunc("/api/v1/files/{fileId}", handleGetFileMeta).Methods("GET", "OPTIONS")
|
||||
r.HandleFunc("/api/v1/files/{fileId}", handleDeleteFile).Methods("DELETE", "OPTIONS")
|
||||
|
||||
http.Handle("/", r)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user