Skip to content

Add support for Permissions #41

Closed
Closed

Description

@benlower
No description provided.

Activity

  1. hugoboos commented on Dec 28, 2016

    @hugoboos
    Contributor

    Any plans on this? I'm willing to implement this.

  2. t8y8 commented on Dec 28, 2016

    @t8y8
    Contributor

    @hugoboos there's a partial implementation in the inprogress branch.

    If you want to implement it we'd be happy to review the PR! Before jumping in though, it would be good to list out some of the high-level APIs here, and maybe an example blob of code demonstrating how it would look to add/remove permissions.

    It'll give us a chance to discuss how we want this to feel in the API and resolve any architecture questions before you spend too much time on it :)

  3. hugoboos commented on Dec 29, 2016

    @hugoboos
    Contributor

    I've looked at the inprogress branch.

    Was thinking to add a populate_permissions method to the datasource, project and workbook endpoint classes.
    Then extending the update method on these endpoints that will make requests to add or delete permissions. Like it is done with the tags for workbooks.

    For the default permissions we can do the same. Add a populate method to the project endpoint. And extend the update method on the project endpoint.

    I can start with the populate methods and then the update methods.

  4. t8y8 commented on Dec 29, 2016

    @t8y8
    Contributor

    Thanks, that would be a good place to start.

    The interesting part of the API design will be how we represent permissions rules and capabilities as objects.

    I'm not sure what in inprogress is what we want or not -- what do you think?

  5. hugoboos commented on Dec 29, 2016

    @hugoboos
    Contributor

    The PermissionItem is a good start but I would rename the permissions property to capabilities. So that we use the same terminology as the REST API.
    Then create a PermissionCapabilityItem.

    We would have this structure then:

    ProjectItem, WorkbookItem or DatasourceItem
    └── PermissionItem[]
        └── PermissionCapabilityItem[]
    

    Maybe change grantee_id to two separate properties, user_id and group_id? What do you think?

  6. t8y8 commented on Jan 3, 2017

    @t8y8
    Contributor

    I think that all makes sense. I may have to see it to really get a feel.

    Here's an off-the-cuff example:

    # server = TSC.Server('server')
    
    wb = next((w for w in TSC.Pager(server.workbooks) if w.name == 'Secret'), None)
    all_users = next((g for g in TSC.Pager(server.groups) if g.name == 'All Users'), None)
    
    secret_rule = TSC.PermissionsItem()
    secret_rule.group_id = all_users.id
    secret_rule.capabilities = {
    TSC.Capabilities.Read: 'Allow',
    TSC.Capabilities.Download: 'Deny'
    }
    
    wb.add_permissions_rule(secret_rule)

    That's one idea of how the API could feel at a high level.

    Note that I'm using the 'rule' as the item that we create on the Project/Workbook/DataSource. That's what they're called in the UI and is a noted break from the low-level resources we expose via the REST API directly. I think this makes more sense in the long run -- others may disagree.

    Our preference for enums makes me a bit sad to have to do all the typing for capabilities.

    An alternative is to have the PermissionsItem have an attribute for each property (None) by default, and then you'd set the mode, so it would be:

    secret_rule = TSC.PermissionsItem()
    secret_rule.group_id = all_users.id
    secret_rule.capabilities.read = 'Allow'  # or True/False/None if we want to stick to builtin types
    secret_rule.capabilities.download = 'Deny'
    secret_rule.capabilities.party = 'Allow'  # Raises exception because it's not a valid attribute
    }

    I think that would have very simple serialization code as well, even if we use 'Allow', 'Deny', and None.

    After typing it out I sort of prefer the latter, but I think @LGraber @benlower and @RussTheAerialist should weigh in -- as well as hearing your thoughts on what might work better for your use case.

  7. hugoboos commented on Jan 3, 2017

    @hugoboos
    Contributor

    Adding to your snippet:

    secret_rule = TSC.PermissionsItem()
    secret_rule.add_capability(PermissionCapability.Read, PermissionCapability.Allow)
    secret_rule.add_capability(PermissionCapability.Write, PermissionCapability.Deny)
    secret_rule.remove_capability(PermissionCapability.Download)
    

    In add_capability you can do some checking for valid values etc.

    It think it is better to stick with the same naming as the REST API. Can cause confusion when using different names for the same thing. Can always be changed later when the REST API changes.

  8. hugoboos commented on Jan 3, 2017

    @hugoboos
    Contributor

    Thinking about the PermissionsItem, it can have either a user of a group, not both.

    So this should not be possible:

    secret_rule = TSC.PermissionsItem()
    secret_rule.user_id = "<user_id>"
    secret_rule.group_id = "<group_id>"
    

    Kind of strange that you can't set both of the attributes.
    But when you stick with attributes grantee_type and grantee_id, the meaning of grantee_id is affected by another attribute.

    What about classes like UserPermissionsItem and GroupPermissionsItem?

  9. VathsalaAchar commented on Mar 2, 2017

    @VathsalaAchar
    Contributor

    Hello, I am hoping that this is still an ongoing decision and I do have an implementation/POC that suits what I want to achieve, but it is not perfect, there are repetitions that I don't like but for the short term it gets the job done. If there is a already a consensus on what is required, could someone outline it so I can change what I have to conform to those requirements?

    Let me start off with what it is I wanted to achieve: we need to add Permissions to a Project that would carry down to the Workbooks and DataSources in that project, which means permissions to user or group at Project level, then default permissions for the Workbooks and DataSources in that Project.

    I started off looking at the PermissionRequest class and wanted to keep from changing that, so I used that as a base for altering PermissionItem and creating CapabilityItem. This is what I have so far

    class CapabilityItem:
        Group = 'group'
        User = 'user'
    
        AddComment = "AddComment"  # Add Comment
        ChangeHierarchy = "ChangeHierarchy"
        ChangePermissions = "ChangePermissions"  # Set Permissions
        Connect = "Connect"
        Delete = "Delete"
        ExportData = "ExportData"
        ExportImage = "ExportImage"
        ExportXml = "ExportXml"  # Download
        Filter = "Filter"
        ProjectLeader = "ProjectLeader"  # Project Leader
        Read = "Read"  # View
        ShareView = "ShareView"  # Share Customized
        ViewComments = "ViewComments"  # View Comments
        ViewUnderlyingData = "ViewUnderlyingData"  # View Underlying Data
        WebAuthoring = "WebAuthoring"  # Web Edit
        Write = "Write"  # Save
    
        def __init__(self, grantee_id):
            self.Allow = "Allow"
            self.Deny = "Deny"
            self._allowed = list()
            self._denied = list()
            self.grantee_id = grantee_id
    
        @property
        def allowed(self):
            return self._allowed
    
        @allowed.setter
        def allowed(self, value):
            self._allowed.extend(value)
    
        @property
        def denied(self):
            return self._denied
    
        @denied.setter
        def denied(self, value):
            self._denied.extend(value)
    

    I extended the PermissionItem from the inprogress branch to suit my needs.

    class PermissionItem(object):
        Group = 'group'
        User = 'user'
    
        def __init__(self):
            self._grantee_type = None
            self._grantee_id = None
            self.permissions = {}
            self._user_capabilities = set()
            self._group_capabilities = set()
    
        @property
        def user_capabilities(self):
            return self._user_capabilities
    
        @user_capabilities.setter
        def user_capabilities(self, capability):
            self._user_capabilities.add(capability)
    
        @property
        def group_capabilities(self):
            return self._group_capabilities
    
        @group_capabilities.setter
        def group_capabilities(self, capability):
            self._group_capabilities.add(capability)
    

    I have also added two methods to ProjectEndpoint

    • add_permissions to add permissions to the project
    • add_default_permissions to add default permissions to workbooks or datasources

    The usage:

    permissions = tsc.PermissionItem()
    permissions.grantee_id = group_id
    permissions.grantee_type = tsc.PermissionItem.Group
    
    # add project permissions
    wb_capability = tsc.CapabilityItem(group_id)
    cap_item = tsc.CapabilityItem
    wb_capability.allowed = [cap_item.Read]
    permissions.group_capabilities = wb_capability
    server.projects.add_permissions(project, permissions)
    
    # cleanup old permissions # can be done better
    permissions.group_capabilities.clear()
    
    # add workbook permissions
    wb_capability = tsc.CapabilityItem(group_id)
    cap_item = tsc.CapabilityItem
    wb_capability.allowed = [cap_item.Read, cap_item.ExportData, cap_item.AddComment,
                             cap_item.ExportImage, cap_item.Filter, cap_item.ShareView]
    permissions.group_capabilities = wb_capability
    server.projects.add_default_permissions(project, permissions, 'workbooks')
    

    Do you want me to create a PR so you can have a look at the changes in detail? Happy to take any suggestions :)

  10. t8y8 commented on Mar 2, 2017

    @t8y8
    Contributor

    @VathsalaAchar thanks for this!

    This is definitely an active discussion still -- I'll try and take a look this weekend and compare to @hugoboos and let's see if we can't nail down an API!

  11. VathsalaAchar commented on Apr 25, 2017

    @VathsalaAchar
    Contributor

    @t8y8 Are there any updates on this?

  12. LGraber commented on Apr 27, 2017

    @LGraber
    Contributor

    Hi @VathsalaAchar
    We had a couple of other projects that we were focusing on. For TSC we were pretty heads down on making sure we could deliver Refresh for extracts in the next release of our server (and thus in the library). We have some other infrastructure work going on right now but I expect we will be able to spend some focus time on reviewing the design shortly. Sorry for the delay. We will definitely get back to you, though, and work with you to get your changes in. We really appreciate you working with us. Thanks!

  13. DepthDeluxe commented on May 3, 2018

    @DepthDeluxe

    @LGraber, @VathsalaAchar has anything moved on this in the past year? Would be really useful to have this feature.

  14. DepthDeluxe commented on May 5, 2018

    @DepthDeluxe

    I have a working implementation here. Adding permissions, deleting permissions is supported for workbooks, projects, and datasources. I will follow up shortly with unit tests and a PR.

    https://github.com/DepthDeluxe/server-client-python

  15. t8y8 commented on May 7, 2018

    @t8y8
    Contributor

    @DepthDeluxe great timing, this is hackathon week @ Tableau and I might have some time to collaborate.

    Can you submit the CLA (if you haven't already) and submit a PR against development?

    I'm sure the code is great ;) , we just want to make sure the design fits in with our long term goals.

    I look forward to collaborating with you!

  16. DepthDeluxe commented on May 7, 2018

    @DepthDeluxe
  17. awithey-sedex commented on Nov 27, 2018

    @awithey-sedex

    Wow! 2 years and Tableau have still not done this!

  18. yyx100 commented on Oct 7, 2019

    @yyx100

    Need this really bad :) Permission is the most critical part of automation. Please up up the feature request?

  19. t8y8 commented on Oct 8, 2019

    @t8y8
    Contributor

    @yyx100 Permissions support was added with the most recent release, can you check out the master branch?

    This can help get you started by taking a look at some of the tests: https://github.com/tableau/server-client-python/blob/master/test/test_datasource.py#L185

  20. darth0s commented on Jan 10, 2020

    @darth0s

    Hi, I am trying to add permissions to project but unfortunately only Locking is described in documentation.. Are methods for Project permissions implemented already or I have to go through REST API?

  21. thechadd commented on Jan 10, 2020

    @thechadd

    Permission functionality does exist, but just not in the documentation yet. @t8y8's link demonstrates how it can be done. I published an example of extracting permissions from a data source in the Tableau Developer Forums, if that might help point you in the right direction, too.
    https://community.tableau.com/thread/324497

  22. andreahowes commented on Aug 10, 2021

    @andreahowes

    Does permission update for projects and data sources exist?

  23. jacalata commented on Nov 10, 2021

    @jacalata
    Contributor

    Didn't see this comment, sorry. It does exist - take a look at the sample file 'add_default_permissions.py'

  24. jambesh commented on Jan 8, 2023

    @jambesh

    I don't think @thechadd or @andreahowes understood the initial ask of the project permission . those thread reference and script reference are basically to get the default permission , get the existing permission of datasource , workbook etc. Let say i would like to programmatically update the "PROJECT PERMISSION" to Project Lead or view to a group or to specific user - where is that reference or documentation ? I see DepthDelux code is nice but i don't see similar implementation or API or documentation exist as of today officially. @jacalata : I don't think the Add_default_permissions.py have the option to set Project Permission . Example set to Project Lead or Project View

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions