Example #1
0
    def revokePermission(self, subscription, permission, permanent=DEFAULT_CONTEXT_PERMISSIONS_PERMANENCY):
        """
        Revoke a permission on a context's user subscription.

        Revokes will persist over context default permission changes based on permanent parameter.
        Non permanent permission revoke will remove grants!

        """
        criteria = {}
        new_permissions = []

        # Add current permissions except revoked one
        new_permissions = [p for p in subscription['permissions'] if permission != p]

        if permanent:
            # Add permission to vetos if not present
            subscription.setdefault('_vetos', [])
            if permission not in subscription['_vetos']:
                subscription['_vetos'].append(permission)

        # Remove permission from grants if present
        subscription.setdefault('_grants', [])
        subscription['_grants'] = [granted for granted in subscription['_grants'] if granted != permission]

        # Get a dummy context from subscription to determine the fields to update
        ContextClass = getMaxModelByObjectType(subscription['objectType'])
        context_unique_field = ContextClass.unique.lstrip('_')
        temp_context = ContextClass.from_object(
            self.request,
            {
                context_unique_field: subscription[context_unique_field],
                'objectType': subscription['objectType']
            }
        )

        context_storage_field = temp_context.user_subscription_storage
        subscription_unique_field = '{}.{}'.format(context_storage_field, context_unique_field)

        criteria.update({subscription_unique_field: subscription[context_unique_field]})   # update object that matches hash
        criteria.update({'_id': self['_id']})                 # of collection entry with _id

        # overwrite permissions

        what = {
            '$set': {
                '{}.$.permissions'.format(context_storage_field): new_permissions,
                '{}.$._grants'.format(context_storage_field): subscription.get('_grants', []),
                '{}.$._vetos'.format(context_storage_field): subscription.get('_vetos', [])
            }
        }

        subscription['permissions'] = new_permissions
        fields_to_squash = ['published', 'owner', 'creator', 'tags', 'vetos', 'grants']
        subscription = flatten(subscription, squash=fields_to_squash)

        self.mdb_collection.update(criteria, what)
        return subscription
Example #2
0
    def getSubscription(self, context):
        """
        """
        subscription_object_type = context.get('objectType', None)
        if subscription_object_type is None:
            return None

        ContextClass = getMaxModelByObjectType(subscription_object_type)
        temp_context = ContextClass.from_object(self.request, context)

        for subscription in self.get(temp_context.user_subscription_storage, []):
            if subscription.get(temp_context.unique.lstrip('_')) == str(temp_context[temp_context.unique]):
                return subscription
Example #3
0
    def process_file(self, request, activity_file):
        """
            Process file and save it into the database
        """
        base_path = request.registry.settings.get("file_repository")
        uploadURL = ""
        file_type = self["object"].get("objectType", "file").lower()
        # Look if the activity belongs to an specific context
        if self.get("contexts", False):
            # Look if we need to upload to an external URL
            context = self.get("contexts")[0]
            ContextClass = getMaxModelByObjectType(self.get("contexts")[0]["objectType"])
            identifier = (
                context[ContextClass.unique]
                if ContextClass.unique in context
                else context[ContextClass.unique.lstrip("_")]
            )
            context = ContextClass.from_database(self.request, identifier)
            uploadURL = context.get("uploadURL", "")

        if uploadURL:
            headers = {
                "X-Oauth-Scope": request.headers.get("X-Oauth-Scope"),
                "X-Oauth-Username": request.headers.get("X-Oauth-Username"),
                "X-Oauth-Token": request.headers.get("X-Oauth-Token"),
            }
            # Todo: Make sure that the mimetype is correctly or even informed
            # Use magic or imghdr libraries for that
            files = {"image": (activity_file.filename, activity_file.file, activity_file.type)}
            res = requests.post(uploadURL, headers=headers, files=files)
            if res.status_code == 201:
                response = json.loads(res.text)
                self["object"]["fullURL"] = response.get("uploadURL", "")
                if file_type == "image":
                    self["object"]["thumbURL"] = response.get("thumbURL", "")

        else:
            # We have a conversation or an activity with no related context
            # or a context with no community which we should save localy
            dirs = list(re.search("(\w{2})(\w{2})(\w{2})(\w{2})(\w{2})(\w{2})(\w{12})", str(self["_id"])).groups())
            filename = dirs.pop()
            path = base_path + "/" + "/".join(dirs)
            if not os.path.exists(path):
                os.makedirs(path)
            r_file = open(path + "/" + filename, "w")
            r_file.write(activity_file.file.read())
            r_file.close()

            full_endpoint_name = "image/full" if file_type == "image" else "file/download"
            self["object"]["fullURL"] = "/{}/{}/{}".format(self.resource_root, str(self["_id"]), full_endpoint_name)

            if file_type == "image":
                # Generate thumbnail
                activity_file.file.seek(0)
                image = Image.open(activity_file.file)
                thumb = rotate_image_by_EXIF(image)
                thumb.thumbnail((400, 400), Image.ANTIALIAS)
                thumb.save(path + "/" + filename + ".thumb", "JPEG")

                self["object"]["thumbURL"] = "/{}/{}/image/thumb".format(self.resource_root, str(self["_id"]))
        self["object"]["mimetype"] = activity_file.headers.getheader("content-type", "")

        # If there's a user-provided filename, preserve it
        if "filename" not in self["object"]:
            # Try to get filename from content disposition
            filename = re.search(
                r'filename="(.*?)"', activity_file.headers.getheader("content-disposition", "")
            ).groups()
            # Ignore empty filenames and "file" filenames (the latter coming from maxclient)
            if filename and filename != "file":
                self["object"]["filename"] = filename[0]