Пример #1
0
    def getPasswords(self, path):
        path = h.cleanPath(path)
        passwordsFile = h.makePath(self.basePath, path, ".password")
        if not os.path.exists(passwordsFile): return set()
        passwordsCacheKey = h.makeKeyFromArguments(path)
        lh, lf = None, h.makePath(h.LOCKS_FOLDER,
                                  "_sfl_password_%s" % h.clean(path))
        try:
            self.passwordsLock.acquire()
            if passwordsCacheKey in self.passwordsCache:
                pc = self.passwordsCache[passwordsCacheKey]
                if h.getFileModified(passwordsFile) == pc["date"]:
                    return pc["passwords"]

            lh = h.getLockShared(lf, 5)
            passwords = set([
                p for p in h.readFromFile(
                    h.makePath(self.basePath, path, ".password")).split("\n")
                if p != ""
            ])
            self.passwordsCache[passwordsCacheKey] = {
                "passwords": passwords,
                "date": h.getFileModified(passwordsFile)
            }
            return passwords
        finally:
            self.passwordsLock.release()
            if lh is not None: h.releaseLock(lh)
 def getItems(self,
              path,
              r=None,
              asAdmin=False,
              overrideListingForbidden=False,
              overrideNoShow=False) -> (List[item], List[item]):
     path = h.cleanPath(path)
     if not self.doesItemExists(path): return [], []
     if not overrideListingForbidden and not asAdmin and self.ap.listingForbidden(
             path):
         return [], []
     fullPath = self.getFullPath(path)
     items = h.listDirectoryItems(fullPath)
     itemsContainers = []
     for item in items:
         if not os.path.isdir(item): continue
         itemPath = item.replace(self.basePath, "")
         if itemPath.lstrip("/").startswith("_sf"): continue
         isForbidden = self.ap.isForbidden(itemPath)
         if not asAdmin and isForbidden: continue
         showForbidden = self.ap.showForbidden(itemPath)
         if not overrideNoShow and not asAdmin and showForbidden: continue
         i = self.getItem(itemPath, r, asAdmin)
         if i is not None: itemsContainers.append(i)
     itemsLeafs = []
     for item in items:
         if not os.path.isfile(item): continue
         if self.isHiddenForListings(item): continue
         itemPath = item.replace(self.basePath, "")
         if itemPath.lstrip("/").startswith("_sf"): continue
         isForbidden = self.ap.isForbidden(itemPath)
         if not asAdmin and isForbidden: continue
         i = self.getItem(itemPath, r, asAdmin)
         if i is not None: itemsLeafs.append(i)
     return itemsContainers, itemsLeafs
Пример #3
0
 def setUserPassword(self, path, password, r, response=None):
     path = h.cleanPath(path)
     cookieKey = "_sf_pass_%s" % h.clean(path if path != "" else "-")
     r.cookies = dict(r.cookies)
     r.cookies[cookieKey] = password
     if response is not None:
         response.set_cookie(cookieKey, password, max_age=COOKIE_DURATION)
 def remove(self, path):
     path = h.cleanPath(path)
     if self.doesItemExists(path) and self.ap.isEditAllowed(
             self.getParent(path)):
         h.delete(self.getFullPath(path))
         return True
     else:
         return False
Пример #5
0
 def getLowerProtectedPath(self, path):
     path = h.cleanPath(path)
     relativePath = path
     lowerPath = False
     paths = relativePath.split("/")
     for i in range(len(paths)):
         currentPath = h.makePath(*paths[0:len(paths) - i])
         if currentPath == "": currentPath = "/"
         currentRealPath = os.path.abspath(
             h.makePath(self.basePath, currentPath))
         if os.path.isfile(h.makePath(currentRealPath, ".password")):
             lowerPath = currentRealPath
             break
         if os.path.isfile(h.makePath(currentRealPath, ".nopassword")):
             lowerPath = False
             break
     if lowerPath == False: return False
     return h.cleanPath(lowerPath.replace(self.basePath, ""))
Пример #6
0
    def _routeAdmin(self, path="/"):
        path = h.cleanPath(path)

        if request.form.get("password-submit", False):
            response = make_response()
            self.ap.setAdminPassword(request.form.get("password-admin", ""),
                                     request, response)
            return self._redirect("/admin", response)

        if not self.ap.isAdmin(request):
            return self._makeTemplate("password-admin")

        return self._routeItemsAdmin(path)
Пример #7
0
 def _routeList(self, path="/"):
     if request.headers.get("password") != ap.adminPassword:
         return {"result": 403}
     path = h.cleanPath(self._aliasPath(path))
     if not ip.doesItemExists(path):
         return {"result": 500, "error": "path %s does not exist" % path}
     containers, leafs = ip.getItems(path, request)
     containers, leafs = [c.__dict__
                          for c in containers], [l.__dict__ for l in leafs]
     return {
         "result": 200,
         "path": path,
         "containers": containers,
         "leafs": leafs
     }
 def addLeaf(self, path, file):
     path = h.cleanPath(path)
     try:
         if not self.doesItemExists(path):
             return False, "Container does not exists"
         filename = self.getPotentialLeafName(file)
         if self.isItemLeaf(h.makePath(path, filename)):
             return False, "Item already exists"
         if self.isItemContainer(h.makePath(path, filename)):
             return False, "Item already exists"
         filePath = h.makePath(self.basePath, path, filename)
         file.save(filePath)
         h.touchFile(filePath)
         return True, filename
     except:
         le, lt = h.getLastExceptionAndTrace()
         return False, le
Пример #9
0
 def addNewPassword(self, path, password):
     path = h.cleanPath(path)
     if password is None: return False
     if self.passwordEditForbidden(path): return False
     lh, lf = None, h.makePath(h.LOCKS_FOLDER,
                               "_sfl_password_%s" % h.clean(path))
     try:
         passwordFile = h.makePath(self.basePath, path, ".password")
         requiredPasswords = list(self.getPasswords(path))
         requiredPasswords.append(password)
         lh = h.getLockExclusive(lf, 5)
         h.writeToFile(passwordFile,
                       "\n".join(list(set(requiredPasswords))))
         return True
     except:
         print(h.getLastExceptionAndTrace())
         return False
     finally:
         if lh is not None: h.releaseLock(lh)
    def getItem(self, path, r=None, asAdmin=False) -> item:
        path = h.cleanPath(path)
        if not self.doesItemExists(path): return None
        fullPath = h.makePath(self.basePath, path)
        isLeaf = self.isItemLeaf(path)
        isContainer = not isLeaf
        if r is not None:
            protected, requiredPasswords, savedPassword, isAuthorized, lowerProtectedPath, protectedFromParent = self.ap.isAuthorized(
                path, r)
        else:
            isAuthorized, requiredPasswords, protected, savedPassword, lowerProtectedPath, protectedFromParent = True, "", False, "", "", False
        if asAdmin: isAuthorized = True
        if isLeaf:
            extension = os.path.splitext(path)[-1].replace(".", "")
            size = os.path.getsize(fullPath)
            nbItems = 0
            isTmpFolder = False
        else:
            extension = ""
            size = 0
            nbItems = len(h.listDirectoryItems(fullPath))
            isTmpFolder = path.lstrip("/") == self.tmpFolder
        isForbidden = self.ap.isForbidden(path)
        listingForbidden = self.ap.listingForbidden(path)
        shareForbidden = self.ap.shareForbidden(path)
        showForbidden = self.ap.showForbidden(path)
        editAllowed = self.ap.isEditAllowed(path)
        downloadForbidden = self.ap.downloadForbidden(path)
        passwordEditForbidden = self.ap.passwordEditForbidden(path)
        expires = h.getFileModified(h.makePath(self.basePath,
                                               path)) + self.tmpFolderDuration

        return item(path, os.path.basename(path),
                    os.stat(fullPath).st_mtime, isAuthorized, protected,
                    isForbidden, showForbidden, listingForbidden,
                    downloadForbidden, shareForbidden, passwordEditForbidden,
                    isTmpFolder, editAllowed, isLeaf, isContainer,
                    lowerProtectedPath, nbItems, requiredPasswords, expires,
                    size, extension, savedPassword, protectedFromParent)
 def getZipFile(self, path, r):
     path = h.cleanPath(path)
     addedSize = 0
     if not self.doesItemExists(path): return None
     fullPath = self.getFullPath(path)
     zipFilePath = h.makePath(h.TMP_FOLDER, h.uniqueID())
     try:
         zipf = zipfile.ZipFile(zipFilePath, "w", zipfile.ZIP_DEFLATED)
         for root, dirs, files in os.walk(fullPath):
             dirs[:] = [
                 d for d in dirs
                 if not self.ap.isForbidden(d.replace(self.basePath, ""))
             ]
             dirs[:] = [
                 d for d in dirs
                 if self.ap.isAuthorized(d.replace(self.basePath, ""), r)[3]
             ]
             dirs[:] = [
                 d for d in dirs if
                 not self.ap.downloadForbidden(d.replace(self.basePath, ""))
             ]
             for f in files:
                 fpath = h.makePath(root, f)
                 frpath = fpath.replace(self.basePath, "")
                 if self.ap.isForbidden(frpath): continue
                 addedSize += h.getFileSize(fpath)
                 if addedSize > self.maxZipSize: break
                 zipf.write(fpath, arcname=frpath)
             if addedSize > self.maxZipSize:
                 h.logDebug("Max zip file size reached", path,
                            self.maxZipSize)
                 break
         return zipFilePath
     except Exception as e:
         os.remove(zipFilePath)
         raise (e)
Пример #12
0
 def _doTrack(self, path, address, isProtected, isAuthotirzed,
              passwordProvided, shareID, shareTag):
     try:
         self.trackingsLock.acquire()
         path = h.cleanPath(path)
         if shareID is not None: path = "%s - sid: %s" % (path, shareID)
         if shareTag is not None: path = "%s - stag: %s" % (path, shareTag)
         if self.locationEnabled:
             location = self._getLocationFromIP(address)
         else:
             location = address
         self.trackings.append(
             tracking(
                 path,
                 passwordProvided if passwordProvided is not None else "",
                 isAuthotirzed, address, h.now(), isProtected, location))
         if len(self.trackings) > self.maxSize:
             nbLines = len(self.trackings)
             offset = int(nbLines - self.maxSize / 2)
             if offset > 0: self.trackings = self.trackings[offset:nbLines]
             h.logDebug("Trimed trackings", nbLines, len(self.trackings))
         self.trackingsSaved = False
     finally:
         self.trackingsLock.release()
Пример #13
0
 def listingForbidden(self, path):
     path = h.cleanPath(path)
     return h.isfile(h.makePath(self.basePath, path, ".nolist"))
 def isItemContainer(self, path):
     path = h.cleanPath(path)
     fullPath = self.getFullPath(path)
     if not os.path.exists(fullPath): return False
     return os.path.isdir(self.getFullPath(path))
 def getParent(self, path):
     path = h.cleanPath(path)
     return os.path.dirname(path)
 def _isFullPathWithinBaseFolder(self, fullPath):
     return h.cleanPath(self.basePath) in fullPath
 def isItemLeaf(self, path):
     path = h.cleanPath(path)
     fullPath = self.getFullPath(path)
     if not os.path.exists(fullPath): return False
     return os.path.isfile(fullPath)
Пример #18
0
 def downloadForbidden(self, path):
     path = h.cleanPath(path)
     if path == "": return True
     return h.isfile(h.makePath(self.basePath, path,
                                ".nodownload")) or self.showForbidden(
                                    path) or self.listingForbidden(path)
Пример #19
0
    def _routeShare(self, shareIDAndPath):
        shareID = shareIDAndPath.split("/")[0]
        query = str(request.query_string, "utf8")
        if not self.sp.shareExists(shareID):
            return self._makeTemplate("not-found", path=shareID)

        if request.form.get("password-submit", False):
            response = make_response()
            self.ap.setSharePassword(shareID,
                                     request.form.get("password-share", ""),
                                     request, response)
            return self._redirect(h.makeURL("/share=%s" % shareID, query),
                                  response)

        isAdmin = self.ap.isAdmin(request)
        subPath = h.cleanPath(
            os.path.normpath(shareIDAndPath.replace(shareID, ""))).lstrip(".")

        s, hint = self.sp.getShare(shareID, asAdmin=isAdmin, r=request)
        if s is None:
            raise Exception("Can't get Share %s, %s" % (shareID, hint))

        baseFilesIndexes = {
            s.files[i].split("/")[-1]: i
            for i in range(len(s.files))
        }
        subPathBits = subPath.split("/")
        if not isAdmin and len(s.files) == 1 and subPath == "":
            return self._redirect(
                h.makeURL(
                    "/share=%s/%s" % (shareID, s.files[0].split("/")[-1]),
                    query))
        elif subPath == "":
            baseFile, indexFile = None, -1
        else:
            baseFile = subPathBits.pop(0)
            indexFile = baseFilesIndexes.get(baseFile, -2)

        isAuthorized, savedPassword = self.ap.isShareAuthorized(s, request)
        if not isAdmin:
            self.sp.addView(
                s, h.makePath(*subPathBits), baseFile,
                request.remote_addr if request is not None else None, s.tag,
                isAuthorized)
        if indexFile == -2:
            return self._makeTemplate("not-found", path="%s" % shareID)
        if isAdmin and request.args.get("view") is None:
            return self._makeTemplate("share-admin", shareID=shareID, share=s)

        if indexFile == -1: path, displayPath, shareBasePath = "", shareID, ""
        else:
            shareBasePath = s.files[indexFile]
            path = h.cleanPath(h.makePath(shareBasePath, *subPathBits))
            if baseFile is not None:
                shareBasePath = shareBasePath.replace(baseFile, "")
            displayPath = shareID
            if baseFile is not None:
                displayPath = h.makePath(displayPath, baseFile)
            if subPath != "":
                displayPath = h.makePath(displayPath, *subPathBits)

        if h.TRACKING and not isAdmin:
            self.tp.track(path, request, ap.isShareProtected(s), isAuthorized,
                          savedPassword, shareID, s.tag)
        if not ip.doesItemExists(path):
            return self._makeTemplate("not-found", path=displayPath)
        if not isAdmin and not isAuthorized:
            return self._makeTemplate("share-password",
                                      displayPath=displayPath,
                                      share=s)

        if indexFile == -1:
            isLeaf, readme = False, None
            containers, leafs = [], []
            for file in s.files:
                item = ip.getItem(file)
                if item is None: continue
                item.path = item.path.split("/")[-1]
                if ip.isItemContainer(file): containers.append(item)
                else: leafs.append(item)
        else:
            isLeaf = ip.isItemLeaf(path)
            if not isLeaf:
                containers, leafs = self.ip.getItems(
                    path, overrideListingForbidden=True, overrideNoShow=True)
                readme = ip.getReadme(path)
            else:
                containers, leafs, readme = None, None, None
        if isLeaf: return send_from_directory(h.DATA_FOLDER, path)
        else:
            return self._makeTemplate("share",
                                      displayPath=displayPath,
                                      shareBasePath=shareBasePath,
                                      subPath=subPath,
                                      share=s,
                                      containers=containers,
                                      leafs=leafs,
                                      alerts=[],
                                      readme=readme,
                                      indexFile=indexFile,
                                      query=query)
Пример #20
0
 def shareForbidden(self, path):
     path = h.cleanPath(path)
     return h.isfile(h.makePath(self.basePath, path, ".noshare"))
Пример #21
0
 def setDownloadForbidden(self, path):
     path = h.cleanPath(path)
     h.writeToFile(h.makePath(self.basePath, path, ".nodownload"), "")
Пример #22
0
 def passwordEditForbidden(self, path):
     path = h.cleanPath(path)
     return h.isfile(h.makePath(self.basePath, path, ".nopasswordedit"))
 def getReadmeAdmin(self, path):
     path = h.cleanPath(path)
     readmeFile = h.makePath(self.getFullPath(path), "README.admin.md")
     if not os.path.exists(readmeFile): return self.getReadme(path)
     return markdown2.markdown(h.readFromFile(readmeFile))
 def getFullPath(self, path):
     path = h.cleanPath(path)
     fullPath = os.path.abspath(h.makePath(self.basePath, path))
     if not self._isFullPathWithinBaseFolder(fullPath): return self.basePath
     return fullPath
Пример #25
0
    def _routeItems(self, path="/"):
        path = h.cleanPath(self._aliasPath(path))

        if self.ap.isAdmin(request): return self._routeAdmin(path)

        if not ip.doesItemExists(path):
            return self._makeTemplate("not-found", path=path)

        item = self.ip.getItem(path, request)
        if item is None:
            return self._makeTemplate("error", path=path, e="Can't get item")

        if request.form.get("password-submit", False):
            response = make_response()
            self.ap.setUserPassword(item.lowerProtectedPath,
                                    request.form.get("password", ""), request,
                                    response)
            return self._redirect(path, response)

        if h.TRACKING:
            self.tp.track(path, request, item.protected, item.isAuthorized,
                          item.savedPassword)
        alerts = []
        if item.isAuthorized:
            if ip.isItemLeaf(path):
                if item.forbidden:
                    return self._makeTemplate("forbidden", path=path)
                return send_from_directory(h.DATA_FOLDER, path)
            else:
                if item.forbidden:
                    return self._makeTemplate("forbidden", path=path)
                if item.listingForbidden:
                    return self._makeTemplate("forbidden", path=path)
                if "download" in request.args and not item.downloadForbidden:
                    return self._downloadAndDeleteFile(
                        ip.getZipFile(path, request), "%s.zip" %
                        (os.path.basename(path) if path != "" else "root"))
                containers, leafs = ip.getItems(path, request)
                readme = ip.getReadme(path)
                return self._makeTemplate(
                    "items",
                    containers=containers,
                    leafs=leafs,
                    path=path,
                    readme=readme,
                    downloadAllowed=not self.ap.downloadForbidden(path),
                    currentURLWithoutURI=path,
                    alerts=alerts)
        else:
            if item.protected:
                if item.savedPassword is not None and item.savedPassword != "":
                    alerts.append([
                        "Can't authenticate",
                        "The password you provided (%s) is not valid." %
                        item.savedPassword
                    ])
                else:
                    alerts.append([
                        "Can't authenticate", "You did not provide a password."
                    ])
            return self._makeTemplate(
                "password",
                path=path,
                lowerProtectedPath=item.lowerProtectedPath,
                alerts=alerts)
Пример #26
0
 def setListingForbidden(self, path):
     path = h.cleanPath(path)
     h.writeToFile(h.makePath(self.basePath, path, ".nolist"), "")
Пример #27
0
 def passwordProtected(self, path):
     path = h.cleanPath(path)
     return h.isfile(h.makePath(self.basePath, path, ".password"))
 def doesItemExists(self, path):
     path = h.cleanPath(path)
     return os.path.exists(self.getFullPath(path))
Пример #29
0
 def _aliasPath(self, path):
     path = h.cleanPath(path)
     if self.aliases is None: return path
     return self.aliases.get(path, path)
Пример #30
0
 def setShareForbidden(self, path):
     path = h.cleanPath(path)
     h.writeToFile(h.makePath(self.basePath, path, ".noshare"), "")