We are aware of the issue with the badge emails resending to everyone, we apologise for the inconvenience - learn more here.

Forum Discussion

dsoprea's avatar
dsoprea
Helpful | Level 6
2 years ago

How to get account object for file uploader?

We have an app that's using team-scoped credentials. A particular file has a `modified_by` attribute that returns an account ID. We have a team-scoped resource (created by constructing a `DropboxTeam` object). That has a `as_user()` method which takes a member id, but this obviously doesn't work for it. We tried constructing a `Dropbox` object and then calling `users_get_account(account_id)`, but the API balks:

 

dropbox.exceptions.BadInputError: BadInputError('1c01f5e00950405c91606a19b6ec425f', 'Error in call to API function "users/get_account": This API function operates on a single Dropbox account, but the OAuth 2 access token you provided is for an entire Dropbox Business team.  Since your API app key has team member file access permissions, you can operate on a team member\'s Dropbox by providing the "Dropbox-API-Select-User" HTTP header or "select_user" URL parameter to specify the exact user <https://www.dropbox.com/developers/documentation/http/teams>.')

 

 

So, it seems like the only way of getting accounts is enumerating all members and filtering for an account ID. Is there nothing more specific/efficient?

  • Здравко's avatar
    Здравко
    Legendary | Level 20

    Haha..😀 Hi dsoprea,

    Yes, good equilibristics, but as can be seen in error message you're relying on methods (users_get_account(account_id) in particular) that require User authentication already and cannot work on Team authentication (what you're trying)! 😉

    Unfortunately, this is not mentioned in Dropbox Python SDK documentation in a proper way. 🤔 Let's hope will be improved.

    The better way is usage of users_get_current_account() method. Here you don't need to probe for proper account id (such id can be any on a file - including such that's outside the team and it's optional - exists only on shared objects).

    I believe you know what's next.

    • dsoprea's avatar
      dsoprea
      Helpful | Level 6
      How would getting my own account help me get the account of the uploader?

      Are you saying that you think that there's no way of looking up users/members by account ID within the context of this app (my original question)?
      • Здравко's avatar
        Здравко
        Legendary | Level 20

        Hm..🤔 To be honest, I have no idea what you ask me for...

        What you mean: account of the uploader 🧐

        Isn't it your own account or account of this "uploader"'s user (whoever is he)? If so, the method above does this... or what's wrong actually? 🤷 ... Can you clarify?

         


        dsoprea wrote:
        ...
        Are you saying that you think that there's no way of looking up users/members by account ID within the context of this app (my original question)?

        You can, of course... I have never said that! You asked just "Is there nothing more specific/efficient?" and... that's what I said.

  • Greg-DB's avatar
    Greg-DB
    Icon for Dropbox Staff rankDropbox Staff

    dsoprea It sounds like you're trying to identify which account uploaded a file. The 'modified_by' field you mentioned would be the right property for that. That would give you the account ID of the account that modified that file. (Note that it's the account ID of the account that last modified it though; it may be different than the account that previously/originally uploaded it.)

     

    In order to retrieve the account information for the account for that account ID, you would use the users_get_account method. Note though that that method calls a user endpoint, so you need to call it on behalf of a particular user. That's what the "This API function operates on a single Dropbox account" error is about, since your app is linked to the team itself.

     

    This error message is referring to specifying what account on the Business team to operate on behalf of. When using any "team scopes", the resulting access token is connected to an entire Dropbox Business team, not an individual account. So, when using a team-scoped access token to access user-specific endpoints, such as using the users_get_account method in the Python SDK, you will need to specify which member of the team you want to operate on behalf of.
     
    To do this, you'd need to specify  the 'Dropbox-API-Select-User' header. The value should be the team_member_id for whichever member you wish to act on behalf of. In the Python SDK, you should do that using the as_user method on DropboxTeam (not Dropbox) in the Python SDK. That returns a Dropbox object you can use to call user methods, such as the users_get_account method. The team_member_id you supply to as_user does not need to be for the same account as the account ID you supply to the users_get_account method.

    • dsoprea's avatar
      dsoprea
      Helpful | Level 6

      Thanks for responding, Greg-DB.

       

      Yes. I'm aware. Dropbox doesn't [seemingly] provide an "uploader" attribute, so the modified-by attribute is all I have. With our usage, we can assume that all files are uploaded once, so it's equivalent.

       

      There's a sizable amount of your response dedicate to selecting a member-ID, but all I have is an account ID. My hypothesis in the original post was that, in this case, perhaps the only way to get from an account ID to a member ID is by enumerating all members and filtering for account ID, though this is not ideal. It sounds like this is true?

       

      Can you clarify your statement "The team_member_id you supply to as_user does not need to be for the same account as the account ID you supply to the users_get_account method."? I'm trying to get the user (and then the email) associated with the modified-by account ID. Why would I reference a different user/account/member than the one who modified the file?

       

      Where would I get "individual account" credentials? Users themselves don't have API credentials, so maybe I'd need a second app that doesn't have team scopes from which to take credentials to do the non-team-scoped API requests from the same process as the existing requests, and switch between them as necessary?

      • Greg-DB's avatar
        Greg-DB
        Icon for Dropbox Staff rankDropbox Staff

        dsoprea There are a number of different ways to get team member IDs, such as:

        The team member ID you supply to the as_user method tells the Dropbox API which team member you want to operate as. This is necessary for performing calls to user-endpoints, such as for the users_get_account method in the Python SDK. This can be any member of the team. Then, operating as that member, you can look up the account information of a different member, such as for whichever member happens to modify the file.

         

        To avoid needing to use the as_user method, you can connect an app to a specific account instead of the entire team. In that case, the resulting access/refresh token would only have access to whatever information/functionality that particular account has access to. And since it's specific to that account already, you wouldn't need to use the as_user method. To do that, you would need to process the authorization without requesting any team scopes. One way to do that is to use an app registration without any team scopes enabled at all. That's not technically required though; an alternative way to do that is to just specify the desired subset of scopes (that is, only users scopes and no team scopes) at the time of authorization, which you can do by specifying the scopes in the 'scope' parameter on DropboxOAuth2Flow or DropboxOAuth2FlowNoRedirect, for example.