package apitokens import ( "path" "strings" "github.com/ultisuite/ulti-backend/internal/nextcloud" ) func AllowsMailAccount(auth *AuthContext, accountID string) bool { if auth == nil || accountID == "" { return true } if auth.MailScope.AllAccounts { return true } for _, id := range auth.MailScope.AccountIDs { if id == accountID { return true } } return false } func AllowsDrivePath(auth *AuthContext, rawPath string) bool { if auth == nil { return true } if auth.DriveScope.AllFolders { return true } target := NormalizeDriveScopePath(rawPath) if target == "" { return true } // Scoped paths: org:{id}:/path or mount:{id}:/path if strings.HasPrefix(target, "org:") || strings.HasPrefix(target, "mount:") { for _, allowed := range auth.DriveScope.FolderPaths { if driveScopePrefixMatch(target, allowed) { return true } } return false } for _, allowed := range auth.DriveScope.FolderPaths { if drivePathWithinScope(target, allowed) { return true } } return false } func driveScopePrefixMatch(target, allowed string) bool { allowed = strings.TrimSpace(allowed) if allowed == "" || allowed == "/" { return true } return target == allowed || strings.HasPrefix(target, allowed+":") || strings.HasPrefix(target, allowed+"/") } func NormalizeDriveScopePath(rawPath string) string { rawPath = strings.TrimSpace(rawPath) if rawPath == "" { return "" } normalized := nextcloud.NormalizeClientPath(rawPath) if normalized == "" { return "/" } if !strings.HasPrefix(normalized, "/") { normalized = "/" + normalized } return path.Clean(normalized) } func drivePathWithinScope(target, allowed string) bool { target = NormalizeDriveScopePath(target) allowed = NormalizeDriveScopePath(allowed) if allowed == "/" { return true } if target == allowed { return true } return strings.HasPrefix(target, allowed+"/") } func AllowsAgendaCalendar(auth *AuthContext, calendarID string) bool { if auth == nil || calendarID == "" { return true } if auth.AgendaScope.AllCalendars { return true } for _, id := range auth.AgendaScope.CalendarIDs { if id == calendarID { return true } } return false }