Add user file editor endpoint and enhance WOPI handlers with logging
This commit is contained in:
@@ -196,6 +196,10 @@ func NewRouter(cfg *config.Config, db *database.DB, jwtManager *jwt.Manager, aut
|
||||
r.Post("/user/files/{fileId}/wopi-session", func(w http.ResponseWriter, req *http.Request) {
|
||||
wopiSessionHandler(w, req, db, jwtManager, "https://of.b0esche.cloud")
|
||||
})
|
||||
// User file editor
|
||||
r.Get("/user/files/{fileId}/edit", func(w http.ResponseWriter, req *http.Request) {
|
||||
userEditorHandler(w, req, db, auditLogger)
|
||||
})
|
||||
// Collabora form proxy for user files
|
||||
r.Get("/user/files/{fileId}/collabora-proxy", func(w http.ResponseWriter, req *http.Request) {
|
||||
collaboraProxyHandler(w, req, db, jwtManager, "https://of.b0esche.cloud")
|
||||
@@ -681,6 +685,43 @@ func editorHandler(w http.ResponseWriter, r *http.Request, db *database.DB, audi
|
||||
orgID := r.Context().Value(middleware.OrgKey).(uuid.UUID)
|
||||
fileId := chi.URLParam(r, "fileId")
|
||||
|
||||
// Log activity
|
||||
db.LogActivity(r.Context(), userID, orgID, &fileId, "edit_file", map[string]interface{}{})
|
||||
|
||||
// Generate WOPI access token (1 hour duration)
|
||||
token, _ := middleware.GetToken(r.Context())
|
||||
|
||||
// Build WOPISrc URL
|
||||
wopiSrc := fmt.Sprintf("https://go.b0esche.cloud/wopi/files/%s?access_token=%s", fileId, token)
|
||||
|
||||
// Build Collabora editor URL
|
||||
collaboraUrl := fmt.Sprintf("https://of.b0esche.cloud/lool/dist/mobile/cool.html?WOPISrc=%s", url.QueryEscape(wopiSrc))
|
||||
|
||||
// Check if user can edit (for now, all org members can edit)
|
||||
readOnly := false
|
||||
|
||||
session := struct {
|
||||
EditUrl string `json:"editUrl"`
|
||||
Token string `json:"token"`
|
||||
ReadOnly bool `json:"readOnly"`
|
||||
ExpiresAt string `json:"expiresAt"`
|
||||
}{
|
||||
EditUrl: collaboraUrl,
|
||||
Token: token, // JWT token for authenticating file access
|
||||
ReadOnly: readOnly,
|
||||
ExpiresAt: time.Now().Add(15 * time.Minute).UTC().Format(time.RFC3339),
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
json.NewEncoder(w).Encode(session)
|
||||
}
|
||||
|
||||
// userEditorHandler handles GET /user/files/{fileId}/edit
|
||||
func userEditorHandler(w http.ResponseWriter, r *http.Request, db *database.DB, auditLogger *audit.Logger) {
|
||||
userIDStr, _ := middleware.GetUserID(r.Context())
|
||||
userID, _ := uuid.Parse(userIDStr)
|
||||
fileId := chi.URLParam(r, "fileId")
|
||||
|
||||
// Get file metadata to determine path and type
|
||||
fileUUID, err := uuid.Parse(fileId)
|
||||
if err != nil {
|
||||
@@ -695,19 +736,27 @@ func editorHandler(w http.ResponseWriter, r *http.Request, db *database.DB, audi
|
||||
return
|
||||
}
|
||||
|
||||
// Verify user owns this file
|
||||
if file.UserID == nil || *file.UserID != userID {
|
||||
errors.WriteError(w, errors.CodePermissionDenied, "Access denied", http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
|
||||
// Log activity
|
||||
db.LogActivity(r.Context(), userID, orgID, &fileId, "edit_file", map[string]interface{}{})
|
||||
db.LogActivity(r.Context(), userID, uuid.Nil, &fileId, "edit_file", map[string]interface{}{})
|
||||
|
||||
// Build Collabora editor URL - Collabora needs the file download URL as the WOPISrc parameter
|
||||
editUrl := fmt.Sprintf("https://go.b0esche.cloud/orgs/%s/files/download?path=%s", orgID.String(), url.QueryEscape(file.Path))
|
||||
collaboraUrl := fmt.Sprintf("https://of.b0esche.cloud/lool/dist/mobile/cool.html?WOPISrc=%s", url.QueryEscape(editUrl))
|
||||
|
||||
// Check if user can edit (for now, all org members can edit)
|
||||
readOnly := false
|
||||
|
||||
// Get JWT token from context
|
||||
// Generate WOPI access token (1 hour duration)
|
||||
token, _ := middleware.GetToken(r.Context())
|
||||
|
||||
// Build WOPISrc URL
|
||||
wopiSrc := fmt.Sprintf("https://go.b0esche.cloud/wopi/files/%s?access_token=%s", fileId, token)
|
||||
|
||||
// Build Collabora editor URL
|
||||
collaboraUrl := fmt.Sprintf("https://of.b0esche.cloud/lool/dist/mobile/cool.html?WOPISrc=%s", url.QueryEscape(wopiSrc))
|
||||
|
||||
// Check if user can edit (for now, all users can edit their own files)
|
||||
readOnly := false
|
||||
|
||||
session := struct {
|
||||
EditUrl string `json:"editUrl"`
|
||||
Token string `json:"token"`
|
||||
|
||||
@@ -245,6 +245,8 @@ func wopiCheckFileInfoHandler(w http.ResponseWriter, r *http.Request, db *databa
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Printf("[WOPI-CheckFileInfo] START: file=%s user=%s size=%d path=%s\n", fileID, userID.String(), file.Size, file.Path)
|
||||
|
||||
// Verify user has access to this file
|
||||
canAccess := false
|
||||
var ownerID string
|
||||
@@ -313,6 +315,8 @@ func wopiGetFileHandler(w http.ResponseWriter, r *http.Request, db *database.DB,
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Printf("[WOPI-GetFile] START: file=%s\n", fileID)
|
||||
|
||||
// Get access token from query parameter
|
||||
accessToken := r.URL.Query().Get("access_token")
|
||||
if accessToken == "" {
|
||||
@@ -393,6 +397,8 @@ func wopiGetFileHandler(w http.ResponseWriter, r *http.Request, db *database.DB,
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
fmt.Printf("[WOPI-STORAGE] Download response status: %d\n", resp.StatusCode)
|
||||
|
||||
// Set response headers
|
||||
contentType := getMimeType(file.Name)
|
||||
w.Header().Set("Content-Type", contentType)
|
||||
|
||||
Reference in New Issue
Block a user