├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.md │ ├── config.yml │ ├── feature_request.md │ └── question_help.md ├── dependabot.yml └── workflows │ └── dispatch_spec_update.yml ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── account.stone ├── async.stone ├── auth.stone ├── check_api_v2_service.stone ├── check_api_v2_types.stone ├── common.stone ├── contacts.stone ├── file_properties.stone ├── file_requests.stone ├── file_tagging.stone ├── files.stone ├── openid_openid.stone ├── openid_openid_types.stone ├── paper.stone ├── release_note_generator.py ├── secondary_emails.stone ├── seen_state.stone ├── shared_content_links.stone ├── shared_links.stone ├── sharing.stone ├── sharing_files.stone ├── sharing_folders.stone ├── stone_cfg.stone ├── team.stone ├── team_common.stone ├── team_devices.stone ├── team_folders.stone ├── team_groups.stone ├── team_legal_holds.stone ├── team_linked_apps.stone ├── team_log.stone ├── team_log_generated.stone ├── team_member_space_limits.stone ├── team_members.stone ├── team_namespaces.stone ├── team_policies.stone ├── team_reports.stone ├── team_secondary_mails.stone ├── team_sharing_allowlist.stone ├── users.stone └── users_common.stone /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: "\U0001F41B Bug report" 3 | about: Create a report to help us improve the SDK 4 | title: '' 5 | labels: bug 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of the bug. 12 | 13 | **To Reproduce** 14 | The steps to reproduce the behavior 15 | 16 | **Expected Behavior** 17 | A clear description of what you expected to happen. 18 | 19 | **Actual Behavior** 20 | A clear description of what actually happened 21 | 22 | **Screenshots** 23 | If applicable, add screenshots to help explain your problem. 24 | 25 | **Additional context** 26 | Add any other context about the problem here. -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: false -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: "\U0001F680 Feature Request" 3 | about: Suggest an idea for this SDK 4 | title: '' 5 | labels: enhancement 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Why is this feature valuable to you? Does it solve a problem you're having?** 11 | A clear and concise description of why this feature is valuable. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. (if applicable) 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/question_help.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: "\U0001F4AC Questions / Help" 3 | about: Get help with issues you are experiencing 4 | title: '' 5 | labels: help-wanted, question 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Before you start** 11 | Have you checked StackOverflow, previous issues, and Dropbox Developer Forums for help? 12 | 13 | **What is your question?** 14 | A clear and concise description the question. 15 | 16 | **Screenshots** 17 | If applicable, add screenshots to help explain your question. 18 | 19 | **Additional context** 20 | Add any other context about the question here. -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | # To get started with Dependabot version updates, you'll need to specify which 2 | # package ecosystems to update and where the package manifests are located. 3 | # Please see the documentation for all configuration options: 4 | # https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates 5 | 6 | version: 2 7 | updates: 8 | - package-ecosystem: "github-actions" 9 | directory: "/" 10 | schedule: 11 | interval: "weekly" -------------------------------------------------------------------------------- /.github/workflows/dispatch_spec_update.yml: -------------------------------------------------------------------------------- 1 | name: Dispatch Spec Update 2 | on: 3 | workflow_dispatch: 4 | push: 5 | branches: 6 | - main 7 | 8 | jobs: 9 | Dispatch: 10 | runs-on: ubuntu-latest 11 | strategy: 12 | matrix: 13 | repository: ['dropbox/dropbox-sdk-python', 'dropbox/dropbox-sdk-js', 'dropbox/dropbox-sdk-dotnet', 'dropbox/dropbox-api-v2-explorer'] 14 | steps: 15 | - name: Dispatch Update 16 | uses: peter-evans/repository-dispatch@v1 17 | with: 18 | token: ${{ secrets.SPEC_UPDATE_TOKEN }} 19 | repository: ${{ matrix.repository }} 20 | event-type: spec_update 21 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Dropbox Code Of Conduct 2 | 3 | *Dropbox believes that an inclusive development environment fosters greater technical achievement. To encourage a diverse group of contributors we've adopted this code of conduct.* 4 | 5 | Please read the Official Dropbox [Code of Conduct](https://opensource.dropbox.com/coc/) before contributing. -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to the Dropbox API Spec 2 | We value and rely on the feedback from our community. This comes in the form of bug reports, feature requests, and general guidance. We welcome your issues and try our hardest to be timely in both response and resolution. Please read through this document before submitting issues to ensure we have the necessary information to help you resolve your issue. 3 | 4 | Unfortunately, because this repo is entirely autogenerated, we are not accepting pull requests. We hope that if you find an issue, we will be able to resolve it quickly. 5 | 6 | ## Filing Bug Reports 7 | You can file a bug report on the [GitHub Issues][issues] page. 8 | 9 | 1. Search through existing issues to ensure that your issue has not been reported. If it is a common issue, there is likely already an issue. 10 | 11 | 2. Please ensure you are using the latest version of the spec. While this may be a valid issue, we only will fix bugs affecting the latest version and your bug may have been fixed in a newer version. 12 | 13 | 3. Provide as much information as you can regarding the language, version, SDK version, and any other relevant information about your environment so we can help resolve the issue as quickly as possible. 14 | 15 | [issues]: https://github.com/dropbox/dropbox-api-spec/issues -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2020 Dropbox Inc., http://www.dropbox.com/ 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining 4 | a copy of this software and associated documentation files (the 5 | "Software"), to deal in the Software without restriction, including 6 | without limitation the rights to use, copy, modify, merge, publish, 7 | distribute, sublicense, and/or sell copies of the Software, and to 8 | permit persons to whom the Software is furnished to do so, subject to 9 | the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be 12 | included in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Logo][logo]][repo] 2 | 3 | The offical Dropbox API Spec. 4 | 5 | ## SDKs 6 | 7 | We have a variety of SDKs available for you to use that are based off this spec. 8 | 9 | - [Dropbox Python SDK](https://github.com/dropbox/dropbox-sdk-python) 10 | - [Dropbox Javascript SDK](https://github.com/dropbox/dropbox-sdk-js) 11 | - [Dropbox DotNet SDK](https://github.com/dropbox/dropbox-sdk-dotnet) 12 | - [Dropbox Java SDK](https://github.com/dropbox/dropbox-sdk-java) 13 | - [Dropbox Swift SDK](https://github.com/dropbox/swiftydropbox) 14 | - [Dropbox Objective-C SDK](https://github.com/dropbox/dropbox-sdk-obj-c) 15 | 16 | - [Dropbox API V2 Explorer](https://github.com/dropbox/dropbox-api-v2-explorer) 17 | 18 | ## Getting Help 19 | 20 | If you find a bug, please see [CONTRIBUTING.md][contributing] for information on how to report it. 21 | 22 | If you need help that is not specific to the API Spec, please reach out to [Dropbox Support][support]. 23 | 24 | ## License 25 | 26 | The API Spec is distributed under the MIT license, please see [LICENSE][license] for more information. 27 | 28 | [logo]: https://cfl.dropboxstatic.com/static/images/sdk/api_spec_banner.png 29 | [repo]: https://github.com/dropbox/dropbox-api-spec 30 | [license]: https://github.com/dropbox/dropbox-api-spec/blobs/main/LICENSE 31 | [contributing]: https://github.com/dropbox/dropbox-api-spec/blobs/main/CONTRIBUTING.md 32 | [support]: https://www.dropbox.com/developers/contact 33 | -------------------------------------------------------------------------------- /account.stone: -------------------------------------------------------------------------------- 1 | namespace account 2 | 3 | import common 4 | 5 | # 6 | # Route set_profile_photo 7 | # 8 | 9 | union PhotoSourceArg 10 | base64_data String 11 | "Image data in base64-encoded bytes." 12 | 13 | example default 14 | base64_data = "SW1hZ2UgZGF0YSBpbiBiYXNlNjQtZW5jb2RlZCBieXRlcy4gTm90IGEgdmFsaWQgZXhhbXBsZS4=" 15 | 16 | 17 | struct SetProfilePhotoArg 18 | photo PhotoSourceArg 19 | "Image to set as the user's new profile photo." 20 | 21 | example default 22 | photo = default 23 | 24 | 25 | struct SetProfilePhotoResult 26 | profile_photo_url String 27 | "URL for the photo representing the user, if one is set." 28 | 29 | example default 30 | profile_photo_url = "https://dl-web.dropbox.com/account_photo/get/dbaphid%3AAAHWGmIXV3sUuOmBfTz0wPsiqHUpBWvv3ZA?vers=1556069330102&size=128x128" 31 | 32 | 33 | union SetProfilePhotoError 34 | file_type_error 35 | "File cannot be set as profile photo." 36 | file_size_error 37 | "File cannot exceed 10 MB." 38 | dimension_error 39 | "Image must be larger than 128 x 128." 40 | thumbnail_error 41 | "Image could not be thumbnailed." 42 | transient_error 43 | "Temporary infrastructure failure, please retry." 44 | 45 | route set_profile_photo(SetProfilePhotoArg, SetProfilePhotoResult, SetProfilePhotoError) 46 | "Sets a user's profile photo." 47 | 48 | attrs 49 | scope = "account_info.write" 50 | -------------------------------------------------------------------------------- /async.stone: -------------------------------------------------------------------------------- 1 | namespace async 2 | 3 | # 4 | # Types for writing asynchronous API methods. 5 | # 6 | # There are two calls for each asynchronous method: 7 | # 1. A "Launch" method that (optionally) launches the asynchronous job 8 | # 2. A "Polling" method that polls for the status of the job that was launched by the first call. 9 | # 10 | # The following definitions are prefixed by "Launch" or "Poll", according to their intended use. 11 | 12 | 13 | alias AsyncJobId = String(min_length=1) 14 | 15 | 16 | # 17 | # Launch 18 | # 19 | 20 | union_closed LaunchResultBase 21 | "Result returned by methods that launch an asynchronous job. 22 | 23 | A method who may either launch an asynchronous job, or complete the request 24 | synchronously, can use this union by extending it, and adding a 'complete' field 25 | with the type of the synchronous response. 26 | 27 | See :type:`LaunchEmptyResult` for an example." 28 | 29 | async_job_id AsyncJobId 30 | "This response indicates that the processing is asynchronous. 31 | The string is an id that can be used to obtain the status of the asynchronous job." 32 | 33 | example default 34 | async_job_id = "34g93hh34h04y384084" 35 | 36 | union_closed LaunchEmptyResult extends LaunchResultBase 37 | "Result returned by methods that may either launch an asynchronous job or complete synchronously. 38 | Upon synchronous completion of the job, no additional information is returned." 39 | 40 | complete 41 | "The job finished synchronously and successfully." 42 | 43 | example complete 44 | complete = null 45 | 46 | example async_job_id 47 | async_job_id = "34g93hh34h04y384084" 48 | 49 | # 50 | # Poll 51 | # 52 | 53 | struct PollArg 54 | "Arguments for methods that poll the status of an asynchronous job." 55 | 56 | async_job_id AsyncJobId 57 | "Id of the asynchronous job. 58 | This is the value of a response returned from the method that launched the job." 59 | 60 | example default 61 | async_job_id = "34g93hh34h04y384084" 62 | 63 | # TODO(kelkabany): Remove `error_msg` since others might want to return it 64 | # differently. 65 | union_closed PollResultBase 66 | "Result returned by methods that poll for the status of an asynchronous job. 67 | Unions that extend this union should add a 'complete' field with a type of 68 | the information returned upon job completion. 69 | 70 | See :type:`PollEmptyResult` for an example." 71 | 72 | in_progress 73 | "The asynchronous job is still in progress." 74 | 75 | 76 | union_closed PollEmptyResult extends PollResultBase 77 | "Result returned by methods that poll for the status of an asynchronous job. 78 | Upon completion of the job, no additional information is returned." 79 | 80 | complete 81 | "The asynchronous job has completed successfully." 82 | 83 | example complete 84 | complete = null 85 | 86 | example in_progress 87 | in_progress = null 88 | 89 | 90 | union PollError 91 | "Error returned by methods for polling the status of asynchronous job." 92 | 93 | invalid_async_job_id 94 | "The job ID is invalid." 95 | internal_error 96 | "Something went wrong with the job on Dropbox's end. You'll need to 97 | verify that the action you were taking succeeded, and if not, try 98 | again. This should happen very rarely." 99 | -------------------------------------------------------------------------------- /auth.stone: -------------------------------------------------------------------------------- 1 | namespace auth 2 | 3 | import common 4 | 5 | struct TokenScopeError 6 | required_scope String 7 | "The required scope to access the route." 8 | 9 | union AuthError 10 | "Errors occurred during authentication." 11 | 12 | invalid_access_token 13 | "The access token is invalid." 14 | invalid_select_user 15 | "The user specified in 'Dropbox-API-Select-User' is no longer on the team." 16 | invalid_select_admin 17 | "The user specified in 'Dropbox-API-Select-Admin' is not a Dropbox Business team admin." 18 | user_suspended 19 | "The user has been suspended." 20 | expired_access_token 21 | "The access token has expired." 22 | missing_scope TokenScopeError 23 | "The access token does not have the required scope to access the route." 24 | route_access_denied 25 | "The route is not available to public." 26 | 27 | route token/revoke(Void, Void, Void) 28 | "Disables the access token used to authenticate the call. 29 | If there is a corresponding refresh token for the access token, 30 | this disables that refresh token, as well as any other access tokens for that refresh token." 31 | 32 | attrs 33 | allow_app_folder_app = true 34 | 35 | union RateLimitReason 36 | too_many_requests 37 | "You are making too many requests in the past few minutes." 38 | too_many_write_operations 39 | "There are currently too many write operations happening in the user's Dropbox." 40 | 41 | struct RateLimitError 42 | "Error occurred because the app is being rate limited." 43 | 44 | reason RateLimitReason 45 | "The reason why the app is being rate limited." 46 | 47 | retry_after UInt64 = 1 48 | "The number of seconds that the app should wait 49 | before making another request." 50 | 51 | # 52 | # OAuth 1.0 token conversion 53 | # 54 | 55 | struct TokenFromOAuth1Arg 56 | 57 | oauth1_token String(min_length=1) 58 | "The supplied OAuth 1.0 access token." 59 | 60 | oauth1_token_secret String(min_length=1) 61 | "The token secret associated with the supplied access token." 62 | 63 | example default 64 | oauth1_token = "qievr8hamyg6ndck" 65 | oauth1_token_secret = "qomoftv0472git7" 66 | 67 | struct TokenFromOAuth1Result 68 | 69 | oauth2_token String(min_length=1) 70 | "The OAuth 2.0 token generated from the supplied OAuth 1.0 token." 71 | 72 | example default 73 | oauth2_token = "9mCrkS7BIdAAAAAAAAAAHHS0TsSnpYvKQVtKdBnN5IuzhYOGblSgTcHgBFKFMmFn" 74 | 75 | union TokenFromOAuth1Error 76 | invalid_oauth1_token_info 77 | "Part or all of the OAuth 1.0 access token info is invalid." 78 | app_id_mismatch 79 | "The authorized app does not match the app associated with the supplied access token." 80 | 81 | route token/from_oauth1(TokenFromOAuth1Arg, TokenFromOAuth1Result, TokenFromOAuth1Error) deprecated 82 | "Creates an OAuth 2.0 access token from the supplied OAuth 1.0 access token." 83 | attrs 84 | auth = "app" 85 | allow_app_folder_app = true 86 | 87 | union AccessError 88 | "Error occurred because the account doesn't have permission to access the resource." 89 | 90 | invalid_account_type InvalidAccountTypeError 91 | "Current account type cannot access the resource." 92 | 93 | paper_access_denied PaperAccessError 94 | "Current account cannot access Paper." 95 | 96 | union PaperAccessError 97 | paper_disabled 98 | "Paper is disabled." 99 | not_paper_user 100 | "The provided user has not used Paper yet." 101 | 102 | union InvalidAccountTypeError 103 | endpoint 104 | "Current account type doesn't have permission to access this route endpoint." 105 | feature 106 | "Current account type doesn't have permission to access this feature." 107 | -------------------------------------------------------------------------------- /check_api_v2_service.stone: -------------------------------------------------------------------------------- 1 | # @generated by protoc-gen-stone. DO NOT EDIT. 2 | # source: configs/proto/dropbox/proto/check/api_v2_service.proto 3 | namespace check 4 | 5 | route user (EchoArg, EchoResult, Void) 6 | "This endpoint performs User Authentication, validating the supplied access token, 7 | and returns the supplied string, to allow you to test your code and connection to the 8 | Dropbox API. It has no other effect. If you receive an HTTP 200 response with the supplied 9 | query, it indicates at least part of the Dropbox API infrastructure is working and that the 10 | access token is valid." 11 | 12 | attrs 13 | allow_app_folder_app = true 14 | auth = "user" 15 | is_preview = true 16 | scope = "account_info.read" 17 | 18 | route app (EchoArg, EchoResult, Void) 19 | "This endpoint performs App Authentication, validating the supplied app key and secret, 20 | and returns the supplied string, to allow you to test your code and connection to the 21 | Dropbox API. It has no other effect. If you receive an HTTP 200 response with the supplied 22 | query, it indicates at least part of the Dropbox API infrastructure is working and that the 23 | app key and secret valid." 24 | 25 | attrs 26 | allow_app_folder_app = true 27 | auth = "app" 28 | is_preview = true 29 | 30 | -------------------------------------------------------------------------------- /check_api_v2_types.stone: -------------------------------------------------------------------------------- 1 | # @generated by protoc-gen-stone. DO NOT EDIT. 2 | # source: configs/proto/dropbox/proto/check/api_v2_types.proto 3 | namespace check 4 | 5 | import common 6 | 7 | struct EchoArg 8 | "Contains the arguments to be sent to the Dropbox servers." 9 | query String(max_length=500) = "" 10 | "The string that you'd like to be echoed back to you." 11 | 12 | example default 13 | query = "foo" 14 | 15 | struct EchoResult 16 | "EchoResult contains the result returned from the Dropbox servers." 17 | result String = "" 18 | "If everything worked correctly, this would be the same as query." 19 | 20 | example default 21 | result = "foo" 22 | 23 | -------------------------------------------------------------------------------- /common.stone: -------------------------------------------------------------------------------- 1 | namespace common 2 | 3 | # Annotates fields to serialize a subset of total fields, depending on caller type 4 | 5 | # Annotates fields to redact information before storing in logs 6 | 7 | # Annotates fields for documentation changes 8 | 9 | alias DropboxTimestamp = Timestamp("%Y-%m-%dT%H:%M:%SZ") 10 | 11 | alias Date = Timestamp("%Y-%m-%d") 12 | 13 | # Note - "\\." is needed in order to translate to "\." 14 | 15 | # Note: If this pattern is changed, we also need to update _parse_json_arg_to_stone_data_type in dropbox/api/v2/substrate/wrapper.py 16 | alias EmailAddress = String(pattern="^['#&A-Za-z0-9._%+-]+@[A-Za-z0-9-][A-Za-z0-9.-]*\\.[A-Za-z]{2,15}$", max_length=255) 17 | 18 | # First name or Last name. NOTE: max_length should be synced with USER_NAME_MAX_LEN 19 | alias NamePart = String(pattern="[^\/:?*<>\"|]*", min_length=1, max_length=100) 20 | 21 | # First name or Last name. NOTE: max_length should be synced with USER_NAME_MAX_LEN 22 | # Accepting zeo length values which are usually used to clear the first or last name. 23 | alias OptionalNamePart = String(pattern="[^\/:?*<>\"|]*", max_length=100) 24 | 25 | # We don't limit the length because it's always generated from the first & last names. 26 | alias DisplayName = String(pattern="[^\/:?*<>\"|]*") 27 | 28 | # There are some existing accounts with special characters in their names. Though we don't allow such special characters 29 | # being used through UI, it's still possible to use them right now through some endpoints. This alias should be used in 30 | # the places where those legacy account names are expected, one of the example being the team audit logging. In other 31 | # places we should use `DisplayName` instead to prevent more usage of these special characters. 32 | alias DisplayNameLegacy = String 33 | 34 | alias NamespaceId = String(pattern="[-_0-9a-zA-Z:]+") 35 | 36 | alias SharedFolderId = NamespaceId 37 | 38 | alias SessionId = String 39 | 40 | struct RootInfo 41 | "Information about current user's root." 42 | 43 | union 44 | team TeamRootInfo 45 | user UserRootInfo 46 | 47 | root_namespace_id NamespaceId 48 | "The namespace ID for user's root namespace. It will be the namespace ID 49 | of the shared team root if the user is member of a team with a separate team root. 50 | Otherwise it will be same as :field:`RootInfo.home_namespace_id`." 51 | 52 | home_namespace_id NamespaceId 53 | "The namespace ID for user's home namespace." 54 | 55 | example default 56 | user = default 57 | 58 | struct TeamRootInfo extends RootInfo 59 | "Root info when user is member of a team with a separate root namespace ID." 60 | 61 | home_path String 62 | "The path for user's home directory under the shared team root." 63 | 64 | struct UserRootInfo extends RootInfo 65 | "Root info when user is not member of a team or 66 | the user is a member of a team and the team does not have a separate root namespace." 67 | 68 | example default 69 | home_namespace_id = "3235641" 70 | root_namespace_id = "3235641" 71 | 72 | union PathRoot 73 | home 74 | "Paths are relative to the authenticating user's home namespace, 75 | whether or not that user belongs to a team." 76 | 77 | root NamespaceId 78 | "Paths are relative to the authenticating user's root namespace 79 | (This results in :field:`PathRootError.invalid_root` if the 80 | user's root namespace has changed.)." 81 | 82 | namespace_id NamespaceId 83 | "Paths are relative to given namespace id (This results in 84 | :field:`PathRootError.no_permission` if you don't have access 85 | to this namespace.)." 86 | 87 | 88 | union PathRootError 89 | invalid_root RootInfo 90 | "The root namespace id in Dropbox-API-Path-Root header is not valid. The value 91 | of this error is the user's latest root info." 92 | no_permission 93 | "You don't have permission to access the namespace id in Dropbox-API-Path-Root 94 | header." 95 | 96 | alias LanguageCode = String(min_length=2) 97 | "A ISO639-1 code." 98 | -------------------------------------------------------------------------------- /contacts.stone: -------------------------------------------------------------------------------- 1 | namespace contacts 2 | 3 | import common 4 | 5 | route delete_manual_contacts(Void, Void, Void) 6 | "Removes all manually added contacts. 7 | You'll still keep contacts who are on your team or who you imported. 8 | New contacts will be added when you share." 9 | 10 | attrs 11 | scope = "contacts.write" 12 | 13 | struct DeleteManualContactsArg 14 | email_addresses List(common.EmailAddress) 15 | "List of manually added contacts to be deleted." 16 | 17 | example default 18 | email_addresses = ["contactemailaddress1@domain.com", "contactemailaddress2@domain.com"] 19 | 20 | union DeleteManualContactsError 21 | contacts_not_found List(common.EmailAddress) 22 | "Can't delete contacts from this list. 23 | Make sure the list only has manually added contacts. 24 | The deletion was cancelled." 25 | 26 | route delete_manual_contacts_batch(DeleteManualContactsArg, Void, DeleteManualContactsError) 27 | "Removes manually added contacts from the given list." 28 | 29 | attrs 30 | scope = "contacts.write" 31 | -------------------------------------------------------------------------------- /file_properties.stone: -------------------------------------------------------------------------------- 1 | namespace file_properties 2 | "This namespace contains helpers for property and template metadata endpoints. 3 | 4 | 5 | These endpoints enable you to tag arbitrary key/value data to Dropbox files. 6 | 7 | 8 | The most basic unit in this namespace is the :type:`PropertyField`. These fields encapsulate the 9 | actual key/value data. 10 | 11 | 12 | Fields are added to a Dropbox file using a :type:`PropertyGroup`. Property groups contain a 13 | reference to a Dropbox file and a :type:`PropertyGroupTemplate`. Property groups are uniquely 14 | identified by the combination of their associated Dropbox file and template. 15 | 16 | 17 | The :type:`PropertyGroupTemplate` is a way of restricting the possible key names and value types 18 | of the data within a property group. The possible key names and value types are explicitly 19 | enumerated using :type:`PropertyFieldTemplate` objects. 20 | 21 | 22 | You can think of a property group template as a class definition for a particular key/value 23 | metadata object, and the property groups themselves as the instantiations of these objects. 24 | 25 | 26 | Templates are owned either by a user/app pair or team/app pair. Templates and their associated 27 | properties can't be accessed by any app other than the app that created them, and even then, only 28 | when the app is linked with the owner of the template (either a user or team). 29 | 30 | 31 | User-owned templates are accessed via the user-auth file_properties/templates/*_for_user endpoints, while 32 | team-owned templates are accessed via the team-auth file_properties/templates/*_for_team endpoints. Properties 33 | associated with either type of template can be accessed via the user-auth properties/* endpoints. 34 | 35 | 36 | Finally, properties can be accessed from a number of endpoints that return metadata, including 37 | `files/get_metadata`, and `files/list_folder`. Properties can also be added during upload, using 38 | `files/upload`. 39 | 40 | " 41 | 42 | alias TemplateId = String(min_length=1,pattern="(/|ptid:).*") 43 | alias PathOrId = String(pattern="/(.|[\\r\\n])*|id:.*|(ns:[0-9]+(/.*)?)") 44 | alias Id = String(min_length=1) 45 | alias PropertiesSearchCursor = String(min_length=1) 46 | 47 | # 48 | # Core data types 49 | # 50 | 51 | struct PropertyField 52 | "Raw key/value data to be associated with a Dropbox file. Property fields are added to Dropbox 53 | files as a :type:`PropertyGroup`." 54 | 55 | name String 56 | "Key of the property field associated with a file and template. 57 | Keys can be up to 256 bytes." 58 | value String 59 | "Value of the property field associated with a file and template. 60 | Values can be up to 1024 bytes." 61 | 62 | example default 63 | name = "Security Policy" 64 | value = "Confidential" 65 | 66 | struct PropertyGroup 67 | "A subset of the property fields described by the corresponding :type:`PropertyGroupTemplate`. 68 | Properties are always added to a Dropbox file as a :type:`PropertyGroup`. 69 | The possible key names and value types in this group are defined by the 70 | corresponding :type:`PropertyGroupTemplate`." 71 | 72 | template_id TemplateId 73 | "A unique identifier for the associated template." 74 | fields List(PropertyField) 75 | "The actual properties associated with the template. There can be up to 32 76 | property types per template." 77 | 78 | example default 79 | template_id = "ptid:1a5n2i6d3OYEAAAAAAAAAYa" 80 | fields = [default] 81 | 82 | struct PropertyFieldTemplate 83 | "Defines how a single property field may be structured. Used exclusively by :type:`PropertyGroupTemplate`." 84 | 85 | name String 86 | "Key of the property field being described. Property field keys can be up to 256 bytes." 87 | description String 88 | "Description of the property field. Property field descriptions can be up to 1024 bytes." 89 | type PropertyType 90 | "Data type of the value of this property field. This type 91 | will be enforced upon property creation and modifications." 92 | union 93 | "Data type of the given property field added." 94 | 95 | string 96 | "The associated property field will be of type string. Unicode is supported." 97 | 98 | example default 99 | string = null 100 | 101 | example default 102 | name = "Security Policy" 103 | description = "This is the security policy of the file or folder described. 104 | Policies can be Confidential, Public or Internal." 105 | type = default 106 | 107 | struct PropertyGroupTemplate 108 | "Defines how a property group may be structured." 109 | 110 | name String 111 | "Display name for the template. Template names can 112 | be up to 256 bytes." 113 | description String 114 | "Description for the template. Template descriptions 115 | can be up to 1024 bytes." 116 | fields List(PropertyFieldTemplate) 117 | "Definitions of the property fields associated with this template. 118 | There can be up to 32 properties in a single template." 119 | 120 | example default 121 | name = "Security" 122 | description = "These properties describe how confidential this file or folder is." 123 | fields = [default] 124 | 125 | # 126 | # Property routes 127 | # 128 | 129 | struct AddPropertiesArg 130 | path PathOrId 131 | "A unique identifier for the file or folder." 132 | property_groups List(PropertyGroup) 133 | "The property groups which are to be added to a Dropbox file. No two groups in the input should 134 | refer to the same template." 135 | 136 | example default 137 | path = "/my_awesome/word.docx" 138 | property_groups = [default] 139 | 140 | union LookupError 141 | malformed_path String 142 | not_found 143 | "There is nothing at the given path." 144 | not_file 145 | "We were expecting a file, but the given path refers to something that isn't a file." 146 | not_folder 147 | "We were expecting a folder, but the given path refers to something that isn't a folder." 148 | restricted_content 149 | "The file cannot be transferred because the content is restricted. For example, we might restrict a file due to legal requirements." 150 | 151 | union LookUpPropertiesError 152 | property_group_not_found 153 | "No property group was found." 154 | 155 | union TemplateError 156 | template_not_found TemplateId 157 | "Template does not exist for the given identifier." 158 | restricted_content 159 | "You do not have permission to modify this template." 160 | 161 | union PropertiesError extends TemplateError 162 | path LookupError 163 | unsupported_folder 164 | "This folder cannot be tagged. Tagging folders is not supported for team-owned templates." 165 | 166 | union InvalidPropertyGroupError extends PropertiesError 167 | property_field_too_large 168 | "One or more of the supplied property field values is too large." 169 | does_not_fit_template 170 | "One or more of the supplied property fields does not conform to the template specifications." 171 | duplicate_property_groups 172 | "There are 2 or more property groups referring to the same templates in the input. " 173 | 174 | union AddPropertiesError extends InvalidPropertyGroupError 175 | property_group_already_exists 176 | "A property group associated with this template and file already exists." 177 | 178 | route properties/add(AddPropertiesArg, Void, AddPropertiesError) 179 | "Add property groups to a Dropbox file. See :route:`templates/add_for_user` or 180 | :route:`templates/add_for_team` to create new templates." 181 | 182 | attrs 183 | scope = "files.metadata.write" 184 | 185 | struct OverwritePropertyGroupArg 186 | path PathOrId 187 | "A unique identifier for the file or folder." 188 | property_groups List(PropertyGroup, min_items=1) 189 | "The property groups \"snapshot\" updates to force apply. No two groups in the input should 190 | refer to the same template." 191 | 192 | example default 193 | path = "/my_awesome/word.docx" 194 | property_groups = [default] 195 | 196 | route properties/overwrite(OverwritePropertyGroupArg, Void, InvalidPropertyGroupError) 197 | "Overwrite property groups associated with a file. This endpoint should be used 198 | instead of :route:`properties/update` when property groups are being updated via a 199 | \"snapshot\" instead of via a \"delta\". In other words, this endpoint will delete all 200 | omitted fields from a property group, whereas :route:`properties/update` will only 201 | delete fields that are explicitly marked for deletion." 202 | 203 | attrs 204 | scope = "files.metadata.write" 205 | 206 | struct PropertyGroupUpdate 207 | template_id TemplateId 208 | "A unique identifier for a property template." 209 | add_or_update_fields List(PropertyField)? 210 | "Property fields to update. If the property field already exists, it is updated. 211 | If the property field doesn't exist, the property group is added." 212 | remove_fields List(String)? 213 | "Property fields to remove (by name), provided they exist." 214 | 215 | example default 216 | template_id = "ptid:1a5n2i6d3OYEAAAAAAAAAYa" 217 | add_or_update_fields = [default] 218 | remove_fields = [] 219 | 220 | struct UpdatePropertiesArg 221 | path PathOrId 222 | "A unique identifier for the file or folder." 223 | update_property_groups List(PropertyGroupUpdate) 224 | "The property groups \"delta\" updates to apply." 225 | 226 | example default 227 | path = "/my_awesome/word.docx" 228 | update_property_groups = [default] 229 | 230 | union UpdatePropertiesError extends InvalidPropertyGroupError 231 | property_group_lookup LookUpPropertiesError 232 | 233 | route properties/update(UpdatePropertiesArg, Void, UpdatePropertiesError) 234 | "Add, update or remove properties associated with the supplied file and templates. 235 | This endpoint should be used instead of :route:`properties/overwrite` when property groups 236 | are being updated via a \"delta\" instead of via a \"snapshot\" . In other words, this endpoint 237 | will not delete any omitted fields from a property group, whereas :route:`properties/overwrite` 238 | will delete any fields that are omitted from a property group." 239 | 240 | attrs 241 | scope = "files.metadata.write" 242 | 243 | struct RemovePropertiesArg 244 | path PathOrId 245 | "A unique identifier for the file or folder." 246 | property_template_ids List(TemplateId) 247 | "A list of identifiers for a template created by :route:`templates/add_for_user` or 248 | :route:`templates/add_for_team`." 249 | 250 | example default 251 | path = "/my_awesome/word.docx" 252 | property_template_ids = ["ptid:1a5n2i6d3OYEAAAAAAAAAYa"] 253 | 254 | union RemovePropertiesError extends PropertiesError 255 | property_group_lookup LookUpPropertiesError 256 | 257 | route properties/remove(RemovePropertiesArg, Void, RemovePropertiesError) 258 | "Permanently removes the specified property group from the file. To remove specific property field key 259 | value pairs, see :route:`properties/update`. 260 | To update a template, see 261 | :route:`templates/update_for_user` or :route:`templates/update_for_team`. 262 | To remove a template, see 263 | :route:`templates/remove_for_user` or :route:`templates/remove_for_team`." 264 | 265 | attrs 266 | scope = "files.metadata.write" 267 | 268 | # 269 | # Property Group Template Routes 270 | # 271 | 272 | struct AddTemplateArg extends PropertyGroupTemplate 273 | example default 274 | name = "Security" 275 | description = "These properties describe how confidential this file or folder is." 276 | fields = [default] 277 | 278 | struct AddTemplateResult 279 | template_id TemplateId 280 | "An identifier for template added by See :route:`templates/add_for_user` or 281 | :route:`templates/add_for_team`." 282 | 283 | example default 284 | template_id = "ptid:1a5n2i6d3OYEAAAAAAAAAYa" 285 | 286 | union ModifyTemplateError extends TemplateError 287 | conflicting_property_names 288 | "A property field key with that name already exists in the template." 289 | too_many_properties 290 | "There are too many properties in the changed template. 291 | The maximum number of properties per template is 32." 292 | too_many_templates 293 | "There are too many templates for the team." 294 | template_attribute_too_large 295 | "The template name, description or one or more of the property field keys is too large." 296 | 297 | route templates/add_for_user(AddTemplateArg, AddTemplateResult, ModifyTemplateError) 298 | "Add a template associated with a user. See :route:`properties/add` to add properties to a file. This 299 | endpoint can't be called on a team member or admin's behalf." 300 | 301 | attrs 302 | scope = "files.metadata.write" 303 | 304 | route templates/add_for_team(AddTemplateArg, AddTemplateResult, ModifyTemplateError) 305 | "Add a template associated with a team. See :route:`properties/add` to add properties to a file or folder. 306 | 307 | Note: this endpoint will create team-owned templates." 308 | 309 | attrs 310 | auth="team" 311 | scope = "files.team_metadata.write" 312 | 313 | struct GetTemplateArg 314 | template_id TemplateId 315 | "An identifier for template added by route See :route:`templates/add_for_user` or 316 | :route:`templates/add_for_team`." 317 | 318 | example default 319 | template_id = "ptid:1a5n2i6d3OYEAAAAAAAAAYa" 320 | 321 | struct GetTemplateResult extends PropertyGroupTemplate 322 | 323 | example default 324 | name = "Security" 325 | description = "These properties describe how confidential this file or folder is." 326 | fields = [default] 327 | 328 | route templates/get_for_user(GetTemplateArg, GetTemplateResult, TemplateError) 329 | "Get the schema for a specified template. This endpoint can't be called on a team member or admin's behalf." 330 | 331 | attrs 332 | scope = "files.metadata.read" 333 | 334 | route templates/get_for_team(GetTemplateArg, GetTemplateResult, TemplateError) 335 | "Get the schema for a specified template." 336 | 337 | attrs 338 | auth="team" 339 | scope = "files.team_metadata.write" 340 | 341 | struct UpdateTemplateArg 342 | template_id TemplateId 343 | "An identifier for template added by See :route:`templates/add_for_user` or 344 | :route:`templates/add_for_team`." 345 | name String? 346 | "A display name for the template. template names can 347 | be up to 256 bytes." 348 | description String? 349 | "Description for the new template. Template descriptions 350 | can be up to 1024 bytes." 351 | add_fields List(PropertyFieldTemplate)? 352 | "Property field templates to be added to the group template. 353 | There can be up to 32 properties in a single template." 354 | 355 | example default 356 | template_id = "ptid:1a5n2i6d3OYEAAAAAAAAAYa" 357 | name = "New Security Template Name" 358 | description = "These properties will describe how confidential this file or folder is." 359 | add_fields = [default] 360 | 361 | struct UpdateTemplateResult 362 | template_id TemplateId 363 | "An identifier for template added by route See :route:`templates/add_for_user` or 364 | :route:`templates/add_for_team`." 365 | 366 | example default 367 | template_id = "ptid:1a5n2i6d3OYEAAAAAAAAAYa" 368 | 369 | route templates/update_for_user(UpdateTemplateArg, UpdateTemplateResult, ModifyTemplateError) 370 | "Update a template associated with a user. This route can update the template name, 371 | the template description and add optional properties to templates. This endpoint can't 372 | be called on a team member or admin's behalf." 373 | 374 | attrs 375 | scope = "files.metadata.write" 376 | 377 | route templates/update_for_team(UpdateTemplateArg, UpdateTemplateResult, ModifyTemplateError) 378 | "Update a template associated with a team. This route can update the template name, 379 | the template description and add optional properties to templates." 380 | 381 | attrs 382 | auth="team" 383 | scope = "files.team_metadata.write" 384 | 385 | struct ListTemplateResult 386 | template_ids List(TemplateId) 387 | "List of identifiers for templates added by See :route:`templates/add_for_user` or 388 | :route:`templates/add_for_team`." 389 | 390 | example default 391 | template_ids = ["ptid:1a5n2i6d3OYEAAAAAAAAAYa"] 392 | 393 | route templates/list_for_user(Void, ListTemplateResult, TemplateError) 394 | "Get the template identifiers for a team. To get the schema of 395 | each template use :route:`templates/get_for_user`. This endpoint can't be 396 | called on a team member or admin's behalf." 397 | 398 | attrs 399 | scope = "files.metadata.read" 400 | 401 | route templates/list_for_team(Void, ListTemplateResult, TemplateError) 402 | "Get the template identifiers for a team. To get the schema of 403 | each template use :route:`templates/get_for_team`." 404 | 405 | attrs 406 | auth="team" 407 | scope = "files.team_metadata.write" 408 | 409 | struct RemoveTemplateArg 410 | template_id TemplateId 411 | "An identifier for a template created by :route:`templates/add_for_user` or 412 | :route:`templates/add_for_team`." 413 | 414 | example default 415 | template_id = "ptid:1a5n2i6d3OYEAAAAAAAAAYa" 416 | 417 | route templates/remove_for_user(RemoveTemplateArg, Void, TemplateError) 418 | "Permanently removes the specified template created from :route:`templates/add_for_user`. 419 | All properties associated with the template will also be removed. This action 420 | cannot be undone." 421 | 422 | attrs 423 | scope = "files.metadata.write" 424 | 425 | route templates/remove_for_team(RemoveTemplateArg, Void, TemplateError) 426 | "Permanently removes the specified template created from :route:`templates/add_for_user`. 427 | All properties associated with the template will also be removed. This action 428 | cannot be undone." 429 | 430 | attrs 431 | auth="team" 432 | scope = "files.team_metadata.write" 433 | 434 | union TemplateOwnerType 435 | user 436 | "Template will be associated with a user." 437 | team 438 | "Template will be associated with a team." 439 | 440 | example default 441 | user = null 442 | 443 | union LogicalOperator 444 | "Logical operator to join search queries together." 445 | 446 | or_operator 447 | "Append a query with an \"or\" operator." 448 | 449 | example default 450 | or_operator = null 451 | 452 | union PropertiesSearchMode 453 | field_name String 454 | "Search for a value associated with this field name." 455 | 456 | example default 457 | field_name = "Security" 458 | 459 | struct PropertiesSearchQuery 460 | query String 461 | "The property field value for which to search across templates." 462 | mode PropertiesSearchMode 463 | "The mode with which to perform the search." 464 | logical_operator LogicalOperator = or_operator 465 | "The logical operator with which to append the query." 466 | 467 | example default 468 | query = "Confidential" 469 | mode = default 470 | logical_operator = default 471 | 472 | union TemplateFilterBase 473 | filter_some List(TemplateId, min_items=1) 474 | "Only templates with an ID in the supplied list will be returned (a subset of 475 | templates will be returned)." 476 | 477 | example default 478 | filter_some = ["ptid:1a5n2i6d3OYEAAAAAAAAAYa"] 479 | 480 | union TemplateFilter extends TemplateFilterBase 481 | filter_none 482 | "No templates will be filtered from the result (all templates will be returned)." 483 | 484 | example default 485 | filter_none = null 486 | 487 | struct PropertiesSearchArg 488 | queries List(PropertiesSearchQuery, min_items=1) 489 | "Queries to search." 490 | template_filter TemplateFilter = filter_none 491 | "Filter results to contain only properties associated with these template IDs." 492 | 493 | example default 494 | queries = [default] 495 | template_filter = default 496 | 497 | struct PropertiesSearchMatch 498 | id Id 499 | "The ID for the matched file or folder." 500 | path String 501 | "The path for the matched file or folder." 502 | is_deleted Boolean 503 | "Whether the file or folder is deleted." 504 | property_groups List(PropertyGroup) 505 | "List of custom property groups associated with the file." 506 | 507 | example default 508 | id = "id:a4ayc_80_OEAAAAAAAAAXz" 509 | path = "/my_awesome/word.docx" 510 | is_deleted = false 511 | property_groups = [default] 512 | 513 | struct PropertiesSearchResult 514 | matches List(PropertiesSearchMatch) 515 | "A list (possibly empty) of matches for the query." 516 | cursor PropertiesSearchCursor? 517 | "Pass the cursor into :route:`properties/search/continue` to continue to receive 518 | search results. Cursor will be null when there are no more results." 519 | 520 | example default 521 | matches = [default] 522 | 523 | union PropertiesSearchError 524 | property_group_lookup LookUpPropertiesError 525 | 526 | route properties/search(PropertiesSearchArg, PropertiesSearchResult, PropertiesSearchError) 527 | "Search across property templates for particular property field values." 528 | 529 | attrs 530 | scope = "files.metadata.read" 531 | 532 | struct PropertiesSearchContinueArg 533 | cursor PropertiesSearchCursor 534 | "The cursor returned by your last call to :route:`properties/search` or 535 | :route:`properties/search/continue`." 536 | 537 | example default 538 | cursor = "ZtkX9_EHj3x7PMkVuFIhwKYXEpwpLwyxp9vMKomUhllil9q7eWiAu" 539 | 540 | union PropertiesSearchContinueError 541 | reset 542 | "Indicates that the cursor has been invalidated. Call 543 | :route:`properties/search` to obtain a new cursor." 544 | 545 | route properties/search/continue (PropertiesSearchContinueArg, PropertiesSearchResult, PropertiesSearchContinueError) 546 | "Once a cursor has been retrieved from :route:`properties/search`, use this to paginate through all 547 | search results." 548 | 549 | attrs 550 | scope = "files.metadata.read" 551 | -------------------------------------------------------------------------------- /file_requests.stone: -------------------------------------------------------------------------------- 1 | namespace file_requests 2 | "This namespace contains endpoints and data types for file request operations." 3 | 4 | 5 | alias FileRequestId = String(pattern="[-_0-9a-zA-Z]+", min_length=1) 6 | 7 | import common 8 | import files 9 | 10 | # 11 | # Common file requests objects 12 | # 13 | 14 | union GracePeriod 15 | one_day 16 | two_days 17 | seven_days 18 | thirty_days 19 | always 20 | 21 | example default 22 | seven_days = null 23 | 24 | struct FileRequestDeadline 25 | 26 | deadline common.DropboxTimestamp 27 | "The deadline for this file request." 28 | allow_late_uploads GracePeriod? 29 | "If set, allow uploads after the deadline has passed. These 30 | uploads will be marked overdue." 31 | 32 | example deadline 33 | deadline = "2020-10-12T17:00:00Z" 34 | 35 | example deadline_with_grace_period 36 | deadline = "2020-10-12T17:00:00Z" 37 | allow_late_uploads = seven_days 38 | 39 | struct FileRequest 40 | "A :link:`file request https://www.dropbox.com/help/9090` for receiving 41 | files into the user's Dropbox account." 42 | 43 | id FileRequestId 44 | "The ID of the file request." 45 | url String(min_length=1) 46 | "The URL of the file request." 47 | title String(min_length=1) 48 | "The title of the file request." 49 | destination files.Path? 50 | "The path of the folder in the Dropbox where uploaded files will be 51 | sent. This can be :val:`null` if the destination was removed. For apps 52 | with the app folder permission, this will be relative to the app 53 | folder." 54 | created common.DropboxTimestamp 55 | "When this file request was created." 56 | deadline FileRequestDeadline? 57 | "The deadline for this file request. Only set if the request has a 58 | deadline." 59 | is_open Boolean 60 | "Whether or not the file request is open. If the file request is 61 | closed, it will not accept any more file submissions." 62 | file_count Int64 63 | "The number of files this file request has received." 64 | description String? 65 | "A description of the file request." 66 | 67 | example default 68 | id = "oaCAVmEyrqYnkZX9955Y" 69 | url = "https://www.dropbox.com/request/oaCAVmEyrqYnkZX9955Y" 70 | title = "Homework submission" 71 | destination = "/File Requests/Homework" 72 | created = "2015-10-05T17:00:00Z" 73 | deadline = deadline_with_grace_period 74 | is_open = true 75 | file_count = 3 76 | description = "Please submit your homework here." 77 | 78 | example with_deadline 79 | id = "BAJ7IrRGicQKGToykQdB" 80 | url = "https://www.dropbox.com/request/BAJ7IrRGjcQKGToykQdB" 81 | title = "Photo contest submission" 82 | destination = "/Photo contest entries" 83 | created = "2015-11-02T04:00:00Z" 84 | deadline = deadline 85 | is_open = true 86 | file_count = 105 87 | 88 | example with_no_deadline 89 | id = "rxwMPvK3ATTa0VxOJu5T" 90 | url = "https://www.dropbox.com/request/rxwMPvK3ATTa0VxOJu5T" 91 | title = "Wedding photo submission" 92 | destination = "/Wedding photos" 93 | created = "2015-12-15T13:02:00Z" 94 | deadline = null 95 | is_open = true 96 | file_count = 37 97 | 98 | alias FileRequestValidationError = String? 99 | 100 | union GeneralFileRequestsError 101 | "There is an error accessing the file requests functionality." 102 | 103 | disabled_for_team 104 | "This user's Dropbox Business team doesn't allow file requests." 105 | 106 | union FileRequestError extends GeneralFileRequestsError 107 | "There is an error with the file request." 108 | 109 | not_found 110 | "This file request ID was not found." 111 | not_a_folder 112 | "The specified path is not a folder." 113 | app_lacks_access 114 | "This file request is not accessible to this app. Apps with the app 115 | folder permission can only access file requests in their app folder." 116 | no_permission 117 | "This user doesn't have permission to access or modify this file 118 | request." 119 | email_unverified 120 | "This user's email address is not verified. File requests are only 121 | available on accounts with a verified email address. Users can verify 122 | their email address :link:`here https://www.dropbox.com/help/317`." 123 | validation_error 124 | "There was an error validating the request. For example, the title was 125 | invalid, or there were disallowed characters in the destination path." 126 | 127 | # 128 | # Getting file requests 129 | # 130 | 131 | route list:2(ListFileRequestsArg, ListFileRequestsV2Result, ListFileRequestsError) 132 | "Returns a list of file requests owned by this user. For apps with the app 133 | folder permission, this will only return file requests with destinations in 134 | the app folder." 135 | 136 | attrs 137 | allow_app_folder_app = true 138 | scope = "file_requests.read" 139 | 140 | struct ListFileRequestsArg 141 | "Arguments for :route:`list:2`." 142 | 143 | limit UInt64 = 1000 144 | "The maximum number of file requests that should be returned per request." 145 | 146 | example default 147 | limit = 1000 148 | 149 | struct ListFileRequestsV2Result 150 | "Result for :route:`list:2` and :route:`list/continue`." 151 | 152 | file_requests List(FileRequest) 153 | "The file requests owned by this user. Apps with the app folder 154 | permission will only see file requests in their app folder." 155 | 156 | cursor String 157 | "Pass the cursor into :route:`list/continue` to obtain additional file requests." 158 | 159 | has_more Boolean 160 | "Is true if there are additional file requests that have not been returned 161 | yet. An additional call to :route:list/continue` can retrieve them." 162 | 163 | example default 164 | file_requests = [default, with_deadline, with_no_deadline] 165 | cursor = "ZtkX9_EHj3x7PMkVuFIhwKYXEpwpLwyxp9vMKomUhllil9q7eWiAu" 166 | has_more = true 167 | 168 | route list/continue(ListFileRequestsContinueArg, ListFileRequestsV2Result, ListFileRequestsContinueError) 169 | "Once a cursor has been retrieved from :route:`list:2`, use this to paginate through all 170 | file requests. The cursor must come from a previous call to :route:`list:2` or 171 | :route:`list/continue`." 172 | attrs 173 | allow_app_folder_app = true 174 | scope = "file_requests.read" 175 | 176 | struct ListFileRequestsContinueArg 177 | cursor String 178 | "The cursor returned by the previous API call specified in the endpoint description." 179 | 180 | example default 181 | cursor = "ZtkX9_EHj3x7PMkVuFIhwKYXEpwpLwyxp9vMKomUhllil9q7eWiAu" 182 | 183 | union ListFileRequestsContinueError extends GeneralFileRequestsError 184 | "There was an error retrieving the file requests." 185 | 186 | invalid_cursor 187 | "The cursor is invalid." 188 | 189 | 190 | route list(Void, ListFileRequestsResult, ListFileRequestsError) 191 | "Returns a list of file requests owned by this user. For apps with the app 192 | folder permission, this will only return file requests with destinations in 193 | the app folder." 194 | 195 | attrs 196 | allow_app_folder_app = true 197 | scope = "file_requests.read" 198 | 199 | struct ListFileRequestsResult 200 | "Result for :route:`list`." 201 | 202 | file_requests List(FileRequest) 203 | "The file requests owned by this user. Apps with the app folder 204 | permission will only see file requests in their app folder." 205 | 206 | example default 207 | file_requests = [default, with_deadline, with_no_deadline] 208 | 209 | union ListFileRequestsError extends GeneralFileRequestsError 210 | "There was an error retrieving the file requests." 211 | 212 | 213 | # 214 | # Getting individual file requests 215 | # 216 | 217 | route get(GetFileRequestArgs, FileRequest, GetFileRequestError) 218 | "Returns the specified file request." 219 | 220 | attrs 221 | allow_app_folder_app = true 222 | scope = "file_requests.read" 223 | 224 | struct GetFileRequestArgs 225 | "Arguments for :route:`get`." 226 | 227 | id FileRequestId 228 | "The ID of the file request to retrieve." 229 | 230 | example default 231 | id = "oaCAVmEyrqYnkZX9955Y" 232 | 233 | union GetFileRequestError extends FileRequestError 234 | "There was an error retrieving the specified file request." 235 | 236 | 237 | # 238 | # Creating new file requests 239 | # 240 | 241 | route create(CreateFileRequestArgs, FileRequest, CreateFileRequestError) 242 | "Creates a file request for this user." 243 | 244 | attrs 245 | allow_app_folder_app = true 246 | scope = "file_requests.write" 247 | 248 | struct CreateFileRequestArgs 249 | "Arguments for :route:`create`." 250 | 251 | title String(min_length=1) 252 | "The title of the file request. Must not be empty." 253 | destination files.Path 254 | "The path of the folder in the Dropbox where uploaded files will be 255 | sent. For apps with the app folder permission, this will be relative to 256 | the app folder." 257 | deadline FileRequestDeadline? 258 | "The deadline for the file request. Deadlines can only be set by 259 | Professional and Business accounts." 260 | open Boolean = true 261 | "Whether or not the file request should be open. If the file request is 262 | closed, it will not accept any file submissions, but it can be opened 263 | later." 264 | description String? 265 | "A description of the file request." 266 | 267 | example default 268 | title = "Homework submission" 269 | destination = "/File Requests/Homework" 270 | deadline = deadline_with_grace_period 271 | 272 | union CreateFileRequestError extends FileRequestError 273 | "There was an error creating the file request." 274 | 275 | invalid_location 276 | "File requests are not available on the specified folder." 277 | rate_limit 278 | "The user has reached the rate limit for creating file requests. The 279 | limit is currently 4000 file requests total." 280 | 281 | # 282 | # Updating existing file requests 283 | # 284 | 285 | route update(UpdateFileRequestArgs, FileRequest, UpdateFileRequestError) 286 | "Update a file request." 287 | 288 | attrs 289 | allow_app_folder_app = true 290 | scope = "file_requests.write" 291 | 292 | struct UpdateFileRequestArgs 293 | "Arguments for :route:`update`." 294 | 295 | id FileRequestId 296 | "The ID of the file request to update." 297 | title String(min_length=1)? 298 | "The new title of the file request. Must not be empty." 299 | destination files.Path? 300 | "The new path of the folder in the Dropbox where uploaded files will be 301 | sent. For apps with the app folder permission, this will be relative to 302 | the app folder." 303 | deadline UpdateFileRequestDeadline = no_update 304 | "The new deadline for the file request. Deadlines can only be set by 305 | Professional and Business accounts." 306 | union 307 | no_update 308 | "Do not change the file request's deadline." 309 | update FileRequestDeadline? 310 | "If :val:`null`, the file request's deadline is cleared." 311 | 312 | example set_deadline 313 | update = deadline_with_grace_period 314 | open Boolean? 315 | "Whether to set this file request as open or closed." 316 | description String? 317 | "The description of the file request." 318 | 319 | example default 320 | id = "oaCAVmEyrqYnkZX9955Y" 321 | title = "Homework submission" 322 | destination = "/File Requests/Homework" 323 | deadline = set_deadline 324 | open = true 325 | 326 | union UpdateFileRequestError extends FileRequestError 327 | "There is an error updating the file request." 328 | 329 | # 330 | # Count file requests 331 | # 332 | 333 | route count(Void, CountFileRequestsResult, CountFileRequestsError) 334 | "Returns the total number of file requests owned by this user. Includes both open and 335 | closed file requests." 336 | 337 | attrs 338 | allow_app_folder_app = true 339 | scope = "file_requests.read" 340 | 341 | struct CountFileRequestsResult 342 | "Result for :route:`count`." 343 | 344 | file_request_count UInt64 345 | "The number file requests owner by this user." 346 | 347 | example default 348 | file_request_count = 15 349 | 350 | union CountFileRequestsError extends GeneralFileRequestsError 351 | "There was an error counting the file requests." 352 | 353 | # 354 | # Deleting existing file requests 355 | # 356 | 357 | route delete(DeleteFileRequestArgs, DeleteFileRequestsResult, DeleteFileRequestError) 358 | "Delete a batch of closed file requests." 359 | 360 | attrs 361 | allow_app_folder_app = true 362 | scope = "file_requests.write" 363 | 364 | struct DeleteFileRequestArgs 365 | "Arguments for :route:`delete`." 366 | 367 | ids List(FileRequestId) 368 | "List IDs of the file requests to delete." 369 | 370 | example default 371 | ids = ["oaCAVmEyrqYnkZX9955Y", "BaZmehYoXMPtaRmfTbSG"] 372 | 373 | struct DeleteFileRequestsResult 374 | "Result for :route:`delete`." 375 | 376 | file_requests List(FileRequest) 377 | "The file requests deleted by the request." 378 | 379 | example default 380 | file_requests = [default, with_deadline, with_no_deadline] 381 | 382 | union DeleteFileRequestError extends FileRequestError 383 | "There was an error deleting these file requests." 384 | 385 | file_request_open 386 | "One or more file requests currently open." 387 | 388 | # 389 | # Deleting all closed file requests 390 | # 391 | 392 | route delete_all_closed(Void, DeleteAllClosedFileRequestsResult, DeleteAllClosedFileRequestsError) 393 | "Delete all closed file requests owned by this user." 394 | 395 | attrs 396 | allow_app_folder_app = true 397 | scope = "file_requests.write" 398 | 399 | struct DeleteAllClosedFileRequestsResult 400 | "Result for :route:`delete_all_closed`." 401 | 402 | file_requests List(FileRequest) 403 | "The file requests deleted for this user." 404 | 405 | example default 406 | file_requests = [default, with_deadline, with_no_deadline] 407 | 408 | union DeleteAllClosedFileRequestsError extends FileRequestError 409 | "There was an error deleting all closed file requests." 410 | -------------------------------------------------------------------------------- /file_tagging.stone: -------------------------------------------------------------------------------- 1 | namespace files 2 | 3 | import common 4 | import async 5 | 6 | alias TagText = String(min_length=1, max_length=32, pattern="[\\w]+") 7 | 8 | union Tag 9 | "Tag that can be added in multiple ways." 10 | 11 | user_generated_tag UserGeneratedTag 12 | "Tag generated by the user." 13 | 14 | example default 15 | user_generated_tag = default 16 | 17 | 18 | struct UserGeneratedTag 19 | tag_text TagText 20 | 21 | example default 22 | tag_text = "my_tag" 23 | 24 | 25 | union BaseTagError 26 | path LookupError 27 | 28 | 29 | ##################################### 30 | # Add Tag to an item 31 | ##################################### 32 | struct AddTagArg 33 | path Path 34 | "Path to the item to be tagged." 35 | 36 | tag_text TagText 37 | "The value of the tag to add. Will be automatically converted to lowercase letters." 38 | 39 | example default 40 | path = "/Prime_Numbers.txt" 41 | tag_text = "my_tag" 42 | 43 | union AddTagError extends BaseTagError 44 | too_many_tags 45 | "The item already has the maximum supported number of tags." 46 | 47 | route tags/add(AddTagArg, Void, AddTagError) 48 | "Add a tag to an item. A tag is a string. The strings are automatically converted to lowercase letters. No more than 20 tags can be added to a given item." 49 | 50 | attrs 51 | auth = "user" 52 | is_preview = true 53 | scope = "files.metadata.write" 54 | 55 | 56 | ##################################### 57 | # Remove Tag from a item 58 | ##################################### 59 | 60 | struct RemoveTagArg 61 | path Path 62 | "Path to the item to tag." 63 | 64 | tag_text TagText 65 | "The tag to remove. Will be automatically converted to lowercase letters." 66 | 67 | example default 68 | path = "/Prime_Numbers.txt" 69 | tag_text = "my_tag" 70 | 71 | union RemoveTagError extends BaseTagError 72 | tag_not_present 73 | "That tag doesn't exist at this path." 74 | 75 | route tags/remove(RemoveTagArg, Void, RemoveTagError) 76 | "Remove a tag from an item." 77 | 78 | attrs 79 | auth = "user" 80 | is_preview = true 81 | scope = "files.metadata.write" 82 | 83 | ############################################### 84 | # Get tags by item 85 | ############################################### 86 | struct GetTagsArg 87 | paths List(Path) 88 | "Path to the items." 89 | 90 | example default 91 | paths = ["/Prime_Numbers.txt"] 92 | 93 | struct PathToTags 94 | path Path 95 | "Path of the item." 96 | tags List(Tag) 97 | "Tags assigned to this item." 98 | example default 99 | path = "/Prime_Numbers.txt" 100 | tags = [default] 101 | 102 | struct GetTagsResult 103 | paths_to_tags List(PathToTags) 104 | "List of paths and their corresponding tags." 105 | 106 | example default 107 | paths_to_tags = [default] 108 | 109 | route tags/get(GetTagsArg, GetTagsResult, BaseTagError) 110 | "Get list of tags assigned to items." 111 | 112 | attrs 113 | auth = "user" 114 | is_preview = true 115 | scope = "files.metadata.read" 116 | -------------------------------------------------------------------------------- /openid_openid.stone: -------------------------------------------------------------------------------- 1 | # @generated by protoc-gen-stone. DO NOT EDIT. 2 | # source: configs/proto/dropbox/proto/openid/openid.proto 3 | namespace openid 4 | 5 | route userinfo (UserInfoArgs, UserInfoResult, UserInfoError) 6 | "This route is used for refreshing the info that is found in the id_token during the OIDC flow. 7 | This route doesn't require any arguments and will use the scopes approved for the given access token." 8 | 9 | attrs 10 | allow_app_folder_app = true 11 | auth = "user" 12 | is_preview = true 13 | scope = "openid" 14 | 15 | -------------------------------------------------------------------------------- /openid_openid_types.stone: -------------------------------------------------------------------------------- 1 | # @generated by protoc-gen-stone. DO NOT EDIT. 2 | # source: configs/proto/dropbox/proto/openid/openid_types.proto 3 | namespace openid 4 | 5 | import common 6 | 7 | union OpenIdError 8 | incorrect_openid_scopes 9 | "Missing openid claims for the associated access token." 10 | 11 | 12 | union UserInfoError 13 | openid_error OpenIdError = incorrect_openid_scopes 14 | 15 | struct UserInfoArgs 16 | "No Parameters" 17 | 18 | struct UserInfoResult 19 | family_name String? 20 | "Last name of user." 21 | given_name String? 22 | "First name of user." 23 | email String? 24 | "Email address of user." 25 | email_verified Boolean? 26 | "If user is email verified." 27 | iss String = "" 28 | "Issuer of token (in this case Dropbox)." 29 | sub String = "" 30 | "An identifier for the user. This is the Dropbox account_id, a string 31 | value such as dbid:AAH4f99T0taONIb-OurWxbNQ6ywGRopQngc." 32 | 33 | -------------------------------------------------------------------------------- /release_note_generator.py: -------------------------------------------------------------------------------- 1 | import os 2 | import re 3 | from enum import Enum 4 | from datetime import date 5 | from collections import defaultdict 6 | from sys import argv 7 | from typing import List, Optional, NamedTuple, Tuple 8 | from unidiff import PatchSet 9 | 10 | class DataType(str, Enum): 11 | ROUTE = "route" 12 | STRUCT = "struct" 13 | UNION = "union" 14 | 15 | NsChange = NamedTuple('NsChange', [ 16 | ('file_name', str), 17 | ('added_routes', List[str]), 18 | ('added_structs', List[str]), 19 | ('added_unions', List[str]), 20 | ('deprecated_routes', List[str]), 21 | ('removed_routes', List[str]), 22 | ('removed_structs', List[str]), 23 | ('removed_unions', List[str]), 24 | ('updated_datatypes', Optional[List[Tuple[str, DataType]]]), 25 | ]) 26 | 27 | ChangeLog = NamedTuple('ChangeLog', [ 28 | ('ns_changes', List[NsChange]), 29 | ('added_nses', List[str]), 30 | ('removed_nses', List[str]), 31 | ]) 32 | 33 | 34 | def parse_datatype_info(line): 35 | # type: (str) -> Optional[Tuple[DataType, str]] 36 | route = re.match(r"^route (.+)\(", line) 37 | struct = re.match(r"^struct (.+)$", line) 38 | union = re.match(r"^union (.+)$", line) 39 | match = struct or union or route 40 | if not match: 41 | return None 42 | datatype = DataType.ROUTE 43 | if struct: 44 | datatype = DataType.STRUCT 45 | if union: 46 | datatype = DataType.UNION 47 | return datatype, match.group(1) 48 | 49 | 50 | def parse_change_log(change_log_diff): 51 | # type: (str) -> ChangeLog 52 | ns_changes = [] 53 | added_nses = [] 54 | removed_nses = [] 55 | 56 | patch = PatchSet(change_log_diff) 57 | for patch_file in patch: 58 | path_parts = patch_file.path.split('.') 59 | if len(path_parts) != 2: 60 | continue 61 | ns_file_name, ext = path_parts 62 | if ext != "stone": 63 | continue 64 | 65 | if patch_file.is_added_file: 66 | added_nses.append(ns_file_name) 67 | continue 68 | 69 | if patch_file.is_removed_file: 70 | removed_nses.append(ns_file_name) 71 | continue 72 | 73 | added_routes = [] 74 | added_structs = [] 75 | added_unions = [] 76 | deprecated_routes = [] 77 | removed_routes = [] 78 | removed_structs = [] 79 | removed_unions = [] 80 | updated_datatypes = [] 81 | 82 | route_map = defaultdict(int) 83 | 84 | # Pass for checking for creation/deletion of datatypes 85 | for hunk in patch_file: 86 | for line in hunk: 87 | datatype_info = parse_datatype_info(line.value) 88 | if datatype_info is None: 89 | continue 90 | datatype, datatype_name = datatype_info 91 | 92 | if datatype == DataType.ROUTE: 93 | if line.is_added: 94 | route_map[datatype_name] += 1 95 | if line.is_removed: 96 | route_map[datatype_name] -= 1 97 | 98 | if datatype == DataType.STRUCT: 99 | if line.is_added: 100 | added_structs.append(datatype_name) 101 | if line.is_removed: 102 | removed_structs.append(datatype_name) 103 | 104 | if datatype == DataType.UNION: 105 | if line.is_added: 106 | added_unions.append(datatype_name) 107 | if line.is_removed: 108 | removed_unions.append(datatype_name) 109 | 110 | 111 | datatype, datatype_name = None, None 112 | seen_datatypes = set() 113 | 114 | # Pass to check for updated datatypes 115 | for line in hunk: 116 | datatype_info = parse_datatype_info(line.value) 117 | if datatype_info and not line.is_removed: 118 | if line.is_added: 119 | datatype, datatype_name = None, None 120 | else: 121 | datatype, datatype_name = datatype_info 122 | if not datatype_info and datatype and datatype_name: 123 | if line.is_removed or line.is_added and datatype_name not in seen_datatypes: 124 | updated_datatypes.append((datatype, datatype_name)) 125 | seen_datatypes.add(datatype_name) 126 | 127 | for route, ref_count in route_map.items(): 128 | if ref_count > 0: 129 | added_routes.append(route) 130 | if ref_count < 0: 131 | removed_routes.append(route) 132 | 133 | ns_change = NsChange( 134 | ns_file_name, 135 | added_routes, 136 | added_structs, 137 | added_unions, 138 | deprecated_routes, 139 | removed_routes, 140 | removed_structs, 141 | removed_unions, 142 | updated_datatypes, 143 | ) 144 | ns_changes.append(ns_change) 145 | 146 | change_log = ChangeLog(ns_changes, added_nses, removed_nses) 147 | return change_log 148 | 149 | 150 | def main(): 151 | stream = os.popen('git diff') 152 | diff = stream.read() 153 | change_log = parse_change_log(diff) 154 | print("Spec Update {} (#)".format(date.today().strftime("%m/%d/%Y"))) 155 | print() 156 | print("Change Notes:") 157 | for ns_change in change_log.ns_changes: 158 | print() 159 | print("{} Namespace".format(ns_change.file_name)) 160 | if ns_change.added_routes: 161 | print("- Add {} routes".format(", ".join(ns_change.added_routes))) 162 | if ns_change.added_structs: 163 | print("- Add {} structs".format(", ".join(ns_change.added_structs))) 164 | if ns_change.added_unions: 165 | print("- Add {} unions".format(", ".join(ns_change.added_unions))) 166 | if ns_change.removed_routes: 167 | print("- Remove {} routes".format(", ".join(ns_change.removed_routes))) 168 | if ns_change.removed_structs: 169 | print("- Remove {} structs".format(", ".join(ns_change.removed_structs))) 170 | if ns_change.removed_unions: 171 | print("- Remove {} unions".format(", ".join(ns_change.removed_unions))) 172 | if ns_change.updated_datatypes: 173 | for datatype, datatype_name in ns_change.updated_datatypes: 174 | print("- Update {} {} to include/remove/deprecate ".format(datatype_name, datatype)) 175 | if change_log.added_nses: 176 | print() 177 | for ns in change_log.added_nses: 178 | print("Add {} namespace".format(ns)) 179 | 180 | if change_log.removed_nses: 181 | print() 182 | for ns in change_log.removed_nses: 183 | print("Add {} namespace".format(ns)) 184 | 185 | 186 | if __name__ == "__main__": 187 | main() 188 | -------------------------------------------------------------------------------- /secondary_emails.stone: -------------------------------------------------------------------------------- 1 | namespace secondary_emails 2 | 3 | import common 4 | 5 | struct SecondaryEmail 6 | email common.EmailAddress 7 | "Secondary email address." 8 | 9 | is_verified Boolean 10 | "Whether or not the secondary email address is verified to be owned by a user." 11 | 12 | example default 13 | email = "apple@orange.com" 14 | is_verified = true 15 | 16 | example second_sec_email 17 | email = "banana@honeydew.com" 18 | is_verified = true 19 | 20 | example third_sec_email 21 | email = "grape@strawberry.com" 22 | is_verified = false 23 | -------------------------------------------------------------------------------- /seen_state.stone: -------------------------------------------------------------------------------- 1 | namespace seen_state 2 | 3 | union PlatformType 4 | "Possible platforms on which a user may view content." 5 | web 6 | "The content was viewed on the web." 7 | desktop 8 | "The content was viewed on a desktop client." 9 | mobile_ios 10 | "The content was viewed on a mobile iOS client." 11 | mobile_android 12 | "The content was viewed on a mobile android client." 13 | api 14 | "The content was viewed from an API client." 15 | unknown 16 | "The content was viewed on an unknown platform." 17 | mobile 18 | "The content was viewed on a mobile client. DEPRECATED: Use mobile_ios or mobile_android instead." 19 | -------------------------------------------------------------------------------- /shared_content_links.stone: -------------------------------------------------------------------------------- 1 | namespace sharing 2 | 3 | import common 4 | 5 | 6 | union LinkExpiry 7 | remove_expiry 8 | "Remove the currently set expiry for the link." 9 | set_expiry common.DropboxTimestamp 10 | "Set a new expiry or change an existing expiry." 11 | 12 | union LinkPassword 13 | 14 | remove_password 15 | "Remove the currently set password for the link." 16 | 17 | set_password String 18 | "Set a new password or change an existing password." 19 | 20 | struct LinkSettings 21 | "Settings that apply to a link." 22 | access_level AccessLevel? 23 | "The access level on the link for this file. Currently, 24 | it only accepts 'viewer' and 'viewer_no_comment'." 25 | audience LinkAudience? 26 | "The type of audience on the link for this file." 27 | expiry LinkExpiry? 28 | "An expiry timestamp to set on a link." 29 | password LinkPassword? 30 | "The password for the link." 31 | 32 | union LinkAudience 33 | public 34 | "Link is accessible by anyone." 35 | team 36 | "Link is accessible only by team members." 37 | no_one 38 | "The link can be used by no one. The link merely points the user to the content, and does 39 | not grant additional rights to the user. Members of the content who use this link can only 40 | access the content with their pre-existing access rights." 41 | password 42 | "Use `require_password` instead. A link-specific password is required to access the 43 | link. Login is not required." 44 | members 45 | "Link is accessible only by members of the content." 46 | 47 | struct LinkPermission 48 | "Permissions for actions that can be performed on a link." 49 | action LinkAction 50 | allow Boolean 51 | reason PermissionDeniedReason? 52 | 53 | example default 54 | action = change_audience 55 | allow = true 56 | 57 | union LinkAction 58 | "Actions that can be performed on a link." 59 | change_access_level 60 | "Change the access level of the link." 61 | change_audience 62 | "Change the audience of the link." 63 | remove_expiry 64 | "Remove the expiry date of the link." 65 | remove_password 66 | "Remove the password of the link." 67 | set_expiry 68 | "Create or modify the expiry date of the link." 69 | set_password 70 | "Create or modify the password of the link." 71 | 72 | struct SharedContentLinkMetadataBase 73 | access_level AccessLevel? 74 | "The access level on the link for this file." 75 | audience_options List(LinkAudience) 76 | "The audience options that are available for the content. Some audience options may be 77 | unavailable. For example, team_only may be unavailable if the content is not owned by a 78 | user on a team. The 'default' audience option is always available if the user can modify 79 | link settings." 80 | audience_restricting_shared_folder AudienceRestrictingSharedFolder? 81 | "The shared folder that prevents the link audience for this link from being more 82 | restrictive." 83 | current_audience LinkAudience 84 | "The current audience of the link." 85 | expiry common.DropboxTimestamp? 86 | "Whether the link has an expiry set on it. A link with an expiry will have its 87 | audience changed to members when the expiry is reached." 88 | link_permissions List(LinkPermission) 89 | "A list of permissions for actions you can perform on the link." 90 | password_protected Boolean 91 | "Whether the link is protected by a password." 92 | 93 | struct SharedContentLinkMetadata extends SharedContentLinkMetadataBase 94 | "Metadata of a shared link for a file or folder." 95 | 96 | audience_exceptions AudienceExceptions? 97 | "The content inside this folder with link audience different than this folder's. This is 98 | only returned when an endpoint that returns metadata for a single shared folder is called, 99 | e.g. /get_folder_metadata." 100 | 101 | url String 102 | "The URL of the link." 103 | 104 | example default 105 | audience_options = [public, team, members] 106 | current_audience = public 107 | link_permissions = [default] 108 | password_protected = false 109 | url = "" 110 | 111 | struct ExpectedSharedContentLinkMetadata extends SharedContentLinkMetadataBase 112 | "The expected metadata of a shared link for a file or folder when a link is first created for 113 | the content. Absent if the link already exists." 114 | 115 | example default 116 | audience_options = [public, team, members] 117 | current_audience = public 118 | link_permissions = [default] 119 | password_protected = false 120 | 121 | struct AudienceRestrictingSharedFolder 122 | "Information about the shared folder that prevents the link audience for this link from being 123 | more restrictive." 124 | shared_folder_id common.SharedFolderId 125 | "The ID of the shared folder." 126 | name String 127 | "The name of the shared folder." 128 | audience LinkAudience 129 | "The link audience of the shared folder." 130 | 131 | struct AudienceExceptions 132 | "The total count and truncated list of information of content inside this folder that has a 133 | different audience than the link on this folder. This is only returned for folders." 134 | count UInt32 135 | exceptions List(AudienceExceptionContentInfo) 136 | "A truncated list of some of the content that is an exception. The length of this list could 137 | be smaller than the count since it is only a sample but will not be empty as long as 138 | count is not 0." 139 | 140 | example default 141 | count = 0 142 | exceptions = [] 143 | 144 | struct AudienceExceptionContentInfo 145 | "Information about the content that has a link audience different than that of this folder." 146 | name String 147 | "The name of the content, which is either a file or a folder." 148 | 149 | example default 150 | name = "sample file name" 151 | -------------------------------------------------------------------------------- /sharing.stone: -------------------------------------------------------------------------------- 1 | namespace sharing 2 | "This namespace contains endpoints and data types for creating and managing shared links and 3 | shared folders." 4 | 5 | import common 6 | import files 7 | import users 8 | -------------------------------------------------------------------------------- /stone_cfg.stone: -------------------------------------------------------------------------------- 1 | namespace stone_cfg 2 | 3 | struct Route 4 | 5 | auth String(pattern="^(user|team|app|noauth|app, user)$") = "user" 6 | "The auth type for the route. In case of multiple values it should be sorted allphabetically" 7 | host String(pattern="^(api|content|notify)$") = "api" 8 | "The server to make the request to. " 9 | style String(pattern="^(rpc|download|upload)$") = "rpc" 10 | "The RPC format to use for the request." 11 | is_preview Boolean = false 12 | "A flag indicating whether the route is subject to breaking 13 | changes without notice." 14 | allow_app_folder_app Boolean = false 15 | "If app folder app is allowed to use this endpoint." 16 | select_admin_mode String(pattern="^(team_admin|whole_team)$")? 17 | "Which mode for Dropbox-API-Select-Admin header can be used in this route." 18 | scope String? 19 | "Name of the scope required to call this route." 20 | is_cloud_doc_auth Boolean = false 21 | "Whether the endpoint is a Dropbox cloud docs endpoint which takes cloud docs auth token." 22 | -------------------------------------------------------------------------------- /team.stone: -------------------------------------------------------------------------------- 1 | namespace team 2 | 3 | import common 4 | import file_properties 5 | import team_common 6 | import team_policies 7 | import users_common 8 | import secondary_emails 9 | 10 | # Note that in the database, we also have members that are in state "deleted" 11 | # meaning that the User has been permanently removed from the team. 12 | # But the API is not going to expose such users externally. We will omit such users 13 | # in API responses. 14 | # 15 | union_closed TeamMemberStatus 16 | "The user's status as a member of a specific team." 17 | 18 | active 19 | "User has successfully joined the team." 20 | invited 21 | "User has been invited to a team, but has not joined the team yet." 22 | suspended 23 | "User is no longer a member of the team, but the account can be un-suspended, 24 | re-establishing the user as a team member." 25 | removed RemovedStatus 26 | "User is no longer a member of the team. 27 | Removed users are only listed when include_removed is true in members/list." 28 | 29 | struct RemovedStatus 30 | is_recoverable Boolean 31 | "True if the removed team member is recoverable." 32 | 33 | is_disconnected Boolean 34 | "True if the team member's account was converted to individual account." 35 | 36 | example default 37 | is_recoverable = false 38 | is_disconnected = false 39 | 40 | union_closed TeamMembershipType 41 | full 42 | "User uses a license and has full access to team resources like the shared quota." 43 | limited 44 | "User does not have access to the shared quota and team admins have restricted administrative control." 45 | 46 | struct MemberProfile 47 | "Basic member profile." 48 | 49 | team_member_id team_common.TeamMemberId 50 | "ID of user as a member of a team." 51 | 52 | external_id String? 53 | "External ID that a team can attach to the user. 54 | An application using the API may find it easier to use their 55 | own IDs instead of Dropbox IDs like account_id or team_member_id." 56 | 57 | account_id users_common.AccountId? 58 | "A user's account identifier." 59 | 60 | email String 61 | "Email address of user." 62 | 63 | email_verified Boolean 64 | "Is true if the user's email is verified to be owned by the user." 65 | 66 | secondary_emails List(secondary_emails.SecondaryEmail)? 67 | "Secondary emails of a user." 68 | 69 | status TeamMemberStatus 70 | "The user's status as a member of a specific team." 71 | 72 | name users.Name 73 | "Representations for a person's name." 74 | 75 | membership_type TeamMembershipType 76 | "The user's membership type: full (normal team member) vs limited (does not use a license; no access to the team's shared quota)." 77 | 78 | invited_on common.DropboxTimestamp? 79 | "The date and time the user was invited to the team (contains value only when the member's status matches :field:`TeamMemberStatus.invited`)." 80 | 81 | joined_on common.DropboxTimestamp? 82 | "The date and time the user joined as a member of a specific team." 83 | 84 | suspended_on common.DropboxTimestamp? 85 | "The date and time the user was suspended from the team (contains value only when the member's status matches :field:`TeamMemberStatus.suspended`)." 86 | 87 | persistent_id String? 88 | "Persistent ID that a team can attach to the user. 89 | The persistent ID is unique ID to be used for SAML authentication." 90 | 91 | is_directory_restricted Boolean? 92 | "Whether the user is a directory restricted user." 93 | 94 | profile_photo_url String? 95 | "URL for the photo representing the user, if one is set." 96 | 97 | example default 98 | team_member_id = "dbmid:1234567" 99 | account_id = "dbid:AAH4f99T0taONIb-OurWxbNQ6ywGRopQngc" 100 | email = "mary@lamb.com" 101 | email_verified = true 102 | secondary_emails = [default, second_sec_email, third_sec_email] 103 | status = active 104 | name = default 105 | membership_type = full 106 | joined_on = "2015-05-12T15:50:38Z" 107 | profile_photo_url = "https://dl-web.dropbox.com/account_photo/get/dbaphid%3AAAHWGmIXV3sUuOmBfTz0wPsiqHUpBWvv3ZA?vers=1556069330102&size=128x128" 108 | 109 | union_closed UserSelectorArg 110 | "Argument for selecting a single user, either by team_member_id, external_id or email." 111 | 112 | team_member_id team_common.TeamMemberId 113 | external_id team_common.MemberExternalId 114 | email common.EmailAddress 115 | 116 | example default 117 | team_member_id = "dbmid:efgh5678" 118 | 119 | example email 120 | email = "dan@hotmail.com" 121 | 122 | union_closed UserSelectorError 123 | "Error that can be returned whenever a struct derived from :type:`UserSelectorArg` is used." 124 | 125 | user_not_found 126 | "No matching user found. The provided team_member_id, email, or external_id does not exist on this team." 127 | 128 | union_closed UsersSelectorArg 129 | "Argument for selecting a list of users, either by team_member_ids, external_ids or emails." 130 | 131 | team_member_ids List(team_common.TeamMemberId) 132 | "List of member IDs." 133 | external_ids List(team_common.MemberExternalId) 134 | "List of external user IDs." 135 | emails List(common.EmailAddress) 136 | "List of email addresses." 137 | 138 | 139 | 140 | # 141 | # Handle DfB routes that do not have a better place to be. 142 | # 143 | 144 | # 145 | # Route get_info 146 | # 147 | 148 | struct TeamGetInfoResult 149 | 150 | name String 151 | "The name of the team." 152 | 153 | team_id String 154 | "The ID of the team." 155 | 156 | num_licensed_users UInt32 157 | "The number of licenses available to the team." 158 | 159 | num_provisioned_users UInt32 160 | "The number of accounts that have been invited or are already active members of the team." 161 | 162 | num_used_licenses UInt32 = 0 163 | "The number of licenses used on the team." 164 | 165 | policies team_policies.TeamMemberPolicies 166 | 167 | example default 168 | name="Dropbox Inc." 169 | team_id="dbtid:1234abcd" 170 | num_licensed_users=5 171 | num_provisioned_users=2 172 | num_used_licenses=1 173 | policies=default 174 | 175 | route get_info(Void, TeamGetInfoResult, Void) 176 | "Retrieves information about a team." 177 | 178 | attrs 179 | auth = "team" 180 | scope = "team_info.read" 181 | 182 | 183 | # 184 | # Structs for token/get_authenticated_admin 185 | # 186 | 187 | struct TokenGetAuthenticatedAdminResult 188 | "Results for :route:`token/get_authenticated_admin`." 189 | 190 | admin_profile TeamMemberProfile 191 | "The admin who authorized the token." 192 | 193 | example default 194 | admin_profile = default 195 | 196 | union TokenGetAuthenticatedAdminError 197 | "Error returned by :route:`token/get_authenticated_admin`." 198 | 199 | mapping_not_found 200 | "The current token is not associated with a team admin, because mappings were not 201 | recorded when the token was created. Consider re-authorizing a new access token 202 | to record its authenticating admin." 203 | admin_not_active 204 | "Either the team admin that authorized this token is no longer an active member of the 205 | team or no longer a team admin." 206 | 207 | # 208 | # Route: token/get_authenticated_admin 209 | # 210 | 211 | route token/get_authenticated_admin(Void, TokenGetAuthenticatedAdminResult, TokenGetAuthenticatedAdminError) 212 | "Returns the member profile of the admin who generated the team access token used to make the call." 213 | 214 | attrs 215 | auth = "team" 216 | scope = "team_info.read" 217 | 218 | # 219 | # Common types 220 | # 221 | 222 | union Feature 223 | "A set of features that a Dropbox Business account may support." 224 | 225 | upload_api_rate_limit 226 | "The number of upload API calls allowed per month." 227 | has_team_shared_dropbox 228 | "Does this team have a shared team root." 229 | has_team_file_events 230 | "Does this team have file events." 231 | has_team_selective_sync 232 | "Does this team have team selective sync enabled." 233 | 234 | union FeatureValue 235 | "The values correspond to entries in :type:`Feature`. You may get different value according 236 | to your Dropbox Business plan." 237 | 238 | upload_api_rate_limit UploadApiRateLimitValue 239 | has_team_shared_dropbox HasTeamSharedDropboxValue 240 | has_team_file_events HasTeamFileEventsValue 241 | has_team_selective_sync HasTeamSelectiveSyncValue 242 | 243 | example uploadRateLimited 244 | upload_api_rate_limit = limited 245 | 246 | example hasTeamSharedDropbox 247 | has_team_shared_dropbox = default 248 | 249 | example hasTeamFileEvents 250 | has_team_file_events = ex_no_file_events 251 | 252 | example HasTeamSelectiveSync 253 | has_team_selective_sync = default 254 | 255 | union UploadApiRateLimitValue 256 | "The value for :field:`Feature.upload_api_rate_limit`." 257 | 258 | unlimited 259 | "This team has unlimited upload API quota. So far both server version account and legacy 260 | account type have unlimited monthly upload api quota." 261 | limit UInt32 262 | "The number of upload API calls allowed per month." 263 | 264 | example limited 265 | limit = 25000 266 | 267 | union HasTeamSharedDropboxValue 268 | "The value for :field:`Feature.has_team_shared_dropbox`." 269 | 270 | has_team_shared_dropbox Boolean 271 | "Does this team have a shared team root." 272 | 273 | example default 274 | has_team_shared_dropbox = false 275 | 276 | union HasTeamFileEventsValue 277 | "The value for :field:`Feature.has_team_file_events`." 278 | 279 | enabled Boolean 280 | "Does this team have file events." 281 | 282 | example ex_no_file_events 283 | enabled = false 284 | 285 | union HasTeamSelectiveSyncValue 286 | "The value for :field:`Feature.has_team_selective_sync`." 287 | 288 | has_team_selective_sync Boolean 289 | "Does this team have team selective sync enabled." 290 | 291 | example default 292 | has_team_selective_sync = true 293 | 294 | # 295 | # Route: feature/get_value_batch 296 | # 297 | 298 | struct FeaturesGetValuesBatchArg 299 | features List(Feature) 300 | "A list of features in :type:`Feature`. If the list is empty, 301 | this route will return :type:`FeaturesGetValuesBatchError`." 302 | 303 | example listOfValues 304 | features = [upload_api_rate_limit, has_team_shared_dropbox] 305 | 306 | struct FeaturesGetValuesBatchResult 307 | values List(FeatureValue) 308 | 309 | example listOfResults 310 | values = [uploadRateLimited, hasTeamSharedDropbox] 311 | 312 | union FeaturesGetValuesBatchError 313 | empty_features_list 314 | "At least one :type:`Feature` must be included in the 315 | :type:`FeaturesGetValuesBatchArg`.features list." 316 | 317 | route features/get_values(FeaturesGetValuesBatchArg, FeaturesGetValuesBatchResult, FeaturesGetValuesBatchError) 318 | "Get the values for one or more featues. This route allows you to check your account's 319 | capability for what feature you can access or what value you have for certain features. 320 | 321 | Permission : Team information." 322 | 323 | attrs 324 | auth = "team" 325 | scope = "team_info.read" 326 | 327 | # 328 | # Deprecated File Properties Routes 329 | # 330 | 331 | route properties/template/add(file_properties.AddTemplateArg, file_properties.AddTemplateResult, file_properties.ModifyTemplateError) deprecated 332 | "Permission : Team member file access." 333 | 334 | attrs 335 | auth = "team" 336 | scope = "files.team_metadata.write" 337 | 338 | route properties/template/update(file_properties.UpdateTemplateArg, file_properties.UpdateTemplateResult, file_properties.ModifyTemplateError) deprecated 339 | "Permission : Team member file access." 340 | attrs 341 | auth = "team" 342 | scope = "files.team_metadata.write" 343 | 344 | route properties/template/get(file_properties.GetTemplateArg, file_properties.GetTemplateResult, file_properties.TemplateError) deprecated 345 | "Permission : Team member file access. The scope for the route is files.team_metadata.write." 346 | attrs 347 | auth = "team" 348 | scope = "files.team_metadata.write" 349 | 350 | route properties/template/list(Void, file_properties.ListTemplateResult, file_properties.TemplateError) deprecated 351 | "Permission : Team member file access. The scope for the route is files.team_metadata.write." 352 | attrs 353 | auth = "team" 354 | scope = "files.team_metadata.write" 355 | -------------------------------------------------------------------------------- /team_common.stone: -------------------------------------------------------------------------------- 1 | namespace team_common 2 | 3 | import common 4 | 5 | alias TeamMemberId = String 6 | alias MemberExternalId = String(max_length=64) 7 | alias GroupExternalId = String 8 | 9 | alias GroupId = String 10 | alias ResellerId = String 11 | alias TeamId = String 12 | 13 | struct GroupSummary 14 | "Information about a group." 15 | 16 | group_name String 17 | group_id GroupId 18 | group_external_id GroupExternalId? 19 | "External ID of group. This is an arbitrary ID that an admin can attach to a group." 20 | member_count UInt32? 21 | "The number of members in the group." 22 | group_management_type GroupManagementType 23 | "Who is allowed to manage the group." 24 | 25 | example default 26 | group_name = "Test group" 27 | group_id = "g:e2db7665347abcd600000000001a2b3c" 28 | member_count = 10 29 | group_management_type = user_managed 30 | 31 | 32 | union GroupManagementType 33 | "The group type determines how a group is managed." 34 | 35 | user_managed 36 | "A group which is managed by selected users." 37 | company_managed 38 | "A group which is managed by team admins only." 39 | system_managed 40 | "A group which is managed automatically by Dropbox." 41 | 42 | 43 | union GroupType 44 | "The group type determines how a group is created and managed." 45 | 46 | team 47 | "A group to which team members are automatically added. Applicable to 48 | :link:`team folders https://www.dropbox.com/help/986` only." 49 | user_managed 50 | "A group is created and managed by a user." 51 | 52 | struct TimeRange 53 | "Time range." 54 | start_time common.DropboxTimestamp? 55 | "Optional starting time (inclusive)." 56 | end_time common.DropboxTimestamp? 57 | "Optional ending time (exclusive)." 58 | 59 | 60 | union MemberSpaceLimitType 61 | "The type of the space limit imposed on a team member." 62 | 63 | off 64 | "The team member does not have imposed space limit." 65 | alert_only 66 | "The team member has soft imposed space limit - the limit is used for display and 67 | for notifications." 68 | stop_sync 69 | "The team member has hard imposed space limit - Dropbox file sync will stop after 70 | the limit is reached." 71 | -------------------------------------------------------------------------------- /team_devices.stone: -------------------------------------------------------------------------------- 1 | namespace team 2 | 3 | import common 4 | 5 | # 6 | # Structs for devices/list_member_devices 7 | # 8 | 9 | struct ListMemberDevicesArg 10 | team_member_id String 11 | "The team's member id." 12 | include_web_sessions Boolean = true 13 | "Whether to list web sessions of the team's member." 14 | include_desktop_clients Boolean = true 15 | "Whether to list linked desktop devices of the team's member." 16 | include_mobile_clients Boolean = true 17 | "Whether to list linked mobile devices of the team's member." 18 | 19 | example default 20 | team_member_id="dbmid:AAFdgehTzw7WlXhZJsbGCLePe8RvQGYDr-I" 21 | 22 | struct DeviceSession 23 | session_id String 24 | "The session id." 25 | 26 | ip_address String? 27 | "The IP address of the last activity from this session." 28 | 29 | country String? 30 | "The country from which the last activity from this session was made." 31 | 32 | created common.DropboxTimestamp? 33 | "The time this session was created." 34 | 35 | updated common.DropboxTimestamp? 36 | "The time of the last activity from this session." 37 | 38 | # TODO(gal) - for mobile, camera uploads don't count for updated activity (See T25556 39 | # for more context). This needs to be documented somewhere. 40 | 41 | struct ActiveWebSession extends DeviceSession 42 | "Information on active web sessions." 43 | 44 | user_agent String 45 | "Information on the hosting device." 46 | 47 | os String 48 | "Information on the hosting operating system." 49 | 50 | browser String 51 | "Information on the browser used for this web session." 52 | 53 | expires common.DropboxTimestamp? 54 | "The time this session expires." 55 | 56 | example default 57 | session_id = "dbwsid:AAFdgehTzw7WlXhZJsbGCLePe8RvQGYDr-I" 58 | ip_address = "3.3.3.3" 59 | country = "United States" 60 | created = "2015-05-12T15:50:38Z" 61 | updated = "2015-05-12T15:51:22Z" 62 | user_agent = "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/14.0.815.0 Safari/535.1" 63 | os = "Windows" 64 | browser = "Chrome" 65 | expires = "2015-05-13T15:51:22Z" 66 | 67 | union DesktopPlatform 68 | windows 69 | "Official Windows Dropbox desktop client." 70 | mac 71 | "Official Mac Dropbox desktop client." 72 | linux 73 | "Official Linux Dropbox desktop client." 74 | 75 | struct DesktopClientSession extends DeviceSession 76 | "Information about linked Dropbox desktop client sessions." 77 | 78 | host_name String 79 | "Name of the hosting desktop." 80 | 81 | client_type DesktopPlatform 82 | "The Dropbox desktop client type." 83 | 84 | client_version String 85 | "The Dropbox client version." 86 | 87 | platform String 88 | "Information on the hosting platform." 89 | 90 | is_delete_on_unlink_supported Boolean 91 | "Whether it's possible to delete all of the account files upon unlinking." 92 | 93 | example default 94 | session_id= "dbdsid:AAFdgehTzw7WlXhZJsbGCLePe8RvQGYDr-I" 95 | ip_address = "3.3.3.3" 96 | country = "United States" 97 | created = "2015-05-12T15:50:38Z" 98 | updated = "2015-05-12T15:51:22Z" 99 | host_name = "Home_desktop" 100 | client_type = mac 101 | client_version = "3.9.19" 102 | platform = "Mac OS X 10.10.3" 103 | is_delete_on_unlink_supported = true 104 | 105 | union MobileClientPlatform 106 | iphone 107 | "Official Dropbox iPhone client." 108 | ipad 109 | "Official Dropbox iPad client." 110 | android 111 | "Official Dropbox Android client." 112 | windows_phone 113 | "Official Dropbox Windows phone client." 114 | blackberry 115 | "Official Dropbox Blackberry client." 116 | 117 | struct MobileClientSession extends DeviceSession 118 | "Information about linked Dropbox mobile client sessions." 119 | 120 | device_name String 121 | "The device name." 122 | 123 | client_type MobileClientPlatform 124 | "The mobile application type." 125 | 126 | client_version String? 127 | "The dropbox client version." 128 | 129 | os_version String? 130 | "The hosting OS version." 131 | 132 | last_carrier String? 133 | "last carrier used by the device." 134 | 135 | example default 136 | session_id = "dbmsid:AAFdgehTzw7WlXhZJsbGCLePe8RvQGYDr-I" 137 | ip_address = "3.3.3.3" 138 | country = "United States" 139 | created = "2015-05-12T15:50:38Z" 140 | updated = "2015-05-12T15:51:22Z" 141 | device_name = "Iphone 6" 142 | client_type = iphone 143 | client_version = "3.9.5" 144 | os_version = "8.4" 145 | last_carrier = "Verizon" 146 | 147 | struct ListMemberDevicesResult 148 | active_web_sessions List(ActiveWebSession)? 149 | "List of web sessions made by this team member." 150 | desktop_client_sessions List(DesktopClientSession)? 151 | "List of desktop clients used by this team member." 152 | mobile_client_sessions List(MobileClientSession)? 153 | "List of mobile client used by this team member." 154 | 155 | union ListMemberDevicesError 156 | member_not_found 157 | "Member not found." 158 | 159 | # 160 | # Route: devices/list_member_devices 161 | # 162 | 163 | route devices/list_member_devices(ListMemberDevicesArg, ListMemberDevicesResult, ListMemberDevicesError) 164 | "List all device sessions of a team's member." 165 | 166 | attrs 167 | auth = "team" 168 | scope = "sessions.list" 169 | 170 | # 171 | # Structs for devices/list_members_devices 172 | # 173 | 174 | struct ListMembersDevicesArg 175 | cursor String? 176 | "At the first call to the :route:`devices/list_members_devices` the cursor shouldn't be passed. 177 | Then, if the result of the call includes a cursor, the following requests should include the 178 | received cursors in order to receive the next sub list of team devices." 179 | include_web_sessions Boolean = true 180 | "Whether to list web sessions of the team members." 181 | include_desktop_clients Boolean = true 182 | "Whether to list desktop clients of the team members." 183 | include_mobile_clients Boolean = true 184 | "Whether to list mobile clients of the team members." 185 | 186 | struct MemberDevices 187 | "Information on devices of a team's member." 188 | 189 | team_member_id String 190 | "The member unique Id." 191 | web_sessions List(ActiveWebSession)? 192 | "List of web sessions made by this team member." 193 | desktop_clients List(DesktopClientSession)? 194 | "List of desktop clients by this team member." 195 | mobile_clients List(MobileClientSession)? 196 | "List of mobile clients by this team member." 197 | 198 | example default 199 | team_member_id = "dbmid:AAHhy7WsR0x-u4ZCqiDl5Fz5zvuL3kmspwU" 200 | 201 | struct ListMembersDevicesResult 202 | devices List(MemberDevices) 203 | "The devices of each member of the team." 204 | has_more Boolean 205 | "If true, then there are more devices available. Pass the 206 | cursor to :route:`devices/list_members_devices` to retrieve the rest." 207 | cursor String? 208 | "Pass the cursor into :route:`devices/list_members_devices` to receive the next 209 | sub list of team's devices." 210 | 211 | union ListMembersDevicesError 212 | reset 213 | "Indicates that the cursor has been invalidated. Call 214 | :route:`devices/list_members_devices` again with an empty cursor to obtain a new cursor." 215 | 216 | # 217 | # Route: devices/list_members_devices 218 | # 219 | route devices/list_members_devices(ListMembersDevicesArg, ListMembersDevicesResult, ListMembersDevicesError) 220 | "List all device sessions of a team. 221 | 222 | Permission : Team member file access." 223 | 224 | attrs 225 | auth = "team" 226 | scope = "sessions.list" 227 | 228 | # 229 | # Structs for devices/revoke_device_session 230 | # 231 | 232 | struct DeviceSessionArg 233 | session_id String 234 | "The session id." 235 | team_member_id String 236 | "The unique id of the member owning the device." 237 | 238 | example default 239 | session_id = "1234faaf0678bcde" 240 | team_member_id = "dbmid:AAHhy7WsR0x-u4ZCqiDl5Fz5zvuL3kmspwU" 241 | 242 | struct RevokeDesktopClientArg extends DeviceSessionArg 243 | delete_on_unlink Boolean = false 244 | "Whether to delete all files of the account (this is possible only if supported by 245 | the desktop client and will be made the next time the client access the account)." 246 | 247 | example default 248 | session_id = "1234faaf0678bcde" 249 | team_member_id = "dbmid:AAHhy7WsR0x-u4ZCqiDl5Fz5zvuL3kmspwU" 250 | 251 | union_closed RevokeDeviceSessionArg 252 | web_session DeviceSessionArg 253 | "End an active session." 254 | desktop_client RevokeDesktopClientArg 255 | "Unlink a linked desktop device." 256 | mobile_client DeviceSessionArg 257 | "Unlink a linked mobile device." 258 | 259 | example default 260 | web_session = default 261 | 262 | union RevokeDeviceSessionError 263 | device_session_not_found 264 | "Device session not found." 265 | member_not_found 266 | "Member not found." 267 | 268 | # 269 | # Route: devices/revoke_device_session 270 | # 271 | 272 | route devices/revoke_device_session(RevokeDeviceSessionArg, Void, RevokeDeviceSessionError) 273 | "Revoke a device session of a team's member." 274 | 275 | attrs 276 | auth = "team" 277 | scope = "sessions.modify" 278 | 279 | # 280 | # structs for devices/revoke_device_session_batch 281 | # 282 | 283 | struct RevokeDeviceSessionBatchArg 284 | revoke_devices List(RevokeDeviceSessionArg) 285 | 286 | example default 287 | revoke_devices = [default] 288 | 289 | struct RevokeDeviceSessionStatus 290 | 291 | success Boolean 292 | "Result of the revoking request." 293 | error_type RevokeDeviceSessionError? 294 | "The error cause in case of a failure." 295 | 296 | struct RevokeDeviceSessionBatchResult 297 | revoke_devices_status List(RevokeDeviceSessionStatus) 298 | 299 | union RevokeDeviceSessionBatchError 300 | "" 301 | 302 | # 303 | # Route: devices/revoke_device_session_batch 304 | # 305 | 306 | route devices/revoke_device_session_batch(RevokeDeviceSessionBatchArg, RevokeDeviceSessionBatchResult, RevokeDeviceSessionBatchError) 307 | "Revoke a list of device sessions of team members." 308 | 309 | attrs 310 | auth = "team" 311 | scope = "sessions.modify" 312 | 313 | 314 | # 315 | # Deprecated endpoints 316 | # 317 | 318 | struct ListTeamDevicesArg 319 | cursor String? 320 | "At the first call to the :route:`devices/list_team_devices` the cursor shouldn't be passed. 321 | Then, if the result of the call includes a cursor, the following requests should include the 322 | received cursors in order to receive the next sub list of team devices." 323 | include_web_sessions Boolean = true 324 | "Whether to list web sessions of the team members." 325 | include_desktop_clients Boolean = true 326 | "Whether to list desktop clients of the team members." 327 | include_mobile_clients Boolean = true 328 | "Whether to list mobile clients of the team members." 329 | 330 | example default 331 | cursor = "ZtkX9_EHj3x7PMkVuFIhwKYXEpwpLwyxp9vMKomUhllil9q7eWiAu" 332 | 333 | struct ListTeamDevicesResult 334 | devices List(MemberDevices) 335 | "The devices of each member of the team." 336 | has_more Boolean 337 | "If true, then there are more devices available. Pass the 338 | cursor to :route:`devices/list_team_devices` to retrieve the rest." 339 | cursor String? 340 | "Pass the cursor into :route:`devices/list_team_devices` to receive the next 341 | sub list of team's devices." 342 | 343 | example default 344 | devices = [default] 345 | has_more = false 346 | 347 | union ListTeamDevicesError 348 | reset 349 | "Indicates that the cursor has been invalidated. Call 350 | :route:`devices/list_team_devices` again with an empty cursor to obtain a new cursor." 351 | 352 | route devices/list_team_devices(ListTeamDevicesArg, ListTeamDevicesResult, ListTeamDevicesError) deprecated by devices/list_members_devices 353 | "List all device sessions of a team. 354 | 355 | Permission : Team member file access." 356 | 357 | attrs 358 | auth = "team" 359 | scope = "sessions.list" 360 | -------------------------------------------------------------------------------- /team_folders.stone: -------------------------------------------------------------------------------- 1 | namespace team 2 | 3 | import async 4 | import common 5 | import files 6 | 7 | # Common structs 8 | 9 | union TeamFolderStatus 10 | active 11 | "The team folder and sub-folders are available to all members." 12 | archived 13 | "The team folder is not accessible outside of the team folder manager." 14 | archive_in_progress 15 | "The team folder is not accessible outside of the team folder manager." 16 | 17 | struct TeamFolderIdArg 18 | team_folder_id common.SharedFolderId 19 | "The ID of the team folder." 20 | 21 | example default 22 | team_folder_id = "123456789" 23 | 24 | struct TeamFolderIdListArg 25 | team_folder_ids List(common.SharedFolderId, min_items=1) 26 | "The list of team folder IDs." 27 | 28 | example default 29 | team_folder_ids = ["947182", "5819424", "852307532"] 30 | 31 | struct TeamFolderMetadata 32 | "Properties of a team folder." 33 | 34 | team_folder_id common.SharedFolderId 35 | "The ID of the team folder." 36 | 37 | name String 38 | "The name of the team folder." 39 | 40 | status TeamFolderStatus 41 | "The status of the team folder." 42 | 43 | is_team_shared_dropbox Boolean 44 | "True if this team folder is a shared team root." 45 | 46 | sync_setting files.SyncSetting 47 | "The sync setting applied to this team folder." 48 | 49 | content_sync_settings List(files.ContentSyncSetting) 50 | "Sync settings applied to contents of this team folder." 51 | 52 | example default 53 | name = "Marketing" 54 | team_folder_id = "123456789" 55 | status = active 56 | is_team_shared_dropbox = false 57 | sync_setting = default 58 | content_sync_settings = [default] 59 | 60 | union TeamFolderAccessError 61 | invalid_team_folder_id 62 | "The team folder ID is invalid." 63 | no_access 64 | "The authenticated app does not have permission to manage that team folder." 65 | 66 | union TeamFolderInvalidStatusError 67 | active 68 | "The folder is active and the operation did not succeed." 69 | archived 70 | "The folder is archived and the operation did not succeed." 71 | archive_in_progress 72 | "The folder is being archived and the operation did not succeed." 73 | 74 | union TeamFolderTeamSharedDropboxError 75 | disallowed 76 | "This action is not allowed for a shared team root." 77 | 78 | union BaseTeamFolderError 79 | "Base error that all errors for existing team folders should extend." 80 | access_error TeamFolderAccessError 81 | status_error TeamFolderInvalidStatusError 82 | team_shared_dropbox_error TeamFolderTeamSharedDropboxError 83 | 84 | # 85 | # Team folder create 86 | # 87 | 88 | route team_folder/create(TeamFolderCreateArg, TeamFolderMetadata, TeamFolderCreateError) 89 | "Creates a new, active, team folder with no members. This endpoint can only be used for teams 90 | that do not already have a shared team space. 91 | 92 | Permission : Team member file access." 93 | 94 | attrs 95 | auth = "team" 96 | scope = "team_data.content.write" 97 | 98 | struct TeamFolderCreateArg 99 | name String 100 | "Name for the new team folder." 101 | 102 | sync_setting files.SyncSettingArg? 103 | "The sync setting to apply to this team folder. Only permitted if the team has team selective sync enabled." 104 | 105 | example default 106 | name = "Marketing" 107 | sync_setting = not_synced 108 | 109 | union TeamFolderCreateError 110 | invalid_folder_name 111 | "The provided name cannot be used." 112 | folder_name_already_used 113 | "There is already a team folder with the provided name." 114 | folder_name_reserved 115 | "The provided name cannot be used because it is reserved." 116 | sync_settings_error files.SyncSettingsError 117 | "An error occurred setting the sync settings." 118 | 119 | # 120 | # Team folder rename 121 | # 122 | 123 | route team_folder/rename(TeamFolderRenameArg, TeamFolderMetadata, TeamFolderRenameError) 124 | "Changes an active team folder's name. 125 | 126 | Permission : Team member file access." 127 | 128 | attrs 129 | auth = "team" 130 | scope = "team_data.content.write" 131 | 132 | struct TeamFolderRenameArg extends TeamFolderIdArg 133 | name String 134 | "New team folder name." 135 | 136 | example default 137 | team_folder_id = "123456789" 138 | name = "Sales" 139 | 140 | union TeamFolderRenameError extends BaseTeamFolderError 141 | invalid_folder_name 142 | "The provided folder name cannot be used." 143 | folder_name_already_used 144 | "There is already a team folder with the same name." 145 | folder_name_reserved 146 | "The provided name cannot be used because it is reserved." 147 | 148 | # 149 | # Team folder list 150 | # 151 | 152 | route team_folder/list(TeamFolderListArg, TeamFolderListResult, TeamFolderListError) 153 | "Lists all team folders. 154 | 155 | Permission : Team member file access." 156 | attrs 157 | auth = "team" 158 | scope = "team_data.content.read" 159 | 160 | struct TeamFolderListArg 161 | limit UInt32(min_value=1, max_value=1000) = 1000 162 | "The maximum number of results to return per request." 163 | 164 | example default 165 | limit = 100 166 | 167 | struct TeamFolderListResult 168 | "Result for :route:`team_folder/list` and :route:`team_folder/list/continue`." 169 | 170 | team_folders List(TeamFolderMetadata) 171 | "List of all team folders in the authenticated team." 172 | cursor String 173 | "Pass the cursor into :route:`team_folder/list/continue` to obtain additional team folders." 174 | has_more Boolean 175 | "Is true if there are additional team folders that have not been returned 176 | yet. An additional call to :route:`team_folder/list/continue` can retrieve them." 177 | 178 | example default 179 | team_folders = [default] 180 | cursor = "ZtkX9_EHj3x7PMkVuFIhwKYXEpwpLwyxp9vMKomUhllil9q7eWiAu" 181 | has_more = false 182 | 183 | struct TeamFolderListError 184 | access_error TeamFolderAccessError 185 | 186 | # 187 | # Team folder list/continue 188 | # 189 | 190 | route team_folder/list/continue(TeamFolderListContinueArg, TeamFolderListResult, TeamFolderListContinueError) 191 | "Once a cursor has been retrieved from :route:`team_folder/list`, use this to paginate 192 | through all team folders. 193 | 194 | Permission : Team member file access." 195 | 196 | attrs 197 | auth = "team" 198 | scope = "team_data.content.read" 199 | 200 | struct TeamFolderListContinueArg 201 | cursor String 202 | "Indicates from what point to get the next set of team folders." 203 | 204 | example default 205 | cursor = "ZtkX9_EHj3x7PMkVuFIhwKYXEpwpLwyxp9vMKomUhllil9q7eWiAu" 206 | 207 | union TeamFolderListContinueError 208 | invalid_cursor 209 | "The cursor is invalid." 210 | 211 | # 212 | # Team folder get info 213 | # 214 | 215 | route team_folder/get_info(TeamFolderIdListArg, List(TeamFolderGetInfoItem), Void) 216 | "Retrieves metadata for team folders. 217 | 218 | Permission : Team member file access." 219 | 220 | attrs 221 | auth = "team" 222 | scope = "team_data.content.read" 223 | 224 | union_closed TeamFolderGetInfoItem 225 | id_not_found String 226 | "An ID that was provided as a parameter to :route:`team_folder/get_info` did not 227 | match any of the team's team folders." 228 | team_folder_metadata TeamFolderMetadata 229 | "Properties of a team folder." 230 | 231 | # 232 | # Team folder activate 233 | # 234 | 235 | route team_folder/activate(TeamFolderIdArg, TeamFolderMetadata, TeamFolderActivateError) 236 | "Sets an archived team folder's status to active. 237 | 238 | Permission : Team member file access." 239 | 240 | attrs 241 | auth = "team" 242 | scope = "team_data.content.write" 243 | 244 | union TeamFolderActivateError extends BaseTeamFolderError 245 | "" 246 | 247 | # 248 | # Team folder archive 249 | # 250 | 251 | route team_folder/archive(TeamFolderArchiveArg, TeamFolderArchiveLaunch, TeamFolderArchiveError) 252 | "Sets an active team folder's status to archived and removes all folder and file members. 253 | This endpoint cannot be used for teams that have a shared team space. 254 | 255 | Permission : Team member file access." 256 | 257 | attrs 258 | auth = "team" 259 | scope = "team_data.content.write" 260 | 261 | struct TeamFolderArchiveArg extends TeamFolderIdArg 262 | force_async_off Boolean = false 263 | "Whether to force the archive to happen synchronously." 264 | 265 | example default 266 | team_folder_id = "123456789" 267 | force_async_off = false 268 | 269 | union_closed TeamFolderArchiveLaunch extends async.LaunchResultBase 270 | complete TeamFolderMetadata 271 | 272 | example default 273 | complete = default 274 | 275 | example async_job_id 276 | async_job_id = "34g93hh34h04y384084" 277 | 278 | union TeamFolderArchiveError extends BaseTeamFolderError 279 | "" 280 | 281 | route team_folder/archive/check(async.PollArg, TeamFolderArchiveJobStatus, async.PollError) 282 | "Returns the status of an asynchronous job for archiving a team folder. 283 | 284 | Permission : Team member file access." 285 | 286 | attrs 287 | auth = "team" 288 | scope = "team_data.content.write" 289 | 290 | union_closed TeamFolderArchiveJobStatus extends async.PollResultBase 291 | complete TeamFolderMetadata 292 | "The archive job has finished. The value is the metadata for the resulting team folder." 293 | failed TeamFolderArchiveError 294 | "Error occurred while performing an asynchronous job from :route:`team_folder/archive`." 295 | 296 | example default 297 | complete = default 298 | 299 | # 300 | # Team folder permanently delete 301 | # 302 | 303 | route team_folder/permanently_delete(TeamFolderIdArg, Void, TeamFolderPermanentlyDeleteError) 304 | "Permanently deletes an archived team folder. This endpoint cannot be used for teams 305 | that have a shared team space. 306 | 307 | Permission : Team member file access." 308 | 309 | attrs 310 | auth = "team" 311 | scope = "team_data.content.write" 312 | 313 | union TeamFolderPermanentlyDeleteError extends BaseTeamFolderError 314 | "" 315 | 316 | # 317 | # Team folder update_sync_settings 318 | # 319 | 320 | struct TeamFolderUpdateSyncSettingsArg extends TeamFolderIdArg 321 | sync_setting files.SyncSettingArg? 322 | "Sync setting to apply to the team folder itself. Only meaningful if the team folder is not a shared team root." 323 | 324 | content_sync_settings List(files.ContentSyncSettingArg)? 325 | "Sync settings to apply to contents of this team folder." 326 | 327 | example default 328 | team_folder_id = "123456789" 329 | sync_setting = default 330 | content_sync_settings = [default] 331 | 332 | union TeamFolderUpdateSyncSettingsError extends BaseTeamFolderError 333 | sync_settings_error files.SyncSettingsError 334 | "An error occurred setting the sync settings." 335 | 336 | route team_folder/update_sync_settings(TeamFolderUpdateSyncSettingsArg, TeamFolderMetadata, TeamFolderUpdateSyncSettingsError) 337 | "Updates the sync settings on a team folder or its contents. Use of this endpoint requires that the team has team selective sync enabled." 338 | 339 | attrs 340 | auth = "team" 341 | scope = "team_data.content.write" 342 | -------------------------------------------------------------------------------- /team_groups.stone: -------------------------------------------------------------------------------- 1 | namespace team 2 | 3 | import async 4 | import team_common 5 | 6 | # 7 | # Common types. 8 | # 9 | 10 | union_closed GroupAccessType 11 | "Role of a user in group." 12 | 13 | member 14 | "User is a member of the group, but has no special permissions." 15 | owner 16 | "User can rename the group, and add/remove members." 17 | 18 | example default 19 | member = null 20 | 21 | union_closed GroupSelector 22 | "Argument for selecting a single group, either by group_id or by external group ID." 23 | 24 | group_id team_common.GroupId 25 | "Group ID." 26 | group_external_id team_common.GroupExternalId 27 | "External ID of the group." 28 | 29 | example default 30 | group_id = "g:e2db7665347abcd600000000001a2b3c" 31 | 32 | union GroupSelectorError 33 | "Error that can be raised when :type:`GroupSelector` is used." 34 | 35 | group_not_found 36 | "No matching group found. No groups match the specified group ID." 37 | 38 | union GroupSelectorWithTeamGroupError extends GroupSelectorError 39 | "Error that can be raised when :type:`GroupSelector` is used and team groups are disallowed from 40 | being used." 41 | 42 | system_managed_group_disallowed 43 | "This operation is not supported on system-managed groups." 44 | 45 | 46 | union_closed GroupsSelector 47 | "Argument for selecting a list of groups, either by group_ids, or external group IDs." 48 | 49 | group_ids List(team_common.GroupId) 50 | "List of group IDs." 51 | group_external_ids List(String) 52 | "List of external IDs of groups." 53 | 54 | example default 55 | group_ids = ["g:e2db7665347abcd600000000001a2b3c", "g:111111147abcd6000000000222222c"] 56 | 57 | 58 | struct GroupMemberSelector 59 | "Argument for selecting a group and a single user." 60 | 61 | group GroupSelector 62 | "Specify a group." 63 | user UserSelectorArg 64 | "Identity of a user that is a member of :field:`group`." 65 | 66 | example default 67 | group = default 68 | user = default 69 | 70 | 71 | union GroupMemberSelectorError extends GroupSelectorWithTeamGroupError 72 | "Error that can be raised when :type:`GroupMemberSelector` is used, and the user 73 | is required to be a member of the specified group." 74 | 75 | member_not_in_group 76 | "The specified user is not a member of this group." 77 | 78 | 79 | struct GroupMembersSelector 80 | "Argument for selecting a group and a list of users." 81 | 82 | group GroupSelector 83 | "Specify a group." 84 | users UsersSelectorArg 85 | "A list of users that are members of :field:`group`." 86 | 87 | 88 | union GroupMembersSelectorError extends GroupSelectorWithTeamGroupError 89 | "Error that can be raised when :type:`GroupMembersSelector` is used, and the users 90 | are required to be members of the specified group." 91 | 92 | member_not_in_group 93 | "At least one of the specified users is not a member of the group." 94 | 95 | 96 | struct IncludeMembersArg 97 | 98 | return_members Boolean = true 99 | "Whether to return the list of members in the group. 100 | Note that the default value will cause all the group members 101 | to be returned in the response. This may take a long time for large groups." 102 | 103 | #################### 104 | # Group Info methods 105 | #################### 106 | 107 | 108 | struct GroupMemberInfo 109 | "Profile of group member, and role in group." 110 | 111 | profile MemberProfile 112 | "Profile of group member." 113 | access_type GroupAccessType 114 | "The role that the user has in the group." 115 | 116 | example default 117 | profile = default 118 | access_type = default 119 | 120 | 121 | struct GroupFullInfo extends team_common.GroupSummary 122 | "Full description of a group." 123 | 124 | members List(GroupMemberInfo)? 125 | "List of group members." 126 | created UInt64 127 | "The group creation time as a UTC timestamp in milliseconds since the Unix epoch." 128 | 129 | example default 130 | group_name = "project launch" 131 | group_id = "g:e2db7665347abcd600000000001a2b3c" 132 | member_count = 5 133 | group_management_type = user_managed 134 | members = [default] 135 | created = 1447255518000 136 | 137 | # 138 | # route groups/list 139 | # 140 | 141 | struct GroupsListArg 142 | limit UInt32(min_value=1, max_value=1000) = 1000 143 | "Number of results to return per call." 144 | 145 | example default 146 | limit = 100 147 | 148 | 149 | struct GroupsListResult 150 | groups List(team_common.GroupSummary) 151 | cursor String 152 | "Pass the cursor into :route:`groups/list/continue` to obtain the additional groups." 153 | has_more Boolean 154 | "Is true if there are additional groups that have not been returned 155 | yet. An additional call to :route:`groups/list/continue` can retrieve them." 156 | 157 | example default 158 | groups = [default] 159 | cursor = "ZtkX9_EHj3x7PMkVuFIhwKYXEpwpLwyxp9vMKomUhllil9q7eWiAu" 160 | has_more = false 161 | 162 | route groups/list(GroupsListArg, GroupsListResult, Void) 163 | "Lists groups on a team. 164 | 165 | Permission : Team Information." 166 | 167 | attrs 168 | auth = "team" 169 | scope = "groups.read" 170 | 171 | # 172 | # route groups/list/continue 173 | # 174 | 175 | struct GroupsListContinueArg 176 | cursor String 177 | "Indicates from what point to get the next set of groups." 178 | 179 | example default 180 | cursor = "ZtkX9_EHj3x7PMkVuFIhwKYXEpwpLwyxp9vMKomUhllil9q7eWiAu" 181 | 182 | union GroupsListContinueError 183 | invalid_cursor 184 | "The cursor is invalid." 185 | 186 | route groups/list/continue(GroupsListContinueArg, GroupsListResult, GroupsListContinueError) 187 | "Once a cursor has been retrieved from :route:`groups/list`, use this to paginate 188 | through all groups. 189 | 190 | Permission : Team Information." 191 | 192 | attrs 193 | auth = "team" 194 | scope = "groups.read" 195 | 196 | # 197 | # route groups/get_info 198 | # 199 | 200 | union_closed GroupsGetInfoItem 201 | id_not_found String 202 | "An ID that was provided as a parameter to :route:`groups/get_info`, and 203 | did not match a corresponding group. The ID can be a group ID, or an external ID, 204 | depending on how the method was called." 205 | group_info GroupFullInfo 206 | "Info about a group." 207 | 208 | example default 209 | group_info = default 210 | 211 | 212 | alias GroupsGetInfoResult = List(GroupsGetInfoItem) 213 | 214 | 215 | union GroupsGetInfoError 216 | group_not_on_team 217 | "The group is not on your team." 218 | 219 | route groups/get_info(GroupsSelector, GroupsGetInfoResult, GroupsGetInfoError) 220 | "Retrieves information about one or more groups. Note that the optional field 221 | :field:`GroupFullInfo.members` is not returned for system-managed groups. 222 | 223 | Permission : Team Information." 224 | 225 | attrs 226 | auth = "team" 227 | scope = "groups.read" 228 | 229 | ########################## 230 | # Group management methods 231 | ########################## 232 | 233 | 234 | # 235 | # route groups/create 236 | # 237 | 238 | struct GroupCreateArg 239 | group_name String 240 | "Group name." 241 | add_creator_as_owner Boolean = false 242 | "Automatically add the creator of the group." 243 | group_external_id team_common.GroupExternalId? 244 | "The creator of a team can associate an arbitrary external ID to the group." 245 | group_management_type team_common.GroupManagementType? 246 | "Whether the team can be managed by selected users, or only by team admins." 247 | 248 | example default 249 | group_name = "Europe sales" 250 | group_external_id = "group-134" 251 | 252 | union GroupCreateError 253 | group_name_already_used 254 | "The requested group name is already being used by another group." 255 | group_name_invalid 256 | "Group name is empty or has invalid characters." 257 | external_id_already_in_use 258 | "The requested external ID is already being used by another group." 259 | system_managed_group_disallowed 260 | "System-managed group cannot be manually created." 261 | 262 | 263 | route groups/create(GroupCreateArg, GroupFullInfo, GroupCreateError) 264 | "Creates a new, empty group, with a requested name. 265 | 266 | Permission : Team member management." 267 | 268 | attrs 269 | auth = "team" 270 | scope = "groups.write" 271 | 272 | # 273 | # route groups/delete (async method) 274 | # 275 | 276 | union GroupDeleteError extends GroupSelectorWithTeamGroupError 277 | group_already_deleted 278 | "This group has already been deleted." 279 | 280 | 281 | route groups/delete(GroupSelector, async.LaunchEmptyResult, GroupDeleteError) 282 | "Deletes a group. 283 | 284 | The group is deleted immediately. However the revoking of group-owned resources 285 | may take additional time. 286 | Use the :route:`groups/job_status/get` to determine whether this process has completed. 287 | 288 | Permission : Team member management." 289 | 290 | attrs 291 | auth = "team" 292 | scope = "groups.write" 293 | 294 | # 295 | # route groups/update 296 | # 297 | 298 | struct GroupUpdateArgs extends IncludeMembersArg 299 | group GroupSelector 300 | "Specify a group." 301 | new_group_name String? 302 | "Optional argument. Set group name to this if provided." 303 | new_group_external_id team_common.GroupExternalId? 304 | "Optional argument. New group external ID. 305 | If the argument is None, the group's external_id won't be updated. 306 | If the argument is empty string, the group's external id will be cleared." 307 | new_group_management_type team_common.GroupManagementType? 308 | "Set new group management type, if provided." 309 | 310 | example default 311 | group = default 312 | new_group_name = "Europe west sales" 313 | new_group_external_id = "sales-234" 314 | new_group_management_type = company_managed 315 | 316 | union GroupUpdateError extends GroupSelectorWithTeamGroupError 317 | group_name_already_used 318 | "The requested group name is already being used by another group." 319 | group_name_invalid 320 | "Group name is empty or has invalid characters." 321 | external_id_already_in_use 322 | "The requested external ID is already being used by another group." 323 | 324 | route groups/update(GroupUpdateArgs, GroupFullInfo, GroupUpdateError) 325 | "Updates a group's name and/or external ID. 326 | 327 | Permission : Team member management." 328 | 329 | attrs 330 | auth = "team" 331 | scope = "groups.write" 332 | 333 | # 334 | # Structures common to groups/members/add and groups/members/remove 335 | # 336 | 337 | struct GroupMembersChangeResult 338 | "Result returned by :route:`groups/members/add` and :route:`groups/members/remove`." 339 | 340 | group_info GroupFullInfo 341 | "The group info after member change operation has been performed." 342 | async_job_id async.AsyncJobId 343 | "For legacy purposes async_job_id will always return one space ' '. Formerly, it was an ID that was used to obtain the status of granting/revoking group-owned resources. It's no longer necessary because the async processing now happens automatically." 344 | 345 | example default 346 | group_info = default 347 | async_job_id = "99988877733388" 348 | 349 | # 350 | # route groups/members/add (async method) 351 | # 352 | 353 | struct MemberAccess 354 | "Specify access type a member should have when joined to a group." 355 | 356 | user UserSelectorArg 357 | "Identity of a user." 358 | access_type GroupAccessType 359 | "Access type." 360 | 361 | example default 362 | user = default 363 | access_type = default 364 | 365 | struct GroupMembersAddArg extends IncludeMembersArg 366 | group GroupSelector 367 | "Group to which users will be added." 368 | members List(MemberAccess) 369 | "List of users to be added to the group." 370 | 371 | example default 372 | group = default 373 | members = [default] 374 | 375 | 376 | union GroupMembersAddError extends GroupSelectorWithTeamGroupError 377 | duplicate_user 378 | "You cannot add duplicate users. One or more of the members 379 | you are trying to add is already a member of the group." 380 | group_not_in_team 381 | "Group is not in this team. You cannot add members to a 382 | group that is outside of your team." 383 | members_not_in_team List(String) 384 | "These members are not part of your team. Currently, you cannot add members 385 | to a group if they are not part of your team, though this 386 | may change in a subsequent version. To add new members to your Dropbox 387 | Business team, use the :route:`members/add` endpoint." 388 | users_not_found List(String) 389 | "These users were not found in Dropbox." 390 | user_must_be_active_to_be_owner 391 | "A suspended user cannot be added to a group as :field:`GroupAccessType.owner`." 392 | user_cannot_be_manager_of_company_managed_group List(String) 393 | "A company-managed group cannot be managed by a user." 394 | 395 | 396 | route groups/members/add(GroupMembersAddArg, GroupMembersChangeResult, GroupMembersAddError) 397 | "Adds members to a group. 398 | 399 | The members are added immediately. However the granting of group-owned resources 400 | may take additional time. 401 | Use the :route:`groups/job_status/get` to determine whether this process has completed. 402 | 403 | Permission : Team member management." 404 | 405 | attrs 406 | auth = "team" 407 | scope = "groups.write" 408 | 409 | # 410 | # route groups/members/remove (async method) 411 | # 412 | 413 | struct GroupMembersRemoveArg extends IncludeMembersArg 414 | group GroupSelector 415 | "Group from which users will be removed." 416 | users List(UserSelectorArg) 417 | "List of users to be removed from the group." 418 | 419 | example default 420 | group = default 421 | users = [default] 422 | 423 | union GroupMembersRemoveError extends GroupMembersSelectorError 424 | group_not_in_team 425 | "Group is not in this team. You cannot remove members from a group 426 | that is outside of your team." 427 | members_not_in_team List(String) 428 | "These members are not part of your team." 429 | users_not_found List(String) 430 | "These users were not found in Dropbox." 431 | 432 | route groups/members/remove(GroupMembersRemoveArg, GroupMembersChangeResult, GroupMembersRemoveError) 433 | "Removes members from a group. 434 | 435 | The members are removed immediately. However the revoking of group-owned resources 436 | may take additional time. 437 | Use the :route:`groups/job_status/get` to determine whether this process has completed. 438 | 439 | This method permits removing the only owner of a group, even in cases where this is not 440 | possible via the web client. 441 | 442 | Permission : Team member management." 443 | 444 | attrs 445 | auth = "team" 446 | scope = "groups.write" 447 | 448 | # 449 | # route groups/members/set_access_type 450 | # 451 | 452 | 453 | struct GroupMembersSetAccessTypeArg extends GroupMemberSelector 454 | access_type GroupAccessType 455 | "New group access type the user will have." 456 | return_members Boolean = true 457 | "Whether to return the list of members in the group. 458 | Note that the default value will cause all the group members 459 | to be returned in the response. This may take a long time for large groups." 460 | 461 | example default 462 | group = default 463 | user = default 464 | access_type = default 465 | 466 | union GroupMemberSetAccessTypeError extends GroupMemberSelectorError 467 | user_cannot_be_manager_of_company_managed_group 468 | "A company managed group cannot be managed by a user." 469 | 470 | route groups/members/set_access_type(GroupMembersSetAccessTypeArg, GroupsGetInfoResult, GroupMemberSetAccessTypeError) 471 | "Sets a member's access type in a group. 472 | 473 | Permission : Team member management." 474 | 475 | attrs 476 | auth = "team" 477 | scope = "groups.write" 478 | 479 | 480 | # 481 | # route groups/members/list 482 | # 483 | 484 | struct GroupsMembersListArg 485 | group GroupSelector 486 | "The group whose members are to be listed." 487 | limit UInt32(min_value=1, max_value=1000) = 1000 488 | "Number of results to return per call." 489 | 490 | example default 491 | group = default 492 | limit = 100 493 | 494 | struct GroupsMembersListResult 495 | members List(GroupMemberInfo) 496 | cursor String 497 | "Pass the cursor into :route:`groups/members/list/continue` to obtain additional group members." 498 | has_more Boolean 499 | "Is true if there are additional group members that have not been returned 500 | yet. An additional call to :route:`groups/members/list/continue` can retrieve them." 501 | 502 | example default 503 | members = [] 504 | cursor = "ZtkX9_EHj3x7PMkVuFIhwKYXEpwpLwyxp9vMKomUhllil9q7eWiAu" 505 | has_more = false 506 | 507 | 508 | route groups/members/list(GroupsMembersListArg, GroupsMembersListResult, GroupSelectorError) 509 | "Lists members of a group. 510 | 511 | Permission : Team Information." 512 | 513 | attrs 514 | auth = "team" 515 | scope = "groups.read" 516 | 517 | # 518 | # route groups/members/list/continue 519 | # 520 | 521 | struct GroupsMembersListContinueArg 522 | cursor String 523 | "Indicates from what point to get the next set of groups." 524 | 525 | example default 526 | cursor = "ZtkX9_EHj3x7PMkVuFIhwKYXEpwpLwyxp9vMKomUhllil9q7eWiAu" 527 | 528 | union GroupsMembersListContinueError 529 | invalid_cursor 530 | "The cursor is invalid." 531 | 532 | route groups/members/list/continue(GroupsMembersListContinueArg, GroupsMembersListResult, GroupsMembersListContinueError) 533 | "Once a cursor has been retrieved from :route:`groups/members/list`, use this to paginate 534 | through all members of the group. 535 | 536 | Permission : Team information." 537 | 538 | attrs 539 | auth = "team" 540 | scope = "groups.read" 541 | 542 | # 543 | # route groups/job_status/get 544 | # 545 | 546 | union GroupsPollError extends async.PollError 547 | access_denied 548 | "You are not allowed to poll this job." 549 | 550 | route groups/job_status/get(async.PollArg, async.PollEmptyResult, GroupsPollError) 551 | "Once an async_job_id is returned from :route:`groups/delete`, 552 | :route:`groups/members/add` , or :route:`groups/members/remove` 553 | use this method to poll the status of granting/revoking 554 | group members' access to group-owned resources. 555 | 556 | Permission : Team member management." 557 | 558 | attrs 559 | auth = "team" 560 | scope = "groups.write" 561 | -------------------------------------------------------------------------------- /team_legal_holds.stone: -------------------------------------------------------------------------------- 1 | namespace team 2 | 3 | import common 4 | import team_common 5 | import files 6 | 7 | alias LegalHoldId = String(pattern="^pid_dbhid:.+") 8 | alias LegalHoldPolicyName = String(max_length=140) 9 | alias LegalHoldPolicyDescription = String(max_length=501) 10 | alias Path = String(pattern="(/(.|[\\r\\n])*)?") 11 | 12 | union LegalHoldStatus 13 | active 14 | "The legal hold policy is active." 15 | released 16 | "The legal hold policy was released." 17 | activating 18 | "The legal hold policy is activating." 19 | updating 20 | "The legal hold policy is updating." 21 | exporting 22 | "The legal hold policy is exporting." 23 | releasing 24 | "The legal hold policy is releasing." 25 | 26 | struct MembersInfo 27 | team_member_ids List(team_common.TeamMemberId) 28 | "Team member IDs of the users under this hold." 29 | permanently_deleted_users UInt64 30 | "The number of permanently deleted users that were under this hold." 31 | 32 | example default 33 | team_member_ids = ["dbmid:efgh5678"] 34 | permanently_deleted_users = 2 35 | 36 | union LegalHoldsError 37 | unknown_legal_hold_error 38 | "There has been an unknown legal hold error." 39 | insufficient_permissions 40 | "You don't have permissions to perform this action." 41 | 42 | struct LegalHoldPolicy 43 | id LegalHoldId 44 | "The legal hold id." 45 | name LegalHoldPolicyName 46 | "Policy name." 47 | description LegalHoldPolicyDescription? 48 | "A description of the legal hold policy." 49 | activation_time common.DropboxTimestamp? 50 | "The time at which the legal hold was activated." 51 | members MembersInfo 52 | "Team members IDs and number of permanently deleted members under hold." 53 | status LegalHoldStatus 54 | "The current state of the hold." 55 | start_date common.DropboxTimestamp 56 | "Start date of the legal hold policy." 57 | end_date common.DropboxTimestamp? 58 | "End date of the legal hold policy." 59 | 60 | example default 61 | id = "pid_dbhid:abcd1234" 62 | name = "acme cfo policy" 63 | activation_time = "2016-01-20T00:00:10Z" 64 | members = default 65 | status = active 66 | start_date = "2016-01-01T00:00:00Z" 67 | end_date = "2017-12-31T00:00:00Z" 68 | 69 | # 70 | # route legal_holds/create_policy 71 | # 72 | 73 | struct LegalHoldsPolicyCreateArg 74 | name LegalHoldPolicyName 75 | "Policy name." 76 | description LegalHoldPolicyDescription? 77 | "A description of the legal hold policy." 78 | members List(team_common.TeamMemberId) 79 | "List of team member IDs added to the hold." 80 | start_date common.DropboxTimestamp? 81 | "start date of the legal hold policy." 82 | end_date common.DropboxTimestamp? 83 | "end date of the legal hold policy." 84 | 85 | example default 86 | name = "acme cfo policy" 87 | members = ["dbmid:FDFSVF-DFSDF"] 88 | start_date = "2016-01-01T00:00:00Z" 89 | end_date = "2017-12-31T00:00:00Z" 90 | 91 | union LegalHoldsPolicyCreateError extends LegalHoldsError 92 | start_date_is_later_than_end_date 93 | "Start date must be earlier than end date." 94 | empty_members_list 95 | "The users list must have at least one user." 96 | invalid_members 97 | "Some members in the members list are not valid to be placed under legal hold." 98 | number_of_users_on_hold_is_greater_than_hold_limitation 99 | "You cannot add more than 5 users in a legal hold." 100 | transient_error 101 | "Temporary infrastructure failure, please retry." 102 | name_must_be_unique 103 | "The name provided is already in use by another legal hold." 104 | team_exceeded_legal_hold_quota 105 | "Team exceeded legal hold quota." 106 | invalid_date 107 | "The provided date is invalid." 108 | 109 | alias LegalHoldsPolicyCreateResult = LegalHoldPolicy 110 | 111 | route legal_holds/create_policy(LegalHoldsPolicyCreateArg, LegalHoldsPolicyCreateResult, LegalHoldsPolicyCreateError) 112 | "Creates new legal hold policy. 113 | Note: Legal Holds is a paid add-on. Not all teams have the feature. 114 | 115 | Permission : Team member file access." 116 | 117 | attrs 118 | auth = "team" 119 | scope = "team_data.governance.write" 120 | 121 | # 122 | # route legal_holds/get_policy 123 | # 124 | 125 | struct LegalHoldsGetPolicyArg 126 | id LegalHoldId 127 | "The legal hold Id." 128 | example default 129 | id = "pid_dbhid:abcd1234" 130 | 131 | alias LegalHoldsGetPolicyResult = LegalHoldPolicy 132 | 133 | union LegalHoldsGetPolicyError extends LegalHoldsError 134 | legal_hold_policy_not_found 135 | "Legal hold policy does not exist for :field:`LegalHoldsGetPolicyArg.id`." 136 | 137 | route legal_holds/get_policy(LegalHoldsGetPolicyArg, LegalHoldsGetPolicyResult, LegalHoldsGetPolicyError) 138 | "Gets a legal hold by Id. 139 | Note: Legal Holds is a paid add-on. Not all teams have the feature. 140 | 141 | Permission : Team member file access." 142 | 143 | attrs 144 | auth = "team" 145 | scope = "team_data.governance.write" 146 | 147 | 148 | # 149 | # route legal_holds/list_policies 150 | # 151 | struct LegalHoldsListPoliciesArg 152 | include_released Boolean = false 153 | "Whether to return holds that were released." 154 | 155 | example default 156 | include_released = false 157 | 158 | struct LegalHoldsListPoliciesResult 159 | policies List(LegalHoldPolicy) 160 | 161 | example default 162 | policies = [default] 163 | 164 | union LegalHoldsListPoliciesError extends LegalHoldsError 165 | transient_error 166 | "Temporary infrastructure failure, please retry." 167 | 168 | route legal_holds/list_policies(LegalHoldsListPoliciesArg, LegalHoldsListPoliciesResult, LegalHoldsListPoliciesError) 169 | "Lists legal holds on a team. 170 | Note: Legal Holds is a paid add-on. Not all teams have the feature. 171 | 172 | Permission : Team member file access." 173 | 174 | attrs 175 | auth = "team" 176 | scope = "team_data.governance.write" 177 | 178 | 179 | # 180 | # route legal_holds/list_held_revisions 181 | # 182 | 183 | struct LegalHoldsListHeldRevisionsArg 184 | id LegalHoldId 185 | "The legal hold Id." 186 | example default 187 | id = "pid_dbhid:abcd1234" 188 | 189 | union LegalHoldsListHeldRevisionsError extends LegalHoldsError 190 | transient_error 191 | "Temporary infrastructure failure, please retry." 192 | legal_hold_still_empty 193 | "The legal hold is not holding any revisions yet." 194 | inactive_legal_hold 195 | "Trying to list revisions for an inactive legal hold." 196 | 197 | struct LegalHoldHeldRevisionMetadata 198 | new_filename String 199 | "The held revision filename." 200 | original_revision_id files.Rev 201 | "The id of the held revision." 202 | original_file_path Path 203 | "The original path of the held revision." 204 | server_modified common.DropboxTimestamp 205 | "The last time the file was modified on Dropbox." 206 | author_member_id team_common.TeamMemberId 207 | "The member id of the revision's author." 208 | author_member_status TeamMemberStatus 209 | "The member status of the revision's author." 210 | author_email common.EmailAddress 211 | "The email address of the held revision author." 212 | file_type String 213 | "The type of the held revision's file." 214 | size UInt64 215 | "The file size in bytes." 216 | content_hash files.Sha256HexHash 217 | "A hash of the file content. This field can be used to verify data integrity. For more 218 | information see our :link:`Content hash https://www.dropbox.com/developers/reference/content-hash` page." 219 | 220 | example default 221 | new_filename = "111_222.pdf" 222 | original_revision_id = "ab2rij4i5ojgfd" 223 | original_file_path = "/a.pdf" 224 | server_modified = "2019-08-12T12:08:52Z" 225 | author_member_id = "dbmid:abcd1234abcd1234abcd1234abcd1234a23" 226 | author_member_status = active 227 | author_email = "a@a.com" 228 | file_type = "Document" 229 | size = 3 230 | content_hash = "abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234" 231 | 232 | alias ListHeldRevisionCursor = String(min_length=1) 233 | 234 | struct LegalHoldsListHeldRevisionResult 235 | entries List(LegalHoldHeldRevisionMetadata) 236 | "List of file entries that under the hold." 237 | cursor ListHeldRevisionCursor? 238 | "The cursor idicates where to continue reading file metadata entries for the next API call. When there are no more entries, the cursor will return none. 239 | 240 | Pass the cursor into 241 | /2/team/legal_holds/list_held_revisions/continue." 242 | has_more Boolean 243 | "True if there are more file entries that haven't been returned. You can retrieve them with a call to /legal_holds/list_held_revisions_continue." 244 | 245 | example default 246 | entries = [default] 247 | has_more = false 248 | 249 | route legal_holds/list_held_revisions(LegalHoldsListHeldRevisionsArg, LegalHoldsListHeldRevisionResult, LegalHoldsListHeldRevisionsError) 250 | "List the file metadata that's under the hold. 251 | Note: Legal Holds is a paid add-on. Not all teams have the feature. 252 | 253 | Permission : Team member file access." 254 | 255 | attrs 256 | auth = "team" 257 | scope = "team_data.governance.write" 258 | 259 | 260 | # 261 | # route legal_holds/list_held_revisions_continue 262 | # 263 | 264 | struct LegalHoldsListHeldRevisionsContinueArg 265 | id LegalHoldId 266 | "The legal hold Id." 267 | cursor ListHeldRevisionCursor? 268 | "The cursor idicates where to continue reading file metadata entries for the next API call. When there are no more entries, the cursor will return none." 269 | example default 270 | id = "pid_dbhid:abcd1234" 271 | 272 | union LegalHoldsListHeldRevisionsContinueError 273 | unknown_legal_hold_error 274 | "There has been an unknown legal hold error." 275 | transient_error 276 | "Temporary infrastructure failure, please retry." 277 | reset 278 | "Indicates that the cursor has been invalidated. Call 279 | :route:`legal_holds/list_held_revisions_continue` again with an empty cursor to obtain a new cursor." 280 | 281 | route legal_holds/list_held_revisions_continue(LegalHoldsListHeldRevisionsContinueArg, LegalHoldsListHeldRevisionResult, LegalHoldsListHeldRevisionsError) 282 | "Continue listing the file metadata that's under the hold. 283 | Note: Legal Holds is a paid add-on. Not all teams have the feature. 284 | 285 | Permission : Team member file access." 286 | 287 | attrs 288 | auth = "team" 289 | scope = "team_data.governance.write" 290 | 291 | # 292 | # route legal_holds/update_policy 293 | # 294 | 295 | struct LegalHoldsPolicyUpdateArg 296 | id LegalHoldId 297 | "The legal hold Id." 298 | name LegalHoldPolicyName? 299 | "Policy new name." 300 | description LegalHoldPolicyDescription? 301 | "Policy new description." 302 | members List(team_common.TeamMemberId)? 303 | "List of team member IDs to apply the policy on." 304 | example default 305 | id = "pid_dbhid:abcd1234" 306 | members = ["dbmid:FDFSVF-DFSDF"] 307 | 308 | union LegalHoldsPolicyUpdateError extends LegalHoldsError 309 | transient_error 310 | "Temporary infrastructure failure, please retry." 311 | inactive_legal_hold 312 | "Trying to release an inactive legal hold." 313 | legal_hold_performing_another_operation 314 | "Legal hold is currently performing another operation." 315 | invalid_members 316 | "Some members in the members list are not valid to be placed under legal hold." 317 | number_of_users_on_hold_is_greater_than_hold_limitation 318 | "You cannot add more than 5 users in a legal hold." 319 | empty_members_list 320 | "The users list must have at least one user." 321 | name_must_be_unique 322 | "The name provided is already in use by another legal hold." 323 | legal_hold_policy_not_found 324 | "Legal hold policy does not exist for :field:`LegalHoldsPolicyUpdateArg.id`." 325 | 326 | 327 | alias LegalHoldsPolicyUpdateResult = LegalHoldPolicy 328 | 329 | route legal_holds/update_policy(LegalHoldsPolicyUpdateArg, LegalHoldsPolicyUpdateResult, LegalHoldsPolicyUpdateError) 330 | "Updates a legal hold. 331 | Note: Legal Holds is a paid add-on. Not all teams have the feature. 332 | 333 | Permission : Team member file access." 334 | 335 | attrs 336 | auth = "team" 337 | scope = "team_data.governance.write" 338 | 339 | # 340 | # route legal_holds/release_policy 341 | # 342 | 343 | struct LegalHoldsPolicyReleaseArg 344 | id LegalHoldId 345 | "The legal hold Id." 346 | example default 347 | id = "pid_dbhid:abcd1234" 348 | 349 | union LegalHoldsPolicyReleaseError extends LegalHoldsError 350 | legal_hold_performing_another_operation 351 | "Legal hold is currently performing another operation." 352 | legal_hold_already_releasing 353 | "Legal hold is currently performing a release or is already released." 354 | legal_hold_policy_not_found 355 | "Legal hold policy does not exist for :field:`LegalHoldsPolicyReleaseArg.id`." 356 | 357 | route legal_holds/release_policy(LegalHoldsPolicyReleaseArg, Void, LegalHoldsPolicyReleaseError) 358 | "Releases a legal hold by Id. 359 | Note: Legal Holds is a paid add-on. Not all teams have the feature. 360 | 361 | Permission : Team member file access." 362 | 363 | attrs 364 | auth = "team" 365 | scope = "team_data.governance.write" 366 | -------------------------------------------------------------------------------- /team_linked_apps.stone: -------------------------------------------------------------------------------- 1 | namespace team 2 | 3 | import common 4 | 5 | # 6 | # Structures for linked_apps/list_member_linked_apps 7 | # 8 | 9 | struct ListMemberAppsArg 10 | team_member_id String 11 | "The team member id." 12 | 13 | example default 14 | team_member_id = "dbmid:AAFdgehTzw7WlXhZJsbGCLePe8RvQGYDr-I" 15 | 16 | struct ApiApp 17 | "Information on linked third party applications." 18 | 19 | app_id String 20 | "The application unique id." 21 | app_name String 22 | "The application name." 23 | publisher String? 24 | "The application publisher name." 25 | publisher_url String? 26 | "The publisher's URL." 27 | linked common.DropboxTimestamp? 28 | "The time this application was linked." 29 | is_app_folder Boolean 30 | "Whether the linked application uses a dedicated folder." 31 | 32 | example default 33 | app_id = "dbaid:AAFdgehTzw7WlXhZJsbGCLePe8RvQGYDr-I" 34 | app_name = "Notes" 35 | publisher = "Notes company" 36 | publisher_url = "http://company.com" 37 | linked = "2015-05-12T15:50:38Z" 38 | is_app_folder = true 39 | 40 | struct ListMemberAppsResult 41 | linked_api_apps List(ApiApp) 42 | "List of third party applications linked by this team member." 43 | 44 | example default 45 | linked_api_apps = [default] 46 | 47 | union ListMemberAppsError 48 | "Error returned by :route:`linked_apps/list_member_linked_apps`." 49 | 50 | member_not_found 51 | "Member not found." 52 | 53 | # 54 | # Route: linked_apps/list_member_linked_apps 55 | # 56 | 57 | route linked_apps/list_member_linked_apps(ListMemberAppsArg, ListMemberAppsResult, ListMemberAppsError) 58 | "List all linked applications of the team member. 59 | 60 | Note, this endpoint does not list any team-linked applications." 61 | 62 | attrs 63 | auth = "team" 64 | scope = "sessions.list" 65 | 66 | # 67 | # Structs for linked_apps/list_members_linked_apps 68 | # 69 | 70 | struct ListMembersAppsArg 71 | "Arguments for :route:`linked_apps/list_members_linked_apps`." 72 | 73 | cursor String? 74 | "At the first call to the :route:`linked_apps/list_members_linked_apps` the cursor shouldn't be 75 | passed. Then, if the result of the call includes a cursor, the following requests should 76 | include the received cursors in order to receive the next sub list of the team applications." 77 | 78 | example default 79 | cursor = "AADAQO8ZWKvBkSMXb1J9dAYVvwZ0wcvfyzIBo2e1H-_N-67pfrYKTb4oN_3LG9_ilWjblZXuiR8ubjjiQQkHq-MvDjbe_6bkcJgjnTpowrRaQA" 80 | 81 | struct MemberLinkedApps 82 | "Information on linked applications of a team member." 83 | 84 | team_member_id String 85 | "The member unique Id." 86 | linked_api_apps List(ApiApp) 87 | "List of third party applications linked by this team member." 88 | 89 | example default 90 | team_member_id = "dbmid:AAFdgehTzw7WlXhZJsbGCLePe8RvQGYDr-I" 91 | linked_api_apps = [default] 92 | 93 | struct ListMembersAppsResult 94 | "Information returned by :route:`linked_apps/list_members_linked_apps`." 95 | 96 | apps List(MemberLinkedApps) 97 | "The linked applications of each member of the team." 98 | has_more Boolean 99 | "If true, then there are more apps available. Pass the 100 | cursor to :route:`linked_apps/list_members_linked_apps` to retrieve the rest." 101 | cursor String? 102 | "Pass the cursor into :route:`linked_apps/list_members_linked_apps` to receive the next 103 | sub list of team's applications." 104 | 105 | example default 106 | apps = [default] 107 | has_more = true 108 | cursor = "AADAQO8ZWKvBkSMXb1J9dAYVvwZ0wcvfyzIBo2e1H-_N-67pfrYKTb4oN_3LG9_ilWjblZXuiR8ubjjiQQkHq-MvDjbe_6bkcJgjnTpowrRaQA" 109 | 110 | union ListMembersAppsError 111 | "Error returned by :route:`linked_apps/list_members_linked_apps`." 112 | 113 | reset 114 | "Indicates that the cursor has been invalidated. Call 115 | :route:`linked_apps/list_members_linked_apps` again with an empty cursor to obtain a new cursor." 116 | 117 | # 118 | # Route: linked_apps/list_members_linked_apps 119 | # 120 | route linked_apps/list_members_linked_apps(ListMembersAppsArg, ListMembersAppsResult, ListMembersAppsError) 121 | "List all applications linked to the team members' accounts. 122 | 123 | Note, this endpoint does not list any team-linked applications." 124 | 125 | attrs 126 | auth = "team" 127 | scope = "sessions.list" 128 | 129 | # 130 | # Structs for linked_apps/revoke_linked_app 131 | # 132 | 133 | struct RevokeLinkedApiAppArg 134 | app_id String 135 | "The application's unique id." 136 | team_member_id String 137 | "The unique id of the member owning the device." 138 | keep_app_folder Boolean = true 139 | "This flag is not longer supported, the application dedicated folder (in case the application uses 140 | one) will be kept." 141 | 142 | example default 143 | app_id = "dbaid:AAFdgehTzw7WlXhZJsbGCLePe8RvQGYDr-I" 144 | team_member_id = "dbmid:AAFdgehTzw7WlXhZJsbGCLePe8RvQGYDr-I" 145 | 146 | union RevokeLinkedAppError 147 | "Error returned by :route:`linked_apps/revoke_linked_app`." 148 | 149 | app_not_found 150 | "Application not found." 151 | member_not_found 152 | "Member not found." 153 | app_folder_removal_not_supported 154 | "App folder removal is not supported." 155 | 156 | # 157 | # Route: linked_apps/revoke_linked_app 158 | # 159 | 160 | route linked_apps/revoke_linked_app(RevokeLinkedApiAppArg, Void, RevokeLinkedAppError) 161 | "Revoke a linked application of the team member." 162 | 163 | attrs 164 | auth = "team" 165 | scope = "sessions.modify" 166 | 167 | # 168 | # structs for linked_apps/revoke_linked_app_batch 169 | # 170 | 171 | struct RevokeLinkedApiAppBatchArg 172 | revoke_linked_app List(RevokeLinkedApiAppArg) 173 | 174 | example default 175 | revoke_linked_app = [default] 176 | 177 | struct RevokeLinkedAppStatus 178 | 179 | success Boolean 180 | "Result of the revoking request." 181 | error_type RevokeLinkedAppError? 182 | "The error cause in case of a failure." 183 | 184 | example default 185 | success = false 186 | error_type = app_not_found 187 | 188 | struct RevokeLinkedAppBatchResult 189 | revoke_linked_app_status List(RevokeLinkedAppStatus) 190 | 191 | example default 192 | revoke_linked_app_status = [default] 193 | 194 | union RevokeLinkedAppBatchError 195 | "Error returned by :route:`linked_apps/revoke_linked_app_batch`." 196 | 197 | # 198 | # Route: linked_apps/revoke_linked_app_batch 199 | # 200 | 201 | route linked_apps/revoke_linked_app_batch(RevokeLinkedApiAppBatchArg, RevokeLinkedAppBatchResult, RevokeLinkedAppBatchError) 202 | "Revoke a list of linked applications of the team members." 203 | 204 | attrs 205 | auth = "team" 206 | scope = "sessions.modify" 207 | 208 | # 209 | # Deprecated endpoints 210 | # 211 | 212 | struct ListTeamAppsArg 213 | "Arguments for :route:`linked_apps/list_team_linked_apps`." 214 | 215 | cursor String? 216 | "At the first call to the :route:`linked_apps/list_team_linked_apps` the cursor shouldn't be 217 | passed. Then, if the result of the call includes a cursor, the following requests should 218 | include the received cursors in order to receive the next sub list of the team applications." 219 | 220 | example default 221 | cursor = "AADAQO8ZWKvBkSMXb1J9dAYVvwZ0wcvfyzIBo2e1H-_N-67pfrYKTb4oN_3LG9_ilWjblZXuiR8ubjjiQQkHq-MvDjbe_6bkcJgjnTpowrRaQA" 222 | 223 | struct ListTeamAppsResult 224 | "Information returned by :route:`linked_apps/list_team_linked_apps`." 225 | 226 | apps List(MemberLinkedApps) 227 | "The linked applications of each member of the team." 228 | has_more Boolean 229 | "If true, then there are more apps available. Pass the 230 | cursor to :route:`linked_apps/list_team_linked_apps` to retrieve the rest." 231 | cursor String? 232 | "Pass the cursor into :route:`linked_apps/list_team_linked_apps` to receive the next 233 | sub list of team's applications." 234 | 235 | example default 236 | apps = [default] 237 | has_more = true 238 | cursor = "AADAQO8ZWKvBkSMXb1J9dAYVvwZ0wcvfyzIBo2e1H-_N-67pfrYKTb4oN_3LG9_ilWjblZXuiR8ubjjiQQkHq-MvDjbe_6bkcJgjnTpowrRaQA" 239 | 240 | union ListTeamAppsError 241 | "Error returned by :route:`linked_apps/list_team_linked_apps`." 242 | 243 | reset 244 | "Indicates that the cursor has been invalidated. Call 245 | :route:`linked_apps/list_team_linked_apps` again with an empty cursor to obtain a new cursor." 246 | 247 | route linked_apps/list_team_linked_apps(ListTeamAppsArg, ListTeamAppsResult, ListTeamAppsError) deprecated by linked_apps/list_members_linked_apps 248 | "List all applications linked to the team members' accounts. 249 | 250 | Note, this endpoint doesn't list any team-linked applications." 251 | 252 | attrs 253 | auth = "team" 254 | scope = "sessions.list" 255 | -------------------------------------------------------------------------------- /team_log.stone: -------------------------------------------------------------------------------- 1 | namespace team_log 2 | 3 | import async 4 | import common 5 | import team 6 | import team_common 7 | import users_common 8 | 9 | ############################### 10 | # Routes declarations 11 | ############################### 12 | 13 | struct GetTeamEventsArg 14 | limit UInt32(min_value=1, max_value=1000) = 1000 15 | "The maximal number of results to return per call. Note that some calls may not return 16 | :field:`limit` number of events, and may even return no events, even with `has_more` set to true. 17 | In this case, callers should fetch again using :route:`get_events/continue`." 18 | account_id users_common.AccountId? 19 | "Filter the events by account ID. Return only events with this account_id as either 20 | Actor, Context, or Participants." 21 | time team_common.TimeRange? 22 | "Filter by time range." 23 | category EventCategory? 24 | "Filter the returned events to a single category. Note that category shouldn't be provided 25 | together with event_type." 26 | event_type EventTypeArg? 27 | "Filter the returned events to a single event type. Note that event_type shouldn't be provided 28 | together with category." 29 | 30 | example default 31 | limit=50 32 | category=groups 33 | 34 | # This is used only for `json_encode` in metaserver/tests/util/event_helper.py 35 | # simply because I don't know how to use the list. 36 | alias TeamEventList = List(TeamEvent) 37 | 38 | struct GetTeamEventsResult 39 | events List(TeamEvent) 40 | "List of events. Note that events are not guaranteed to be sorted by their timestamp value." 41 | cursor String 42 | "Pass the cursor into :route:`get_events/continue` to obtain additional events. 43 | 44 | The value of :field:`cursor` may change for each response from :route:`get_events/continue`, 45 | regardless of the value of :field:`has_more`; older cursor strings may expire. 46 | 47 | Thus, callers should ensure that they update their cursor based on the latest value of 48 | :field:`cursor` after each call, and poll regularly if they wish to poll for new events. 49 | 50 | Callers should handle reset exceptions for expired cursors." 51 | has_more Boolean 52 | "Is true if there may be additional events that have not been returned yet. 53 | An additional call to :route:`get_events/continue` can retrieve them. 54 | Note that :field:`has_more` may be :val:`true`, even if :field:`events` is empty." 55 | 56 | example default 57 | events = [default] 58 | cursor = "ZtkX9_EHj3x7PMkVuFIhwKYXEpwpLwyxp9vMKomUhllil9q7eWiAu" 59 | has_more = false 60 | 61 | union GetTeamEventsError 62 | "Errors that can be raised when calling :route:`get_events`." 63 | 64 | account_id_not_found 65 | "No user found matching the provided account_id." 66 | invalid_time_range 67 | "Invalid time range." 68 | invalid_filters 69 | "Invalid filters. Do not specify both event_type and category parameters for the same call." 70 | 71 | example default 72 | account_id_not_found = null 73 | 74 | route get_events(GetTeamEventsArg, GetTeamEventsResult, GetTeamEventsError) 75 | "Retrieves team events. If the result's :field:`GetTeamEventsResult.has_more` field is 76 | :val:`true`, call :route:`get_events/continue` with the returned cursor to retrieve 77 | more entries. If end_time is not specified in your request, you may use the returned cursor to 78 | poll :route:`get_events/continue` for new events. 79 | 80 | Many attributes note 'may be missing due to historical data gap'. 81 | 82 | Note that the file_operations category and & analogous paper events are not available on all 83 | Dropbox Business :link:`plans /business/plans-comparison`. 84 | Use :link:`features/get_values /developers/documentation/http/teams#team-features-get_values` 85 | to check for this feature. 86 | 87 | Permission : Team Auditing." 88 | 89 | attrs 90 | auth = "team" 91 | scope = "events.read" 92 | 93 | struct GetTeamEventsContinueArg 94 | cursor String 95 | "Indicates from what point to get the next set of events." 96 | 97 | example default 98 | cursor = "ZtkX9_EHj3x7PMkVuFIhwKYXEpwpLwyxp9vMKomUhllil9q7eWiAu" 99 | 100 | 101 | union GetTeamEventsContinueError 102 | "Errors that can be raised when calling :route:`get_events/continue`." 103 | 104 | bad_cursor 105 | "Bad cursor." 106 | 107 | reset common.DropboxTimestamp 108 | "Cursors are intended to be used quickly. Individual cursor values are normally valid for days, 109 | but in rare cases may be reset sooner. 110 | 111 | Cursor reset errors should be handled by fetching a new cursor from :route:`get_events`. 112 | 113 | The associated value is the approximate timestamp of the most recent event returned by the cursor. 114 | This should be used as a resumption point when calling :route:`get_events` to obtain a new cursor." 115 | 116 | example default 117 | bad_cursor = null 118 | 119 | route get_events/continue(GetTeamEventsContinueArg, GetTeamEventsResult, GetTeamEventsContinueError) 120 | "Once a cursor has been retrieved from :route:`get_events`, use this to paginate through all events. 121 | 122 | Permission : Team Auditing." 123 | 124 | attrs 125 | auth = "team" 126 | scope = "events.read" 127 | -------------------------------------------------------------------------------- /team_member_space_limits.stone: -------------------------------------------------------------------------------- 1 | namespace team 2 | 3 | 4 | alias UserQuota = UInt32(min_value=15) 5 | 6 | 7 | struct UserCustomQuotaArg 8 | "User and their required custom quota in GB (1 TB = 1024 GB)." 9 | user UserSelectorArg 10 | quota_gb UserQuota 11 | 12 | example default 13 | user=default 14 | quota_gb=30 15 | 16 | 17 | struct UserCustomQuotaResult 18 | "User and their custom quota in GB (1 TB = 1024 GB). 19 | No quota returns if the user has no custom quota set." 20 | user UserSelectorArg 21 | quota_gb UserQuota? 22 | 23 | 24 | struct SetCustomQuotaArg 25 | users_and_quotas List(UserCustomQuotaArg) 26 | "List of users and their custom quotas." 27 | 28 | example default 29 | users_and_quotas=[default] 30 | 31 | 32 | union CustomQuotaError 33 | "Error returned when getting member custom quota." 34 | 35 | too_many_users 36 | "A maximum of 1000 users can be set for a single call." 37 | 38 | 39 | union SetCustomQuotaError extends CustomQuotaError 40 | "Error returned when setting member custom quota." 41 | 42 | some_users_are_excluded 43 | "Some of the users are on the excluded users list and can't have custom quota set." 44 | 45 | 46 | union CustomQuotaResult 47 | "User custom quota." 48 | 49 | success UserCustomQuotaResult 50 | "User's custom quota." 51 | invalid_user UserSelectorArg 52 | "Invalid user (not in team)." 53 | 54 | 55 | struct CustomQuotaUsersArg 56 | users List(UserSelectorArg) 57 | "List of users." 58 | 59 | example default 60 | users=[default] 61 | 62 | 63 | union RemoveCustomQuotaResult 64 | "User result for setting member custom quota." 65 | 66 | success UserSelectorArg 67 | "Successfully removed user." 68 | invalid_user UserSelectorArg 69 | "Invalid user (not in team)." 70 | 71 | 72 | route member_space_limits/set_custom_quota(SetCustomQuotaArg, List(CustomQuotaResult), SetCustomQuotaError) 73 | "Set users custom quota. Custom quota has to be at least 15GB. 74 | A maximum of 1000 members can be specified in a single call. 75 | Note: to apply a custom space limit, a team admin needs to set a member space limit for the team first. 76 | (the team admin can check the settings here: https://www.dropbox.com/team/admin/settings/space)." 77 | 78 | attrs 79 | auth = "team" 80 | scope = "members.read" 81 | 82 | 83 | route member_space_limits/remove_custom_quota(CustomQuotaUsersArg, List(RemoveCustomQuotaResult), CustomQuotaError) 84 | "Remove users custom quota. 85 | A maximum of 1000 members can be specified in a single call. 86 | Note: to apply a custom space limit, a team admin needs to set a member space limit for the team first. 87 | (the team admin can check the settings here: https://www.dropbox.com/team/admin/settings/space)." 88 | 89 | attrs 90 | auth = "team" 91 | scope = "members.write" 92 | 93 | 94 | route member_space_limits/get_custom_quota(CustomQuotaUsersArg, List(CustomQuotaResult), CustomQuotaError) 95 | "Get users custom quota. 96 | A maximum of 1000 members can be specified in a single call. 97 | Note: to apply a custom space limit, a team admin needs to set a member space limit for the team first. 98 | (the team admin can check the settings here: https://www.dropbox.com/team/admin/settings/space)." 99 | 100 | attrs 101 | auth = "team" 102 | scope = "members.read" 103 | 104 | 105 | struct ExcludedUsersUpdateArg 106 | "Argument of excluded users update operation. 107 | Should include a list of users to add/remove (according to endpoint), 108 | Maximum size of the list is 1000 users." 109 | 110 | users List(UserSelectorArg)? 111 | "List of users to be added/removed." 112 | 113 | example default 114 | users = [default] 115 | 116 | 117 | union ExcludedUsersUpdateError 118 | "Excluded users update error." 119 | 120 | users_not_in_team 121 | "At least one of the users is not part of your team." 122 | too_many_users 123 | "A maximum of 1000 users for each of addition/removal can be supplied." 124 | 125 | 126 | struct ExcludedUsersListArg 127 | "Excluded users list argument." 128 | 129 | limit UInt32(min_value=1, max_value=1000) = 1000 130 | "Number of results to return per call." 131 | 132 | example default 133 | limit = 100 134 | 135 | 136 | struct ExcludedUsersListContinueArg 137 | "Excluded users list continue argument." 138 | 139 | cursor String 140 | "Indicates from what point to get the next set of users." 141 | 142 | example default 143 | cursor = "ZtkX9_EHj3x7PMkVuFIhwKYXEpwpLwyxp9vMKomUhllil9q7eWiAu" 144 | 145 | 146 | struct ExcludedUsersListResult 147 | "Excluded users list result." 148 | 149 | users List(MemberProfile) 150 | cursor String? 151 | "Pass the cursor into :route:`member_space_limits/excluded_users/list/continue` to obtain 152 | additional excluded users." 153 | has_more Boolean 154 | "Is true if there are additional excluded users that have not been returned 155 | yet. An additional call to :route:`member_space_limits/excluded_users/list/continue` can 156 | retrieve them." 157 | 158 | example default 159 | users = [] 160 | cursor = "ZtkX9_EHj3x7PMkVuFIhwKYXEpwpLwyxp9vMKomUhllil9q7eWiAu" 161 | has_more = false 162 | 163 | 164 | union ExcludedUsersUpdateStatus 165 | "Excluded users update operation status." 166 | 167 | success 168 | "Update successful." 169 | 170 | 171 | struct ExcludedUsersUpdateResult 172 | "Excluded users update result." 173 | 174 | status ExcludedUsersUpdateStatus 175 | "Update status." 176 | 177 | example default 178 | status = success 179 | 180 | 181 | union ExcludedUsersListError 182 | "Excluded users list error." 183 | 184 | list_error 185 | "An error occurred." 186 | 187 | 188 | union ExcludedUsersListContinueError 189 | "Excluded users list continue error." 190 | 191 | invalid_cursor 192 | "The cursor is invalid." 193 | 194 | 195 | route member_space_limits/excluded_users/add(ExcludedUsersUpdateArg, ExcludedUsersUpdateResult, ExcludedUsersUpdateError) 196 | "Add users to member space limits excluded users list." 197 | 198 | attrs 199 | auth = "team" 200 | scope = "members.write" 201 | 202 | 203 | route member_space_limits/excluded_users/remove(ExcludedUsersUpdateArg, ExcludedUsersUpdateResult, ExcludedUsersUpdateError) 204 | "Remove users from member space limits excluded users list." 205 | 206 | attrs 207 | auth = "team" 208 | scope = "members.write" 209 | 210 | route member_space_limits/excluded_users/list(ExcludedUsersListArg, ExcludedUsersListResult, ExcludedUsersListError) 211 | "List member space limits excluded users." 212 | 213 | attrs 214 | auth = "team" 215 | scope = "members.read" 216 | 217 | 218 | route member_space_limits/excluded_users/list/continue(ExcludedUsersListContinueArg, ExcludedUsersListResult, ExcludedUsersListContinueError) 219 | "Continue listing member space limits excluded users." 220 | 221 | attrs 222 | auth = "team" 223 | scope = "members.read" 224 | -------------------------------------------------------------------------------- /team_namespaces.stone: -------------------------------------------------------------------------------- 1 | namespace team 2 | 3 | import common 4 | import team_common 5 | 6 | # 7 | # Route namespaces/list 8 | # 9 | 10 | union NamespaceType 11 | app_folder 12 | "App sandbox folder." 13 | shared_folder 14 | "Shared folder." 15 | team_folder 16 | "Top-level team-owned folder." 17 | team_member_folder 18 | "Team member's home folder." 19 | 20 | struct NamespaceMetadata 21 | "Properties of a namespace." 22 | 23 | name String 24 | "The name of this namespace." 25 | namespace_id common.SharedFolderId 26 | "The ID of this namespace." 27 | namespace_type NamespaceType 28 | "The type of this namespace." 29 | team_member_id team_common.TeamMemberId? 30 | "If this is a team member or app folder, the ID of the owning team member. 31 | Otherwise, this field is not present." 32 | 33 | example shared_folder 34 | name = "Marketing" 35 | namespace_id = "123456789" 36 | namespace_type = shared_folder 37 | 38 | example team_member_folder 39 | name = "Franz Ferdinand" 40 | namespace_id = "123456789" 41 | namespace_type = team_member_folder 42 | team_member_id = "dbmid:1234567" 43 | 44 | struct TeamNamespacesListResult 45 | "Result for :route:`namespaces/list`." 46 | 47 | namespaces List(NamespaceMetadata) 48 | "List of all namespaces the team can access." 49 | cursor String 50 | "Pass the cursor into :route:`namespaces/list/continue` to obtain 51 | additional namespaces. Note that duplicate namespaces may be returned." 52 | has_more Boolean 53 | "Is true if there are additional namespaces that have not been returned yet." 54 | 55 | example default 56 | namespaces = [shared_folder, team_member_folder] 57 | cursor = "ZtkX9_EHj3x7PMkVuFIhwKYXEpwpLwyxp9vMKomUhllil9q7eWiAu" 58 | has_more = false 59 | 60 | route namespaces/list(TeamNamespacesListArg, TeamNamespacesListResult, TeamNamespacesListError) 61 | "Returns a list of all team-accessible namespaces. This list includes team folders, 62 | shared folders containing team members, team members' home namespaces, and team members' 63 | app folders. Home namespaces and app folders are always owned by this team or members of the 64 | team, but shared folders may be owned by other users or other teams. Duplicates may occur in the 65 | list." 66 | 67 | attrs 68 | auth = "team" 69 | scope = "team_data.member" 70 | 71 | struct TeamNamespacesListArg 72 | 73 | limit UInt32(min_value=1, max_value=1000) = 1000 74 | "Specifying a value here has no effect." 75 | 76 | example default 77 | limit = 1 78 | 79 | # 80 | # Route namespaces/list/continue 81 | # 82 | 83 | route namespaces/list/continue(TeamNamespacesListContinueArg, TeamNamespacesListResult, TeamNamespacesListContinueError) 84 | "Once a cursor has been retrieved from :route:`namespaces/list`, use this to paginate 85 | through all team-accessible namespaces. Duplicates may occur in the list." 86 | 87 | attrs 88 | auth = "team" 89 | scope = "team_data.member" 90 | 91 | struct TeamNamespacesListContinueArg 92 | cursor String 93 | "Indicates from what point to get the next set of team-accessible namespaces." 94 | 95 | example default 96 | cursor = "ZtkX9_EHj3x7PMkVuFIhwKYXEpwpLwyxp9vMKomUhllil9q7eWiAu" 97 | 98 | union TeamNamespacesListContinueError extends TeamNamespacesListError 99 | invalid_cursor 100 | "The cursor is invalid." 101 | 102 | 103 | # 104 | # Generic Error 105 | # 106 | union TeamNamespacesListError 107 | invalid_arg 108 | "Argument passed in is invalid." 109 | -------------------------------------------------------------------------------- /team_policies.stone: -------------------------------------------------------------------------------- 1 | namespace team_policies 2 | 3 | struct TeamMemberPolicies 4 | "Policies governing team members." 5 | 6 | sharing TeamSharingPolicies 7 | "Policies governing sharing." 8 | emm_state EmmState 9 | "This describes the Enterprise Mobility Management (EMM) state for this team. 10 | This information can be used to understand if an organization is integrating with 11 | a third-party EMM vendor to further manage and apply restrictions upon the team's 12 | Dropbox usage on mobile devices. 13 | This is a new feature and in the future we'll be adding more new fields and additional 14 | documentation." 15 | office_addin OfficeAddInPolicy 16 | "The admin policy around the Dropbox Office Add-In for this team." 17 | suggest_members_policy SuggestMembersPolicy 18 | "The team policy on if teammembers are allowed to suggest users for admins to invite to the team." 19 | 20 | example default 21 | sharing = default 22 | emm_state = disabled 23 | office_addin = disabled 24 | suggest_members_policy = enabled 25 | 26 | struct TeamSharingPolicies 27 | "Policies governing sharing within and outside of the team." 28 | 29 | shared_folder_member_policy SharedFolderMemberPolicy 30 | "Who can join folders shared by team members." 31 | shared_folder_join_policy SharedFolderJoinPolicy 32 | "Which shared folders team members can join." 33 | shared_link_create_policy SharedLinkCreatePolicy 34 | "Who can view shared links owned by team members." 35 | group_creation_policy GroupCreation 36 | "Who can create groups." 37 | shared_folder_link_restriction_policy SharedFolderBlanketLinkRestrictionPolicy 38 | "Who can view links to content in shared folders." 39 | 40 | example default 41 | shared_folder_member_policy = team 42 | shared_folder_join_policy = from_anyone 43 | shared_link_create_policy = team_only 44 | group_creation_policy = admins_only 45 | shared_folder_link_restriction_policy = anyone 46 | 47 | # NOTE: we do not reuse sharing.MemberPolicy here since we may want to enable folder-specific member 48 | # policies that work on top of the broader team policies. 49 | union SharedFolderMemberPolicy 50 | "Policy governing who can be a member of a folder shared by a team member." 51 | 52 | team 53 | "Only a teammate can be a member of a folder shared by a team member." 54 | anyone 55 | "Anyone can be a member of a folder shared by a team member." 56 | 57 | union SharedFolderJoinPolicy 58 | "Policy governing which shared folders a team member can join." 59 | 60 | from_team_only 61 | "Team members can only join folders shared by teammates." 62 | from_anyone 63 | "Team members can join any shared folder, including those shared by users outside the team." 64 | 65 | union SharedLinkCreatePolicy 66 | "Policy governing the visibility of shared links. This policy can apply to newly created shared 67 | links, or all shared links." 68 | 69 | default_public 70 | "By default, anyone can access newly created shared links. 71 | No login will be required to access the shared links unless overridden." 72 | default_team_only 73 | "By default, only members of the same team can access newly created shared links. 74 | Login will be required to access the shared links unless overridden." 75 | team_only 76 | "Only members of the same team can access all shared links. 77 | Login will be required to access all shared links." 78 | default_no_one 79 | "Only people invited can access newly created links. 80 | Login will be required to access the shared links unless overridden." 81 | 82 | union SharedFolderBlanketLinkRestrictionPolicy 83 | "Policy governing whether shared folder membership is required to access shared links." 84 | 85 | members 86 | "Only members of shared folders can access folder content via shared link." 87 | anyone 88 | "Anyone can access folder content via shared link." 89 | 90 | union EmmState 91 | disabled 92 | "Emm token is disabled." 93 | optional 94 | "Emm token is optional." 95 | required 96 | "Emm token is required." 97 | 98 | union OfficeAddInPolicy 99 | disabled 100 | "Office Add-In is disabled." 101 | enabled 102 | "Office Add-In is enabled." 103 | 104 | union SsoPolicy 105 | disabled 106 | "Users will be able to sign in with their Dropbox credentials." 107 | optional 108 | "Users will be able to sign in with either their Dropbox or single sign-on credentials." 109 | required 110 | "Users will be required to sign in with their single sign-on credentials." 111 | 112 | union PaperDeploymentPolicy 113 | full 114 | "All team members have access to Paper." 115 | partial 116 | "Only whitelisted team members can access Paper. 117 | To see which user is whitelisted, check 'is_paper_whitelisted' on 'account/info'." 118 | 119 | union_closed RolloutMethod 120 | unlink_all 121 | "Unlink all." 122 | unlink_most_inactive 123 | "Unlink devices with the most inactivity." 124 | add_member_to_exceptions 125 | "Add member to Exceptions." 126 | 127 | union PaperEnabledPolicy 128 | disabled 129 | "Paper is disabled." 130 | enabled 131 | "Paper is enabled." 132 | unspecified 133 | "Unspecified policy." 134 | 135 | union PasswordControlMode 136 | disabled 137 | "Password is disabled." 138 | enabled 139 | "Password is enabled." 140 | 141 | union PasswordStrengthPolicy 142 | minimal_requirements 143 | "User passwords will adhere to the minimal password strength policy." 144 | moderate_password 145 | "User passwords will adhere to the moderate password strength policy." 146 | strong_password 147 | "User passwords will adhere to the very strong password strength policy." 148 | 149 | union TwoStepVerificationPolicy 150 | require_tfa_enable 151 | "Enabled require two factor authorization." 152 | require_tfa_disable 153 | "Disabled require two factor authorization." 154 | 155 | union TwoStepVerificationState 156 | required 157 | "Enabled require two factor authorization." 158 | optional 159 | "Optional require two factor authorization." 160 | disabled 161 | "Disabled require two factor authorization." 162 | 163 | union SmartSyncPolicy 164 | local 165 | "The specified content will be synced as local files by default." 166 | on_demand 167 | "The specified content will be synced as on-demand files by default." 168 | 169 | union_closed GroupCreation 170 | admins_and_members 171 | "Team admins and members can create groups." 172 | admins_only 173 | "Only team admins can create groups." 174 | 175 | union ShowcaseEnabledPolicy 176 | disabled 177 | "Showcase is disabled." 178 | enabled 179 | "Showcase is enabled." 180 | 181 | union ShowcaseDownloadPolicy 182 | disabled 183 | "Do not allow files to be downloaded from Showcases." 184 | enabled 185 | "Allow files to be downloaded from Showcases." 186 | 187 | union ShowcaseExternalSharingPolicy 188 | disabled 189 | "Do not allow showcases to be shared with people not on the team." 190 | enabled 191 | "Allow showcases to be shared with people not on the team." 192 | 193 | union CameraUploadsPolicyState 194 | disabled 195 | "Background camera uploads are disabled." 196 | enabled 197 | "Background camera uploads are allowed." 198 | 199 | union SmarterSmartSyncPolicyState 200 | disabled 201 | "Smarter Smart Sync feature is disabled." 202 | enabled 203 | "Smarter Smart Sync feature is enabled." 204 | 205 | union FileLockingPolicyState 206 | disabled 207 | "File locking feature is disabled." 208 | enabled 209 | "File locking feature is allowed." 210 | 211 | union PaperDefaultFolderPolicy 212 | everyone_in_team 213 | "Everyone in team will be the default option when creating a folder in Paper." 214 | invite_only 215 | "Invite only will be the default option when creating a folder in Paper." 216 | 217 | union PaperDesktopPolicy 218 | disabled 219 | "Do not allow team members to use Paper Desktop." 220 | enabled 221 | "Allow team members to use Paper Desktop." 222 | 223 | union SuggestMembersPolicy 224 | disabled 225 | "Suggest members is disabled." 226 | enabled 227 | "Suggest members is enabled." 228 | 229 | union ComputerBackupPolicyState 230 | disabled 231 | "Computer Backup feature is disabled." 232 | enabled 233 | "Computer Backup feature is enabled." 234 | default 235 | "Computer Backup defaults to ON for SSB teams, and OFF for Enterprise teams." 236 | 237 | union ExternalDriveBackupPolicyState 238 | disabled 239 | "External Drive Backup feature is disabled." 240 | enabled 241 | "External Drive Backup feature is enabled." 242 | default 243 | "External Drive Backup default value based on team tier." 244 | 245 | union FileProviderMigrationPolicyState 246 | disabled 247 | "Team admin has opted out of File Provider Migration for team members." 248 | enabled 249 | "Team admin has not opted out of File Provider Migration for team members." 250 | default 251 | "Team admin has default value based on team tier." 252 | -------------------------------------------------------------------------------- /team_reports.stone: -------------------------------------------------------------------------------- 1 | namespace team 2 | 3 | import common 4 | 5 | alias NumberPerDay = List(UInt64?) 6 | 7 | union TeamReportFailureReason 8 | temporary_error 9 | "We couldn't create the report, but we think this was a fluke. Everything should work if you try it again." 10 | many_reports_at_once 11 | "Too many other reports are being created right now. Try creating this report again once the others finish." 12 | too_much_data 13 | "We couldn't create the report. Try creating the report again with less data." 14 | 15 | example default 16 | many_reports_at_once = null 17 | 18 | 19 | struct DateRange 20 | "Input arguments that can be provided for most reports." 21 | start_date common.Date? 22 | "Optional starting date (inclusive). If start_date is None or too long ago, this field will 23 | be set to 6 months ago." 24 | end_date common.Date? 25 | "Optional ending date (exclusive)." 26 | 27 | union DateRangeError 28 | "Errors that can originate from problems in input arguments to reports." 29 | 30 | struct StorageBucket 31 | "Describes the number of users in a specific storage bucket." 32 | bucket String 33 | "The name of the storage bucket. 34 | For example, '1G' is a bucket of users with storage size up to 1 Giga." 35 | users UInt64 36 | "The number of people whose storage is in the range of this storage bucket." 37 | 38 | example default 39 | bucket = "1G" 40 | users = 21 41 | 42 | 43 | struct BaseDfbReport 44 | "Base report structure." 45 | start_date String 46 | "First date present in the results as 'YYYY-MM-DD' or None." 47 | 48 | # 49 | # get_storage 50 | # 51 | 52 | struct GetStorageReport extends BaseDfbReport 53 | "Storage Report Result. 54 | Each of the items in the storage report is an array of values, one value per day. 55 | If there is no data for a day, then the value will be None." 56 | 57 | total_usage NumberPerDay 58 | "Sum of the shared, unshared, and datastore usages, for each day." 59 | shared_usage NumberPerDay 60 | "Array of the combined size (bytes) of team members' shared folders, for each day." 61 | unshared_usage NumberPerDay 62 | "Array of the combined size (bytes) of team members' root namespaces, for each day." 63 | shared_folders NumberPerDay 64 | "Array of the number of shared folders owned by team members, for each day." 65 | member_storage_map List(List(StorageBucket)) 66 | "Array of storage summaries of team members' account sizes. 67 | Each storage summary is an array of key, value pairs, where each pair describes 68 | a storage bucket. 69 | The key indicates the upper bound of the bucket and the value is the 70 | number of users in that bucket. There is one such summary per day. 71 | If there is no data for a day, the storage summary will be empty." 72 | 73 | route reports/get_storage(DateRange, GetStorageReport, DateRangeError) deprecated 74 | "Retrieves reporting data about a team's storage usage. 75 | Deprecated: Will be removed on July 1st 2021." 76 | attrs 77 | auth = "team" 78 | scope = "team_info.read" 79 | 80 | # 81 | # get_activity 82 | # 83 | 84 | struct GetActivityReport extends BaseDfbReport 85 | "Activity Report Result. 86 | Each of the items in the storage report is an array of values, one value per day. 87 | If there is no data for a day, then the value will be None." 88 | 89 | adds NumberPerDay 90 | "Array of total number of adds by team members." 91 | edits NumberPerDay 92 | "Array of number of edits by team members. 93 | If the same user edits the same file multiple times this is counted as a single edit." 94 | deletes NumberPerDay 95 | "Array of total number of deletes by team members." 96 | active_users_28_day NumberPerDay 97 | "Array of the number of users who have been active in the last 28 days." 98 | active_users_7_day NumberPerDay 99 | "Array of the number of users who have been active in the last week." 100 | active_users_1_day NumberPerDay 101 | "Array of the number of users who have been active in the last day." 102 | active_shared_folders_28_day NumberPerDay 103 | "Array of the number of shared folders with some activity in the last 28 days." 104 | active_shared_folders_7_day NumberPerDay 105 | "Array of the number of shared folders with some activity in the last week." 106 | active_shared_folders_1_day NumberPerDay 107 | "Array of the number of shared folders with some activity in the last day." 108 | shared_links_created NumberPerDay 109 | "Array of the number of shared links created." 110 | shared_links_viewed_by_team NumberPerDay 111 | "Array of the number of views by team users to shared links created by the team." 112 | shared_links_viewed_by_outside_user NumberPerDay 113 | "Array of the number of views by users outside of the team to shared links created by the team." 114 | shared_links_viewed_by_not_logged_in NumberPerDay 115 | "Array of the number of views by non-logged-in users to shared links created by the team." 116 | shared_links_viewed_total NumberPerDay 117 | "Array of the total number of views to shared links created by the team." 118 | 119 | route reports/get_activity(DateRange, GetActivityReport, DateRangeError) deprecated 120 | "Retrieves reporting data about a team's user activity. 121 | Deprecated: Will be removed on July 1st 2021." 122 | attrs 123 | auth = "team" 124 | scope = "team_info.read" 125 | 126 | # 127 | # get_membership 128 | # 129 | 130 | struct GetMembershipReport extends BaseDfbReport 131 | "Membership Report Result. 132 | Each of the items in the storage report is an array of values, one value per day. 133 | If there is no data for a day, then the value will be None." 134 | 135 | team_size NumberPerDay 136 | "Team size, for each day." 137 | pending_invites NumberPerDay 138 | "The number of pending invites to the team, for each day." 139 | members_joined NumberPerDay 140 | "The number of members that joined the team, for each day." 141 | suspended_members NumberPerDay 142 | "The number of suspended team members, for each day." 143 | licenses NumberPerDay 144 | "The total number of licenses the team has, for each day." 145 | 146 | 147 | 148 | route reports/get_membership(DateRange, GetMembershipReport, DateRangeError) deprecated 149 | "Retrieves reporting data about a team's membership. 150 | Deprecated: Will be removed on July 1st 2021." 151 | attrs 152 | auth = "team" 153 | scope = "team_info.read" 154 | 155 | # 156 | # get_devices 157 | # 158 | 159 | 160 | struct DevicesActive 161 | "Each of the items is an array of values, one value per day. 162 | The value is the number of devices active within a time window, ending with that day. 163 | 164 | If there is no data for a day, then the value will be None." 165 | 166 | windows NumberPerDay 167 | "Array of number of linked windows (desktop) clients with activity." 168 | macos NumberPerDay 169 | "Array of number of linked mac (desktop) clients with activity." 170 | linux NumberPerDay 171 | "Array of number of linked linus (desktop) clients with activity." 172 | ios NumberPerDay 173 | "Array of number of linked ios devices with activity." 174 | android NumberPerDay 175 | "Array of number of linked android devices with activity." 176 | other NumberPerDay 177 | "Array of number of other linked devices (blackberry, windows phone, etc) 178 | with activity." 179 | total NumberPerDay 180 | "Array of total number of linked clients with activity." 181 | 182 | struct GetDevicesReport extends BaseDfbReport 183 | "Devices Report Result. Contains subsections for different time ranges of activity. 184 | Each of the items in each subsection of the storage report is an array of values, 185 | one value per day. 186 | If there is no data for a day, then the value will be None." 187 | 188 | active_1_day DevicesActive 189 | "Report of the number of devices active in the last day." 190 | active_7_day DevicesActive 191 | "Report of the number of devices active in the last 7 days." 192 | active_28_day DevicesActive 193 | "Report of the number of devices active in the last 28 days." 194 | 195 | 196 | route reports/get_devices(DateRange, GetDevicesReport, DateRangeError) deprecated 197 | "Retrieves reporting data about a team's linked devices. 198 | Deprecated: Will be removed on July 1st 2021." 199 | 200 | attrs 201 | auth = "team" 202 | scope = "team_info.read" 203 | -------------------------------------------------------------------------------- /team_secondary_mails.stone: -------------------------------------------------------------------------------- 1 | namespace team 2 | 3 | import common 4 | import secondary_emails 5 | 6 | alias SecondaryEmail = secondary_emails.SecondaryEmail 7 | 8 | 9 | struct UserSecondaryEmailsArg 10 | "User and a list of secondary emails." 11 | user UserSelectorArg 12 | secondary_emails List(common.EmailAddress) 13 | 14 | example default 15 | user = default 16 | secondary_emails = ["bob2@hotmail.com", "bob@inst.gov"] 17 | 18 | 19 | # 20 | # add secondary emails 21 | # 22 | 23 | 24 | union AddSecondaryEmailResult 25 | "Result of trying to add a secondary email to a user. 26 | 'success' is the only value indicating that a secondary email was successfully added to a user. 27 | The other values explain the type of error that occurred, and include the email for which the error occurred." 28 | 29 | success SecondaryEmail 30 | "Describes a secondary email that was successfully added to a user." 31 | 32 | unavailable common.EmailAddress 33 | "Secondary email is not available to be claimed by the user." 34 | 35 | already_pending common.EmailAddress 36 | "Secondary email is already a pending email for the user." 37 | 38 | already_owned_by_user common.EmailAddress 39 | "Secondary email is already a verified email for the user." 40 | 41 | reached_limit common.EmailAddress 42 | "User already has the maximum number of secondary emails allowed." 43 | 44 | transient_error common.EmailAddress 45 | "A transient error occurred. Please try again later." 46 | 47 | too_many_updates common.EmailAddress 48 | "An error occurred due to conflicting updates. Please try again later." 49 | 50 | unknown_error common.EmailAddress 51 | "An unknown error occurred." 52 | 53 | rate_limited common.EmailAddress 54 | "Too many emails are being sent to this email address. Please try again later." 55 | 56 | example default 57 | success = default 58 | 59 | example unavailable 60 | unavailable = "alice@example.com" 61 | 62 | 63 | struct UserSecondaryEmailsResult 64 | user UserSelectorArg 65 | results List(AddSecondaryEmailResult) 66 | 67 | example default 68 | user = default 69 | results = [default, unavailable] 70 | 71 | 72 | union UserAddResult 73 | "Result of trying to add secondary emails to a user. 74 | 'success' is the only value indicating that a user was successfully retrieved for adding secondary emails. 75 | The other values explain the type of error that occurred, and include the user for which the error occurred." 76 | 77 | success UserSecondaryEmailsResult 78 | "Describes a user and the results for each attempt to add a secondary email." 79 | 80 | invalid_user UserSelectorArg 81 | "Specified user is not a valid target for adding secondary emails." 82 | 83 | unverified UserSelectorArg 84 | "Secondary emails can only be added to verified users." 85 | 86 | placeholder_user UserSelectorArg 87 | "Secondary emails cannot be added to placeholder users." 88 | 89 | example default 90 | success = default 91 | 92 | example invalid 93 | invalid_user = default 94 | 95 | 96 | struct AddSecondaryEmailsArg 97 | new_secondary_emails List(UserSecondaryEmailsArg) 98 | "List of users and secondary emails to add." 99 | 100 | example default 101 | new_secondary_emails = [default] 102 | 103 | 104 | struct AddSecondaryEmailsResult 105 | results List(UserAddResult) 106 | "List of users and secondary email results." 107 | 108 | example default 109 | results = [default, invalid] 110 | 111 | 112 | union AddSecondaryEmailsError 113 | "Error returned when adding secondary emails fails." 114 | 115 | secondary_emails_disabled 116 | "Secondary emails are disabled for the team." 117 | 118 | too_many_emails 119 | "A maximum of 20 secondary emails can be added in a single call." 120 | 121 | 122 | route members/secondary_emails/add(AddSecondaryEmailsArg, AddSecondaryEmailsResult, AddSecondaryEmailsError) 123 | "Add secondary emails to users. 124 | 125 | Permission : Team member management. 126 | 127 | Emails that are on verified domains will be verified automatically. 128 | For each email address not on a verified domain a verification email will be sent." 129 | 130 | attrs 131 | auth = "team" 132 | scope = "members.write" 133 | 134 | # 135 | # resend verification emails 136 | # 137 | 138 | 139 | struct ResendVerificationEmailArg 140 | emails_to_resend List(UserSecondaryEmailsArg) 141 | "List of users and secondary emails to resend verification emails to." 142 | 143 | example default 144 | emails_to_resend = [default] 145 | 146 | 147 | union ResendSecondaryEmailResult 148 | "Result of trying to resend verification email to a secondary email address. 149 | 'success' is the only value indicating that a verification email was successfully sent. 150 | The other values explain the type of error that occurred, and include the email for which the error occurred." 151 | 152 | success common.EmailAddress 153 | "A verification email was successfully sent to the secondary email address." 154 | 155 | not_pending common.EmailAddress 156 | "This secondary email address is not pending for the user." 157 | 158 | rate_limited common.EmailAddress 159 | "Too many emails are being sent to this email address. Please try again later." 160 | 161 | example default 162 | success = "alice@example.com" 163 | 164 | 165 | struct UserResendEmailsResult 166 | user UserSelectorArg 167 | results List(ResendSecondaryEmailResult) 168 | 169 | example default 170 | user = default 171 | results = [default] 172 | 173 | 174 | union UserResendResult 175 | "Result of trying to resend verification emails to a user. 176 | 'success' is the only value indicating that a user was successfully retrieved for sending verification emails. 177 | The other values explain the type of error that occurred, and include the user for which the error occurred." 178 | 179 | success UserResendEmailsResult 180 | "Describes a user and the results for each attempt to resend verification emails." 181 | 182 | invalid_user UserSelectorArg 183 | "Specified user is not a valid target for resending verification emails." 184 | 185 | example default 186 | success = default 187 | 188 | example invalid 189 | invalid_user = default 190 | 191 | 192 | struct ResendVerificationEmailResult 193 | "List of users and resend results." 194 | results List(UserResendResult) 195 | 196 | example default 197 | results = [default] 198 | 199 | 200 | route members/secondary_emails/resend_verification_emails(ResendVerificationEmailArg, ResendVerificationEmailResult, Void) 201 | "Resend secondary email verification emails. 202 | 203 | Permission : Team member management." 204 | 205 | attrs 206 | auth = "team" 207 | scope = "members.write" 208 | 209 | 210 | # 211 | # delete secondary emails 212 | # 213 | 214 | 215 | struct DeleteSecondaryEmailsArg 216 | emails_to_delete List(UserSecondaryEmailsArg) 217 | "List of users and their secondary emails to delete." 218 | 219 | example default 220 | emails_to_delete = [default] 221 | 222 | 223 | union DeleteSecondaryEmailResult 224 | "Result of trying to delete a secondary email address. 225 | 'success' is the only value indicating that a secondary email was successfully deleted. 226 | The other values explain the type of error that occurred, and include the email for which the error occurred." 227 | 228 | success common.EmailAddress 229 | "The secondary email was successfully deleted." 230 | 231 | not_found common.EmailAddress 232 | "The email address was not found for the user." 233 | 234 | cannot_remove_primary common.EmailAddress 235 | "The email address is the primary email address of the user, and cannot be removed." 236 | 237 | example default 238 | success = "alice@example.com" 239 | 240 | example not_found 241 | not_found = "alic@example.com" 242 | 243 | 244 | struct UserDeleteEmailsResult 245 | user UserSelectorArg 246 | results List(DeleteSecondaryEmailResult) 247 | 248 | example default 249 | user = default 250 | results = [default, not_found] 251 | 252 | 253 | union UserDeleteResult 254 | "Result of trying to delete a user's secondary emails. 255 | 'success' is the only value indicating that a user was successfully retrieved for deleting secondary emails. 256 | The other values explain the type of error that occurred, and include the user for which the error occurred." 257 | 258 | success UserDeleteEmailsResult 259 | "Describes a user and the results for each attempt to delete a secondary email." 260 | 261 | invalid_user UserSelectorArg 262 | "Specified user is not a valid target for deleting secondary emails." 263 | 264 | example default 265 | success = default 266 | 267 | example invalid_user 268 | invalid_user = default 269 | 270 | 271 | struct DeleteSecondaryEmailsResult 272 | results List(UserDeleteResult) 273 | 274 | example default 275 | results = [default] 276 | 277 | 278 | route members/secondary_emails/delete(DeleteSecondaryEmailsArg, DeleteSecondaryEmailsResult, Void) 279 | "Delete secondary emails from users 280 | 281 | Permission : Team member management. 282 | 283 | Users will be notified of deletions of verified secondary emails at both the secondary email and their primary email." 284 | 285 | attrs 286 | auth = "team" 287 | scope = "members.write" 288 | -------------------------------------------------------------------------------- /team_sharing_allowlist.stone: -------------------------------------------------------------------------------- 1 | namespace team 2 | 3 | import common 4 | 5 | struct SharingAllowlistAddArgs 6 | "Structure representing Approve List entries. Domain and emails are supported. 7 | At least one entry of any supported type is required." 8 | domains List(String)? 9 | "List of domains represented by valid string representation (RFC-1034/5)." 10 | emails List(String)? 11 | "List of emails represented by valid string representation (RFC-5322/822)." 12 | 13 | example default 14 | domains = ["test-domain.com", "subdomain.some.com"] 15 | emails = ["adam@test-domain.com", "john@some.com"] 16 | 17 | struct SharingAllowlistAddResponse 18 | "This struct is empty. The comment here is intentionally emitted to avoid indentation issues with Stone." 19 | 20 | union SharingAllowlistAddError 21 | malformed_entry String 22 | "One of provided values is not valid." 23 | no_entries_provided 24 | "Neither single domain nor email provided." 25 | too_many_entries_provided 26 | "Too many entries provided within one call." 27 | team_limit_reached 28 | "Team entries limit reached." 29 | unknown_error 30 | "Unknown error." 31 | entries_already_exist String 32 | "Entries already exists." 33 | 34 | 35 | struct SharingAllowlistListArg 36 | limit UInt32(max_value=1000, min_value=1) = 1000 37 | "The number of entries to fetch at one time." 38 | 39 | example default 40 | limit = 100 41 | 42 | struct SharingAllowlistListContinueArg 43 | cursor String 44 | "The cursor returned from a previous call to :route:`sharing_allowlist/list` or :route:`sharing_allowlist/list/continue`." 45 | 46 | example default 47 | cursor = "dGVzdF9jdXJzb3IK" 48 | 49 | struct SharingAllowlistListError 50 | "This struct is empty. The comment here is intentionally emitted to avoid indentation issues with Stone." 51 | 52 | struct SharingAllowlistListResponse 53 | domains List(String) 54 | "List of domains represented by valid string representation (RFC-1034/5)." 55 | emails List(String) 56 | "List of emails represented by valid string representation (RFC-5322/822)." 57 | cursor String = "" 58 | "If this is nonempty, there are more entries that can be fetched with :route:`sharing_allowlist/list/continue`." 59 | has_more Boolean = false 60 | "if true indicates that more entries can be fetched with :route:`sharing_allowlist/list/continue`." 61 | 62 | example default 63 | domains = ["test-domain.com", "subdomain.some.com"] 64 | emails = ["adam@test-domain.com", "john@some.com"] 65 | cursor = "dGVzdF9jdXJzb3IK" 66 | has_more = true 67 | 68 | union SharingAllowlistListContinueError 69 | invalid_cursor 70 | "Provided cursor is not valid." 71 | 72 | struct SharingAllowlistRemoveArgs 73 | domains List(String)? 74 | "List of domains represented by valid string representation (RFC-1034/5)." 75 | emails List(String)? 76 | "List of emails represented by valid string representation (RFC-5322/822)." 77 | 78 | example default 79 | domains = ["test-domain.com", "subdomain.some.com"] 80 | emails = ["adam@test-domain.com", "john@some.com"] 81 | 82 | 83 | struct SharingAllowlistRemoveResponse 84 | "This struct is empty. The comment here is intentionally emitted to avoid indentation issues with Stone." 85 | 86 | union SharingAllowlistRemoveError 87 | malformed_entry String 88 | "One of provided values is not valid." 89 | entries_do_not_exist String 90 | "One or more provided values do not exist." 91 | no_entries_provided 92 | "Neither single domain nor email provided." 93 | too_many_entries_provided 94 | "Too many entries provided within one call." 95 | unknown_error 96 | "Unknown error." 97 | 98 | 99 | route sharing_allowlist/add (SharingAllowlistAddArgs, SharingAllowlistAddResponse, SharingAllowlistAddError) 100 | "Endpoint adds Approve List entries. Changes are effective immediately. 101 | Changes are committed in transaction. In case of single validation error - all entries are rejected. 102 | Valid domains (RFC-1034/5) and emails (RFC-5322/822) are accepted. 103 | Added entries cannot overflow limit of 10000 entries per team. 104 | Maximum 100 entries per call is allowed." 105 | 106 | attrs 107 | auth = "team" 108 | is_preview = true 109 | scope = "team_info.write" 110 | 111 | route sharing_allowlist/list (SharingAllowlistListArg, SharingAllowlistListResponse, SharingAllowlistListError) 112 | "Lists Approve List entries for given team, from newest to oldest, returning 113 | up to `limit` entries at a time. If there are more than `limit` entries 114 | associated with the current team, more can be fetched by passing the 115 | returned `cursor` to :route:`sharing_allowlist/list/continue`." 116 | 117 | attrs 118 | auth = "team" 119 | is_preview = true 120 | scope = "team_info.read" 121 | 122 | route sharing_allowlist/list/continue (SharingAllowlistListContinueArg, SharingAllowlistListResponse, SharingAllowlistListContinueError) 123 | "Lists entries associated with given team, starting from a the cursor. See :route:`sharing_allowlist/list`." 124 | 125 | attrs 126 | auth = "team" 127 | is_preview = true 128 | scope = "team_info.read" 129 | 130 | route sharing_allowlist/remove (SharingAllowlistRemoveArgs, SharingAllowlistRemoveResponse, SharingAllowlistRemoveError) 131 | "Endpoint removes Approve List entries. Changes are effective immediately. 132 | Changes are committed in transaction. In case of single validation error - all entries are rejected. 133 | Valid domains (RFC-1034/5) and emails (RFC-5322/822) are accepted. 134 | Entries being removed have to be present on the list. 135 | Maximum 1000 entries per call is allowed." 136 | 137 | attrs 138 | auth = "team" 139 | is_preview = true 140 | scope = "team_info.write" 141 | 142 | -------------------------------------------------------------------------------- /users.stone: -------------------------------------------------------------------------------- 1 | namespace users 2 | "This namespace contains endpoints and data types for user management." 3 | 4 | import common 5 | 6 | import team_common 7 | 8 | import team_policies 9 | 10 | import users_common 11 | 12 | # 13 | # Route: get_account 14 | # 15 | 16 | route get_account (GetAccountArg, BasicAccount, GetAccountError) 17 | "Get information about a user's account." 18 | 19 | attrs 20 | allow_app_folder_app = true 21 | scope = "sharing.read" 22 | 23 | struct GetAccountArg 24 | account_id users_common.AccountId 25 | "A user's account identifier." 26 | 27 | example default 28 | account_id = "dbid:AAH4f99T0taONIb-OurWxbNQ6ywGRopQngc" 29 | 30 | union GetAccountError 31 | no_account 32 | "The specified :field:`GetAccountArg.account_id` does not exist." 33 | 34 | struct Account 35 | "The amount of detail revealed about an account depends on the user 36 | being queried and the user making the query." 37 | 38 | account_id users_common.AccountId 39 | "The user's unique Dropbox ID." 40 | 41 | name Name 42 | "Details of a user's name." 43 | 44 | email String 45 | "The user's email address. Do not rely on this without checking the 46 | :field:`email_verified` field. Even then, it's possible that the user 47 | has since lost access to their email." 48 | 49 | email_verified Boolean 50 | "Whether the user has verified their email address." 51 | 52 | profile_photo_url String? 53 | "URL for the photo representing the user, if one is set." 54 | 55 | disabled Boolean 56 | "Whether the user has been disabled." 57 | 58 | example default 59 | account_id = "dbid:AAH4f99T0taONIb-OurWxbNQ6ywGRopQngc" 60 | name = default 61 | email = "franz@dropbox.com" 62 | email_verified = true 63 | profile_photo_url = "https://dl-web.dropbox.com/account_photo/get/dbaphid%3AAAHWGmIXV3sUuOmBfTz0wPsiqHUpBWvv3ZA?vers=1556069330102&size=128x128" 64 | disabled = false 65 | 66 | struct BasicAccount extends Account 67 | "Basic information about any account." 68 | 69 | is_teammate Boolean 70 | "Whether this user is a teammate of the current user. If this account 71 | is the current user's account, then this will be :val:`true`." 72 | 73 | team_member_id String? 74 | "The user's unique team member id. This field will only be present if 75 | the user is part of a team and :field:`is_teammate` is :val:`true`." 76 | 77 | example default 78 | account_id = "dbid:AAH4f99T0taONIb-OurWxbNQ6ywGRopQngc" 79 | name = default 80 | email = "franz@dropbox.com" 81 | email_verified = true 82 | profile_photo_url = "https://dl-web.dropbox.com/account_photo/get/dbaphid%3AAAHWGmIXV3sUuOmBfTz0wPsiqHUpBWvv3ZA?vers=1556069330102&size=128x128" 83 | is_teammate = false 84 | disabled = false 85 | 86 | example team 87 | account_id = "dbid:AAH4f99T0taONIb-OurWxbNQ6ywGRopQngc" 88 | name = default 89 | email = "franz@dropbox.com" 90 | email_verified = true 91 | profile_photo_url = "https://dl-web.dropbox.com/account_photo/get/dbaphid%3AAAHWGmIXV3sUuOmBfTz0wPsiqHUpBWvv3ZA?vers=1556069330102&size=128x128" 92 | is_teammate = true 93 | team_member_id = "dbmid:AAHhy7WsR0x-u4ZCqiDl5Fz5zvuL3kmspwU" 94 | disabled = false 95 | # 96 | # Route: get_current_account 97 | # 98 | 99 | route get_current_account (Void, FullAccount, Void) 100 | "Get information about the current user's account." 101 | 102 | attrs 103 | allow_app_folder_app = true 104 | select_admin_mode = "whole_team" 105 | scope = "account_info.read" 106 | 107 | struct FullAccount extends Account 108 | "Detailed information about the current user's account." 109 | 110 | country String(min_length=2, max_length=2)? 111 | "The user's two-letter country code, if available. Country codes are 112 | based on :link:`ISO 3166-1 http://en.wikipedia.org/wiki/ISO_3166-1`." 113 | locale String(min_length=2) 114 | "The language that the user specified. Locale tags will be 115 | :link:`IETF language tags http://en.wikipedia.org/wiki/IETF_language_tag`." 116 | referral_link String 117 | "The user's :link:`referral link https://www.dropbox.com/referrals`." 118 | team FullTeam? 119 | "If this account is a member of a team, information about that team." 120 | team_member_id String? 121 | "This account's unique team member id. This field will only be present if 122 | :field:`team` is present." 123 | is_paired Boolean 124 | "Whether the user has a personal and work account. If the current 125 | account is personal, then :field:`team` will always be :val:`null`, 126 | but :field:`is_paired` will indicate if a work account is linked." 127 | account_type users_common.AccountType 128 | "What type of account this user has." 129 | root_info common.RootInfo 130 | "The root info for this account." 131 | 132 | example default 133 | "Paired account." 134 | account_id = "dbid:AAH4f99T0taONIb-OurWxbNQ6ywGRopQngc" 135 | name = default 136 | email = "franz@dropbox.com" 137 | email_verified = true 138 | country = "US" 139 | locale = "en" 140 | referral_link = "https://db.tt/ZITNuhtI" 141 | team = default 142 | team_member_id = "dbmid:AAHhy7WsR0x-u4ZCqiDl5Fz5zvuL3kmspwU" 143 | is_paired = true 144 | account_type = business 145 | disabled = false 146 | root_info = default 147 | 148 | example unpaired 149 | "A personal account that is not paired with a team." 150 | account_id = "dbid:AAH4f99T0taONIb-OurWxbNQ6ywGRopQngc" 151 | name = default 152 | email = "franz@gmail.com" 153 | email_verified = false 154 | country = "US" 155 | locale = "en" 156 | referral_link = "https://db.tt/ZITNuhtI" 157 | team = null 158 | is_paired = false 159 | account_type = default 160 | profile_photo_url = "https://dl-web.dropbox.com/account_photo/get/dbaphid%3AAAHWGmIXV3sUuOmBfTz0wPsiqHUpBWvv3ZA?vers=1556069330102&size=128x128" 161 | disabled = false 162 | root_info = default 163 | 164 | struct Team 165 | "Information about a team." 166 | 167 | id String 168 | "The team's unique ID." 169 | name String 170 | "The name of the team." 171 | 172 | example default 173 | id = "dbtid:AAFdgehTzw7WlXhZJsbGCLePe8RvQGYDr-I" 174 | name = "Acme, Inc." 175 | 176 | struct FullTeam extends Team 177 | "Detailed information about a team." 178 | 179 | sharing_policies team_policies.TeamSharingPolicies 180 | "Team policies governing sharing." 181 | 182 | office_addin_policy team_policies.OfficeAddInPolicy 183 | "Team policy governing the use of the Office Add-In." 184 | 185 | example default 186 | id = "dbtid:AAFdgehTzw7WlXhZJsbGCLePe8RvQGYDr-I" 187 | name = "Acme, Inc." 188 | sharing_policies = default 189 | office_addin_policy = disabled 190 | 191 | struct Name 192 | "Representations for a person's name to assist with internationalization." 193 | 194 | given_name String 195 | "Also known as a first name." 196 | 197 | surname String 198 | "Also known as a last name or family name." 199 | 200 | familiar_name String 201 | "Locale-dependent name. In the US, a person's familiar name is their 202 | :field:`given_name`, but elsewhere, it could be any combination of a 203 | person's :field:`given_name` and :field:`surname`." 204 | 205 | display_name String 206 | "A name that can be used directly to represent the name of a user's 207 | Dropbox account." 208 | 209 | abbreviated_name String 210 | "An abbreviated form of the person's name. Their initials in most locales." 211 | 212 | example default 213 | given_name = "Franz" 214 | surname = "Ferdinand" 215 | familiar_name = "Franz" 216 | display_name = "Franz Ferdinand (Personal)" 217 | abbreviated_name = "FF" 218 | 219 | example second_name 220 | given_name = "Zexy Desperado" 221 | surname = "Desperado" 222 | familiar_name = "Zexy" 223 | display_name = "Zexy Desperado (Personal)" 224 | abbreviated_name = "ZD" 225 | 226 | # 227 | # Route: get_space_usage 228 | # 229 | 230 | route get_space_usage(Void, SpaceUsage, Void) 231 | "Get the space usage information for the current user's account." 232 | 233 | attrs 234 | allow_app_folder_app = true 235 | scope = "account_info.read" 236 | 237 | struct SpaceUsage 238 | "Information about a user's space usage and quota." 239 | 240 | used UInt64 241 | "The user's total space usage (bytes)." 242 | allocation SpaceAllocation 243 | "The user's space allocation." 244 | 245 | example default 246 | used = 314159265 247 | allocation = default 248 | 249 | union SpaceAllocation 250 | "Space is allocated differently based on the type of account." 251 | 252 | individual IndividualSpaceAllocation 253 | "The user's space allocation applies only to their individual account." 254 | team TeamSpaceAllocation 255 | "The user shares space with other members of their team." 256 | 257 | example default 258 | individual = default 259 | 260 | struct IndividualSpaceAllocation 261 | allocated UInt64 262 | "The total space allocated to the user's account (bytes)." 263 | 264 | example default 265 | allocated = 10000000000 266 | 267 | struct TeamSpaceAllocation 268 | used UInt64 269 | "The total space currently used by the user's team (bytes)." 270 | allocated UInt64 271 | "The total space allocated to the user's team (bytes)." 272 | user_within_team_space_allocated UInt64 273 | "The total space allocated to the user within its team allocated space (0 means that 274 | no restriction is imposed on the user's quota within its team)." 275 | user_within_team_space_limit_type team_common.MemberSpaceLimitType 276 | "The type of the space limit imposed on the team member (off, alert_only, stop_sync)." 277 | user_within_team_space_used_cached UInt64 278 | "An accurate cached calculation of a team member's total space usage (bytes)." 279 | 280 | example default 281 | used = 27182818284 282 | allocated = 100000000000 283 | user_within_team_space_allocated = 2000000000 284 | user_within_team_space_limit_type = stop_sync 285 | user_within_team_space_used_cached = 314159265 286 | 287 | # 288 | # Route: get_account_batch 289 | # 290 | 291 | route get_account_batch (GetAccountBatchArg, GetAccountBatchResult, GetAccountBatchError) 292 | "Get information about multiple user accounts. At most 300 accounts may be queried 293 | per request." 294 | 295 | attrs 296 | allow_app_folder_app = true 297 | scope = "sharing.read" 298 | 299 | struct GetAccountBatchArg 300 | account_ids List(users_common.AccountId, min_items=1) 301 | "List of user account identifiers. Should not contain any duplicate account IDs." 302 | 303 | example default 304 | account_ids = ["dbid:AAH4f99T0taONIb-OurWxbNQ6ywGRopQngc", "dbid:AAH1Vcz-DVoRDeixtr_OA8oUGgiqhs4XPOQ"] 305 | 306 | alias GetAccountBatchResult = List(BasicAccount) 307 | 308 | union GetAccountBatchError 309 | no_account users_common.AccountId 310 | "The value is an account ID specified in :field:`GetAccountBatchArg.account_ids` 311 | that does not exist." 312 | 313 | example default 314 | no_account = "dbid:AAH4f99T0taONIb-OurWxbNQ6ywGRopQngc" 315 | 316 | # 317 | # User Features 318 | # 319 | 320 | union UserFeature 321 | "A set of features that a Dropbox User account may have configured." 322 | 323 | paper_as_files 324 | "This feature contains information about how the user's Paper files are stored." 325 | 326 | file_locking 327 | "This feature allows users to lock files in order to restrict other users from editing them." 328 | 329 | 330 | union UserFeatureValue 331 | "Values that correspond to entries in :type:`UserFeature`." 332 | 333 | paper_as_files PaperAsFilesValue 334 | file_locking FileLockingValue 335 | 336 | example paper_as_files_enabled 337 | paper_as_files = paper_as_files_enabled 338 | 339 | union PaperAsFilesValue 340 | "The value for :field:`UserFeature.paper_as_files`. " 341 | 342 | enabled Boolean 343 | "When this value is true, the user's Paper docs are accessible in Dropbox with the .paper 344 | extension and must be accessed via the /files endpoints. When this value is 345 | false, the user's Paper docs are stored separate from Dropbox files and folders and should 346 | be accessed via the /paper endpoints." 347 | 348 | example paper_as_files_enabled 349 | enabled = true 350 | 351 | union FileLockingValue 352 | "The value for :field:`UserFeature.file_locking`. " 353 | 354 | enabled Boolean 355 | "When this value is True, the user can lock files in shared directories. When the value is 356 | False the user can unlock the files they have locked or request to unlock files locked by 357 | others." 358 | 359 | example file_locking_enabled 360 | enabled = true 361 | # 362 | # Route: feature/get_value_batch 363 | # 364 | 365 | struct UserFeaturesGetValuesBatchArg 366 | features List(UserFeature) 367 | "A list of features in :type:`UserFeature`. If the list is empty, 368 | this route will return :type:`UserFeaturesGetValuesBatchError`." 369 | 370 | example listOfFeatures 371 | features = [paper_as_files, file_locking] 372 | 373 | struct UserFeaturesGetValuesBatchResult 374 | values List(UserFeatureValue) 375 | 376 | example listOfValues 377 | values = [paper_as_files_enabled] 378 | 379 | union UserFeaturesGetValuesBatchError 380 | empty_features_list 381 | "At least one :type:`UserFeature` must be included in the 382 | :type:`UserFeaturesGetValuesBatchArg`.features list." 383 | 384 | route features/get_values(UserFeaturesGetValuesBatchArg, UserFeaturesGetValuesBatchResult, UserFeaturesGetValuesBatchError) 385 | "Get a list of feature values that may be configured for the current account." 386 | 387 | attrs 388 | allow_app_folder_app = true 389 | scope = "account_info.read" 390 | -------------------------------------------------------------------------------- /users_common.stone: -------------------------------------------------------------------------------- 1 | namespace users_common 2 | "This namespace contains common data types used within the users namespace." 3 | 4 | import common 5 | 6 | alias AccountId = String(min_length=40, max_length=40) 7 | 8 | union_closed AccountType 9 | "What type of account this user has." 10 | 11 | basic 12 | "The basic account type." 13 | pro 14 | "The Dropbox Pro account type." 15 | business 16 | "The Dropbox Business account type." 17 | 18 | example default 19 | basic = null 20 | 21 | example business 22 | business = null 23 | --------------------------------------------------------------------------------