diff --git a/docs/tables/googleworkspace_calendar.md b/docs/tables/googleworkspace_calendar.md index 6ab1880..ac2b3f6 100644 --- a/docs/tables/googleworkspace_calendar.md +++ b/docs/tables/googleworkspace_calendar.md @@ -13,6 +13,7 @@ The `googleworkspace_calendar` table provides insights into calendars within Goo **Important Notes** - You must specify the `id` in the `where` or join clause (`where id=`, `join googleworkspace_calendar c on c.id=`) to query this table. +- **Required OAuth Scope**: `https://www.googleapis.com/auth/calendar.readonly`, for more details see required [Authorization scope](https://developers.google.com/workspace/calendar/api/v3/reference/calendars/get#auth) ## Examples @@ -39,4 +40,4 @@ from googleworkspace_calendar where id = 'user@domain.com'; -``` \ No newline at end of file +``` diff --git a/docs/tables/googleworkspace_calendar_event.md b/docs/tables/googleworkspace_calendar_event.md index 6712900..52c5e34 100644 --- a/docs/tables/googleworkspace_calendar_event.md +++ b/docs/tables/googleworkspace_calendar_event.md @@ -13,6 +13,7 @@ The `googleworkspace_calendar_event` table provides insights into Calendar Event **Important Notes** - You must specify the `calendar_id` in the `where` or join clause (`where calendar_id=`, `join googleworkspace_calendar_event e on e.calendar_id=`) to query this table. +- **Required OAuth Scope**: `https://www.googleapis.com/auth/calendar.readonly`, for more details see required [Authorization scope](https://developers.google.com/workspace/calendar/api/v3/reference/events/list#auth) ## Examples @@ -208,4 +209,4 @@ where and start_time >= date('now') and start_time < date('now', '+30 days') order by start_time; -``` \ No newline at end of file +``` diff --git a/docs/tables/googleworkspace_calendar_my_event.md b/docs/tables/googleworkspace_calendar_my_event.md index 1547d9c..40c3cf4 100644 --- a/docs/tables/googleworkspace_calendar_my_event.md +++ b/docs/tables/googleworkspace_calendar_my_event.md @@ -11,6 +11,9 @@ Google Workspace Calendar is a core service within Google Workspace that allows The `googleworkspace_calendar_my_event` table provides insights into Google Workspace Calendar Events. As an administrator or a user, explore event-specific details through this table, including event start and end times, attendees, and event status. Utilize it to uncover information about your events, such as those with conflicting schedules, attendees' responses to event invitations, and details about recurring events. +**Important Notes** +- **Required OAuth Scope**: `https://www.googleapis.com/auth/calendar.readonly`, for more details see required [Authorization scope](https://developers.google.com/workspace/calendar/api/v3/reference/events/list#auth) + ## Examples ### Basic info @@ -197,4 +200,4 @@ where and date(start_time) >= date('now') order by start_time limit 10; -``` \ No newline at end of file +``` diff --git a/docs/tables/googleworkspace_drive.md b/docs/tables/googleworkspace_drive.md index 01c732c..5cfc5b6 100644 --- a/docs/tables/googleworkspace_drive.md +++ b/docs/tables/googleworkspace_drive.md @@ -13,6 +13,7 @@ The `googleworkspace_drive` table provides insights into Drives within Google Wo **Important Notes** - To filter the resource using `name`, or `created_time` you must set `use_domain_admin_access` setting as true** in the where clause, and for that you must have admin access in the domain. See [Shared drive-specific query terms](https://developers.google.com/drive/api/v3/ref-search-terms#drive_properties) for information on `use_domain_admin_access` setting. +- **Required OAuth Scope**: `https://www.googleapis.com/auth/drive.readonly`, for more details see required [Authorization scope](https://developers.google.com/workspace/drive/api/reference/rest/v3/drives/list#authorization-scopes) ## Examples @@ -149,4 +150,4 @@ from where query = 'createdTime > ''2021-08-01T07:00:00'' and name contains ''steampipe''' and use_domain_admin_access; -``` \ No newline at end of file +``` diff --git a/docs/tables/googleworkspace_drive_my_file.md b/docs/tables/googleworkspace_drive_my_file.md index 3661285..780496b 100644 --- a/docs/tables/googleworkspace_drive_my_file.md +++ b/docs/tables/googleworkspace_drive_my_file.md @@ -11,6 +11,9 @@ Google Workspace Drive is a cloud storage service within Google Workspace that a The `googleworkspace_drive_my_file` table provides insights into files within Google Workspace Drive. As a Google Workspace administrator, explore file-specific details through this table, including ownership, sharing settings, and associated metadata. Utilize it to uncover information about files, such as those shared externally, the permissions associated with each file, and the verification of sharing policies. +**Important Notes** +- **Required OAuth Scope**: `https://www.googleapis.com/auth/drive.readonly`, for more details see required [Authorization scope](https://developers.google.com/workspace/drive/api/reference/rest/v3/files/list#authorization-scopes) + ## Examples ### Basic info @@ -127,4 +130,4 @@ from googleworkspace_drive_my_file where query = 'name contains "steampipe"'; -``` \ No newline at end of file +``` diff --git a/docs/tables/googleworkspace_gmail_draft.md b/docs/tables/googleworkspace_gmail_draft.md index d2096cf..565696b 100644 --- a/docs/tables/googleworkspace_gmail_draft.md +++ b/docs/tables/googleworkspace_gmail_draft.md @@ -13,6 +13,7 @@ The `googleworkspace_gmail_draft` table provides insights into draft emails with **Important Notes** - You must specify the `user_id` in the `where` or join clause (`where user_id=`, `join googleworkspace_gmail_draft g on g.user_id=`) to query this table. +- **Required OAuth Scope**: `https://www.googleapis.com/auth/gmail.readonly`, for more details see required [Authorization scope](https://developers.google.com/workspace/gmail/api/auth/scopes) ## Examples @@ -144,4 +145,4 @@ from where user_id = 'user@domain.com' and message_snippet is null; -``` \ No newline at end of file +``` diff --git a/docs/tables/googleworkspace_gmail_message.md b/docs/tables/googleworkspace_gmail_message.md index bee202d..ad83937 100644 --- a/docs/tables/googleworkspace_gmail_message.md +++ b/docs/tables/googleworkspace_gmail_message.md @@ -13,6 +13,7 @@ The `googleworkspace_gmail_message` table provides insights into Gmail Messages **Important Notes** - You must specify the `user_id` in the `where` or join clause (`where user_id=`, `join googleworkspace_gmail_my_message g on g.user_id=`) to query this table. +- **Required OAuth Scope**: `https://www.googleapis.com/auth/gmail.readonly`, for more details see required [Authorization scope](https://developers.google.com/workspace/gmail/api/auth/scopes) ## Examples @@ -179,4 +180,4 @@ where user_id = 'user@domain.com' and query = 'in:chats' order by internal_date; -``` \ No newline at end of file +``` diff --git a/docs/tables/googleworkspace_gmail_my_draft.md b/docs/tables/googleworkspace_gmail_my_draft.md index 4e6132d..ea333a5 100644 --- a/docs/tables/googleworkspace_gmail_my_draft.md +++ b/docs/tables/googleworkspace_gmail_my_draft.md @@ -11,6 +11,9 @@ Gmail Drafts in Google Workspace is a feature that allows users to save and mana The `googleworkspace_gmail_my_draft` table provides insights into draft messages within Google Workspace's Gmail. As an IT administrator, explore draft-specific details through this table, including content, status, and associated metadata. Utilize it to uncover information about drafts, such as those that have been left unsent or abandoned, and the details of these drafts, to better manage email communications within your organization. +**Important Notes** +- **Required OAuth Scope**: `https://www.googleapis.com/auth/gmail.readonly`, for more details see required [Authorization scope](https://developers.google.com/workspace/gmail/api/auth/scopes) + ## Examples ### Basic info @@ -131,4 +134,4 @@ from googleworkspace_gmail_my_draft where message_snippet is null; -``` \ No newline at end of file +``` diff --git a/docs/tables/googleworkspace_gmail_my_message.md b/docs/tables/googleworkspace_gmail_my_message.md index b4288b5..a025966 100644 --- a/docs/tables/googleworkspace_gmail_my_message.md +++ b/docs/tables/googleworkspace_gmail_my_message.md @@ -11,6 +11,9 @@ Gmail is a service within Google Workspace that provides a robust and secure pla The `googleworkspace_gmail_my_message` table provides insights into Gmail Messages within Google Workspace. As a system administrator, explore message-specific details through this table, including the sender, recipient, subject, and timestamp. Utilize it to uncover information about messages, such as those marked as spam, the communication patterns, and the verification of message headers. +**Important Notes** +- **Required OAuth Scope**: `https://www.googleapis.com/auth/gmail.readonly`, for more details see required [Authorization scope](https://developers.google.com/workspace/gmail/api/auth/scopes) + ## Examples ### Basic info @@ -164,4 +167,4 @@ from where query = 'in:chats' order by internal_date; -``` \ No newline at end of file +``` diff --git a/docs/tables/googleworkspace_gmail_my_settings.md b/docs/tables/googleworkspace_gmail_my_settings.md index 8bbbaff..5850344 100644 --- a/docs/tables/googleworkspace_gmail_my_settings.md +++ b/docs/tables/googleworkspace_gmail_my_settings.md @@ -13,6 +13,7 @@ The `googleworkspace_gmail_my_settings` table provides insights into the Gmail S **Important Notes** - To list delegated accounts, you must authenticate using a service account client that has been delegated domain-wide authority. +- **Required OAuth Scope**: `https://www.googleapis.com/auth/gmail.readonly`, for more details see required [Authorization scope](https://developers.google.com/workspace/gmail/api/auth/scopes) ## Examples @@ -135,4 +136,4 @@ from googleworkspace_gmail_my_settings where json_extract(auto_forwarding, '$.enabled'); -``` \ No newline at end of file +``` diff --git a/docs/tables/googleworkspace_gmail_settings.md b/docs/tables/googleworkspace_gmail_settings.md index 97868d0..b0910b8 100644 --- a/docs/tables/googleworkspace_gmail_settings.md +++ b/docs/tables/googleworkspace_gmail_settings.md @@ -14,6 +14,7 @@ The `googleworkspace_gmail_settings` table provides insights into individual use **Important Notes** - You must specify the `user_email` in the `where` or join clause (`where user_email=`, `join googleworkspace_gmail_settings g on g.user_email=`) to query this table. - To list delegated accounts, you must authenticate using a service account client that has been delegated domain-wide authority. +- **Required OAuth Scope**: `https://www.googleapis.com/auth/gmail.readonly`, for more details see required [Authorization scope](https://developers.google.com/workspace/gmail/api/auth/scopes) ## Examples @@ -148,4 +149,4 @@ from where user_email = 'user@domain.com' and json_extract(auto_forwarding, '$.enabled'); -``` \ No newline at end of file +``` diff --git a/docs/tables/googleworkspace_people_contact.md b/docs/tables/googleworkspace_people_contact.md index d56a74d..31ec69d 100644 --- a/docs/tables/googleworkspace_people_contact.md +++ b/docs/tables/googleworkspace_people_contact.md @@ -11,6 +11,9 @@ Google Workspace Contacts is a resource within Google Workspace that allows user The `googleworkspace_people_contact` table provides insights into contact details within Google Workspace. As a system administrator, explore contact-specific details through this table, including names, email addresses, phone numbers, and associated metadata. Utilize it to uncover information about contacts, such as their professional affiliations, communication details, and the verification of associated metadata. +**Important Notes** +- **Required OAuth Scope**: `https://www.googleapis.com/auth/contacts.readonly`, for more details see required [Authorization scope](https://developers.google.com/people/api/rest/v1/people.connections/list#authorization-scopes) + ## Examples ### Basic info @@ -88,4 +91,4 @@ from where json_extract(org.value, '$.metadata.primary') = 'true' and json_extract(org.value, '$.name') = 'Turbot'; -``` \ No newline at end of file +``` diff --git a/docs/tables/googleworkspace_people_contact_group.md b/docs/tables/googleworkspace_people_contact_group.md index 35f0f13..af4bb8b 100644 --- a/docs/tables/googleworkspace_people_contact_group.md +++ b/docs/tables/googleworkspace_people_contact_group.md @@ -11,6 +11,9 @@ Google Workspace People Contact Groups is a feature within Google Workspace that The `googleworkspace_people_contact_group` table provides insights into People Contact Groups within Google Workspace. As an IT administrator or a Google Workspace user, you can explore group-specific details through this table, including group metadata, member count, and member resource names. Use it to manage and organize your Google Workspace contacts more efficiently, such as identifying large groups, finding groups without members, and understanding the structure of your contact groups. +**Important Notes** +- **Required OAuth Scope**: `https://www.googleapis.com/auth/contacts.readonly`, for more details see required [Authorization scope](https://developers.google.com/people/api/rest/v1/contactGroups/list#authorization-scopes) + ## Examples ### Basic info @@ -113,4 +116,4 @@ select member_count from googleworkspace_people_contact_group; -``` \ No newline at end of file +``` diff --git a/docs/tables/googleworkspace_people_directory_people.md b/docs/tables/googleworkspace_people_directory_people.md index ed3324b..af152f0 100644 --- a/docs/tables/googleworkspace_people_directory_people.md +++ b/docs/tables/googleworkspace_people_directory_people.md @@ -11,6 +11,9 @@ Google Workspace Directory People is a resource within Google Workspace that all The `googleworkspace_people_directory_people` table provides insights into user profiles within Google Workspace Directory People. As an IT administrator, explore user-specific details through this table, including email addresses, phone numbers, and other profile details. Utilize it to uncover information about users, such as their roles, the groups they belong to, and their profile's metadata. +**Important Notes** +- **Required OAuth Scope**: `https://www.googleapis.com/auth/directory.readonly`, for more details see required [Authorization scope](https://developers.google.com/people/api/rest/v1/people/listDirectoryPeople#authorization-scopes) + ## Examples ### Basic info @@ -46,4 +49,4 @@ from googleworkspace_people_directory_people, json_each(organizations) as org, json_each(phone_numbers) as ph; -``` \ No newline at end of file +``` diff --git a/googleworkspace/service.go b/googleworkspace/service.go index e32bcce..4d4d700 100644 --- a/googleworkspace/service.go +++ b/googleworkspace/service.go @@ -3,28 +3,31 @@ package googleworkspace import ( "context" "errors" + "strings" "golang.org/x/oauth2" "golang.org/x/oauth2/google" + admin "google.golang.org/api/admin/reports/v1" "google.golang.org/api/calendar/v3" "google.golang.org/api/drive/v3" "google.golang.org/api/gmail/v1" "google.golang.org/api/option" "google.golang.org/api/people/v1" - "google.golang.org/api/admin/reports/v1" "github.com/turbot/steampipe-plugin-sdk/v5/plugin" ) -func CalendarService(ctx context.Context, d *plugin.QueryData) (*calendar.Service, error) { +func CalendarServiceWithScope(ctx context.Context, d *plugin.QueryData, scopes ...string) (*calendar.Service, error) { + // Create cache key based on scopes + cacheKey := "googleworkspace.calendar - " + strings.Join(scopes, "|") + // have we already created and cached the service? - serviceCacheKey := "googleworkspace.calendar" - if cachedData, ok := d.ConnectionManager.Cache.Get(serviceCacheKey); ok { + if cachedData, ok := d.ConnectionManager.Cache.Get(cacheKey); ok { return cachedData.(*calendar.Service), nil } // so it was not in cache - create service - opts, err := getSessionConfig(ctx, d) + opts, err := getSessionConfig(ctx, d, scopes...) if err != nil { return nil, err } @@ -36,20 +39,22 @@ func CalendarService(ctx context.Context, d *plugin.QueryData) (*calendar.Servic } // cache the service - d.ConnectionManager.Cache.Set(serviceCacheKey, svc) + d.ConnectionManager.Cache.Set(cacheKey, svc) return svc, nil } -func PeopleService(ctx context.Context, d *plugin.QueryData) (*people.Service, error) { +func PeopleServiceWithScope(ctx context.Context, d *plugin.QueryData, scopes ...string) (*people.Service, error) { + // Create cache key based on scopes + cacheKey := "googleworkspace.people - " + strings.Join(scopes, "|") + // have we already created and cached the service? - serviceCacheKey := "googleworkspace.people" - if cachedData, ok := d.ConnectionManager.Cache.Get(serviceCacheKey); ok { + if cachedData, ok := d.ConnectionManager.Cache.Get(cacheKey); ok { return cachedData.(*people.Service), nil } // so it was not in cache - create service - opts, err := getSessionConfig(ctx, d) + opts, err := getSessionConfig(ctx, d, scopes...) if err != nil { return nil, err } @@ -61,20 +66,22 @@ func PeopleService(ctx context.Context, d *plugin.QueryData) (*people.Service, e } // cache the service - d.ConnectionManager.Cache.Set(serviceCacheKey, svc) + d.ConnectionManager.Cache.Set(cacheKey, svc) return svc, nil } -func DriveService(ctx context.Context, d *plugin.QueryData) (*drive.Service, error) { +func DriveServiceWithScope(ctx context.Context, d *plugin.QueryData, scopes ...string) (*drive.Service, error) { + // Create cache key based on scopes + cacheKey := "googleworkspace.drive - " + strings.Join(scopes, "|") + // have we already created and cached the service? - serviceCacheKey := "googleworkspace.drive" - if cachedData, ok := d.ConnectionManager.Cache.Get(serviceCacheKey); ok { + if cachedData, ok := d.ConnectionManager.Cache.Get(cacheKey); ok { return cachedData.(*drive.Service), nil } // so it was not in cache - create service - opts, err := getSessionConfig(ctx, d) + opts, err := getSessionConfig(ctx, d, scopes...) if err != nil { return nil, err } @@ -86,20 +93,22 @@ func DriveService(ctx context.Context, d *plugin.QueryData) (*drive.Service, err } // cache the service - d.ConnectionManager.Cache.Set(serviceCacheKey, svc) + d.ConnectionManager.Cache.Set(cacheKey, svc) return svc, nil } -func GmailService(ctx context.Context, d *plugin.QueryData) (*gmail.Service, error) { +func GmailServiceWithScope(ctx context.Context, d *plugin.QueryData, scopes ...string) (*gmail.Service, error) { + // Create cache key based on scopes + cacheKey := "googleworkspace.gmail - " + strings.Join(scopes, "|") + // have we already created and cached the service? - serviceCacheKey := "googleworkspace.gmail" - if cachedData, ok := d.ConnectionManager.Cache.Get(serviceCacheKey); ok { + if cachedData, ok := d.ConnectionManager.Cache.Get(cacheKey); ok { return cachedData.(*gmail.Service), nil } // so it was not in cache - create service - opts, err := getSessionConfig(ctx, d) + opts, err := getSessionConfig(ctx, d, scopes...) if err != nil { return nil, err } @@ -111,36 +120,38 @@ func GmailService(ctx context.Context, d *plugin.QueryData) (*gmail.Service, err } // cache the service - d.ConnectionManager.Cache.Set(serviceCacheKey, svc) + d.ConnectionManager.Cache.Set(cacheKey, svc) return svc, nil } -func ReportsService(ctx context.Context, d *plugin.QueryData) (*admin.Service, error) { +func ReportsServiceWithScope(ctx context.Context, d *plugin.QueryData, scopes ...string) (*admin.Service, error) { + // Create cache key based on scopes + cacheKey := "googleworkspace.reports - " + strings.Join(scopes, "|") + // have we already created and cached the service? - serviceCacheKey := "googleworkspace.reports" - if cached, ok := d.ConnectionManager.Cache.Get(serviceCacheKey); ok { - return cached.(*admin.Service), nil - } - - // so it was not in cache - create service - opts, err := getSessionConfig(ctx, d) - if err != nil { - return nil, err - } - - // Create service - svc, err := admin.NewService(ctx, opts...) - if err != nil { - return nil, err - } - - // cache the service - d.ConnectionManager.Cache.Set(serviceCacheKey, svc) - return svc, nil + if cached, ok := d.ConnectionManager.Cache.Get(cacheKey); ok { + return cached.(*admin.Service), nil + } + + // so it was not in cache - create service + opts, err := getSessionConfig(ctx, d, scopes...) + if err != nil { + return nil, err + } + + // Create service + svc, err := admin.NewService(ctx, opts...) + if err != nil { + return nil, err + } + + // cache the service + d.ConnectionManager.Cache.Set(cacheKey, svc) + return svc, nil } -func getSessionConfig(ctx context.Context, d *plugin.QueryData) ([]option.ClientOption, error) { +func getSessionConfig(ctx context.Context, d *plugin.QueryData, scopes ...string) ([]option.ClientOption, error) { opts := []option.ClientOption{} // Get credential file path, and user to impersonate from config (if mentioned) @@ -161,7 +172,7 @@ func getSessionConfig(ctx context.Context, d *plugin.QueryData) ([]option.Client // If credential path provided, use domain-wide delegation if credentialContent != "" { - ts, err := getTokenSource(ctx, d) + ts, err := getTokenSource(ctx, d, scopes...) if err != nil { return nil, err } @@ -175,7 +186,7 @@ func getSessionConfig(ctx context.Context, d *plugin.QueryData) ([]option.Client if err != nil { return nil, err } - opts = append(opts, option.WithCredentialsFile(path)) + opts = append(opts, option.WithCredentialsFile(path), option.WithScopes(scopes...)) return opts, nil } @@ -183,11 +194,13 @@ func getSessionConfig(ctx context.Context, d *plugin.QueryData) ([]option.Client } // Returns a JWT TokenSource using the configuration and the HTTP client from the provided context. -func getTokenSource(ctx context.Context, d *plugin.QueryData) (oauth2.TokenSource, error) { +func getTokenSource(ctx context.Context, d *plugin.QueryData, scopes ...string) (oauth2.TokenSource, error) { // Note: based on https://developers.google.com/admin-sdk/directory/v1/guides/delegation#go + // Create cache key based on scopes + cacheKey := "googleworkspace.token_source." + strings.Join(scopes, "-") + // have we already created and cached the token? - cacheKey := "googleworkspace.token_source" if ts, ok := d.ConnectionManager.Cache.Get(cacheKey); ok { return ts.(oauth2.TokenSource), nil } @@ -224,13 +237,7 @@ func getTokenSource(ctx context.Context, d *plugin.QueryData) (oauth2.TokenSourc // Authorize the request config, err := google.JWTConfigFromJSON( []byte(credentialContent), - admin.AdminReportsAuditReadonlyScope, - calendar.CalendarReadonlyScope, - drive.DriveReadonlyScope, - gmail.GmailReadonlyScope, - people.ContactsOtherReadonlyScope, - people.ContactsReadonlyScope, - people.DirectoryReadonlyScope, + scopes..., ) if err != nil { return nil, err diff --git a/googleworkspace/table_googleworkspace_activity_report.go b/googleworkspace/table_googleworkspace_activity_report.go index 19b08ff..567fec8 100644 --- a/googleworkspace/table_googleworkspace_activity_report.go +++ b/googleworkspace/table_googleworkspace_activity_report.go @@ -96,7 +96,8 @@ func tableGoogleworkspaceActivityReport(ctx context.Context) *plugin.Table { //// LIST FUNCTION func listGoogleworkspaceAdminReportsActivities(ctx context.Context, d *plugin.QueryData, _ *plugin.HydrateData) (interface{}, error) { - service, err := ReportsService(ctx, d) + // https://developers.google.com/admin-sdk/reports/v1/reference/activities/list#authorization-scopes + service, err := ReportsServiceWithScope(ctx, d, admin.AdminReportsAuditReadonlyScope) if err != nil { plugin.Logger(ctx).Error("googleworkspace_activity_report.listGoogleworkspaceAdminReportsActivities", "service_error", err) return nil, err diff --git a/googleworkspace/table_googleworkspace_calendar.go b/googleworkspace/table_googleworkspace_calendar.go index 21e7bf9..40fb323 100644 --- a/googleworkspace/table_googleworkspace_calendar.go +++ b/googleworkspace/table_googleworkspace_calendar.go @@ -6,6 +6,7 @@ import ( "github.com/turbot/steampipe-plugin-sdk/v5/grpc/proto" "github.com/turbot/steampipe-plugin-sdk/v5/plugin" "github.com/turbot/steampipe-plugin-sdk/v5/plugin/transform" + "google.golang.org/api/calendar/v3" ) //// TABLE DEFINITION @@ -64,7 +65,8 @@ func tableGoogleWorkspaceCalendar(_ context.Context) *plugin.Table { func listCalendars(ctx context.Context, d *plugin.QueryData, _ *plugin.HydrateData) (interface{}, error) { // Create service - service, err := CalendarService(ctx, d) + // https://developers.google.com/workspace/calendar/api/v3/reference/calendars/get#auth + service, err := CalendarServiceWithScope(ctx, d, calendar.CalendarReadonlyScope) if err != nil { return nil, err } diff --git a/googleworkspace/table_googleworkspace_calendar_event.go b/googleworkspace/table_googleworkspace_calendar_event.go index 48c6ba7..9e0c20c 100644 --- a/googleworkspace/table_googleworkspace_calendar_event.go +++ b/googleworkspace/table_googleworkspace_calendar_event.go @@ -270,7 +270,8 @@ func tableGoogleWorkspaceCalendarEvent(_ context.Context) *plugin.Table { func listCalendarEvents(ctx context.Context, d *plugin.QueryData, _ *plugin.HydrateData) (interface{}, error) { // Create service - service, err := CalendarService(ctx, d) + // https://developers.google.com/workspace/calendar/api/v3/reference/events/list#auth + service, err := CalendarServiceWithScope(ctx, d, calendar.CalendarReadonlyScope) if err != nil { return nil, err } @@ -335,7 +336,8 @@ func listCalendarEvents(ctx context.Context, d *plugin.QueryData, _ *plugin.Hydr func getCalendarEvent(ctx context.Context, d *plugin.QueryData, _ *plugin.HydrateData) (interface{}, error) { // Create service - service, err := CalendarService(ctx, d) + // https://developers.google.com/workspace/calendar/api/v3/reference/events/get#auth + service, err := CalendarServiceWithScope(ctx, d, calendar.CalendarReadonlyScope) if err != nil { return nil, err } diff --git a/googleworkspace/table_googleworkspace_calendar_my_event.go b/googleworkspace/table_googleworkspace_calendar_my_event.go index baece8f..ad00819 100644 --- a/googleworkspace/table_googleworkspace_calendar_my_event.go +++ b/googleworkspace/table_googleworkspace_calendar_my_event.go @@ -38,7 +38,8 @@ func tableGoogleWorkspaceCalendarMyEvent(_ context.Context) *plugin.Table { func listCalendarMyEvents(ctx context.Context, d *plugin.QueryData, _ *plugin.HydrateData) (interface{}, error) { // Create service - service, err := CalendarService(ctx, d) + // https://developers.google.com/workspace/calendar/api/reference/rest/v3/events/list#authorization-scopes + service, err := CalendarServiceWithScope(ctx, d, calendar.CalendarReadonlyScope) if err != nil { return nil, err } diff --git a/googleworkspace/table_googleworkspace_drive.go b/googleworkspace/table_googleworkspace_drive.go index 6da7530..309c42b 100644 --- a/googleworkspace/table_googleworkspace_drive.go +++ b/googleworkspace/table_googleworkspace_drive.go @@ -138,7 +138,8 @@ func tableGoogleWorkspaceDrive(_ context.Context) *plugin.Table { func listDrives(ctx context.Context, d *plugin.QueryData, _ *plugin.HydrateData) (interface{}, error) { // Create service - service, err := DriveService(ctx, d) + // https://developers.google.com/workspace/drive/api/reference/rest/v3/drives/list#authorization-scopes + service, err := DriveServiceWithScope(ctx, d, drive.DriveReadonlyScope) if err != nil { return nil, err } @@ -232,7 +233,8 @@ func getDrive(ctx context.Context, d *plugin.QueryData, _ *plugin.HydrateData) ( plugin.Logger(ctx).Trace("getDrive") // Create service - service, err := DriveService(ctx, d) + // https://developers.google.com/workspace/drive/api/reference/rest/v3/drives/get#authorization-scopes + service, err := DriveServiceWithScope(ctx, d, drive.DriveReadonlyScope) if err != nil { return nil, err } diff --git a/googleworkspace/table_googleworkspace_drive_my_file.go b/googleworkspace/table_googleworkspace_drive_my_file.go index 08e6273..7a0fb9f 100644 --- a/googleworkspace/table_googleworkspace_drive_my_file.go +++ b/googleworkspace/table_googleworkspace_drive_my_file.go @@ -349,7 +349,8 @@ func tableGoogleWorkspaceDriveMyFile(_ context.Context) *plugin.Table { func listDriveMyFiles(ctx context.Context, d *plugin.QueryData, _ *plugin.HydrateData) (interface{}, error) { // Create service - service, err := DriveService(ctx, d) + // https://developers.google.com/workspace/drive/api/reference/rest/v3/files/list#authorization-scopes + service, err := DriveServiceWithScope(ctx, d, drive.DriveReadonlyScope) if err != nil { return nil, err } @@ -451,7 +452,8 @@ func getDriveMyFile(ctx context.Context, d *plugin.QueryData, _ *plugin.HydrateD plugin.Logger(ctx).Trace("getDriveMyFile") // Create service - service, err := DriveService(ctx, d) + // https://developers.google.com/workspace/drive/api/reference/rest/v3/files/get#authorization-scopes + service, err := DriveServiceWithScope(ctx, d, drive.DriveReadonlyScope) if err != nil { return nil, err } diff --git a/googleworkspace/table_googleworkspace_gmail_draft.go b/googleworkspace/table_googleworkspace_gmail_draft.go index a6ae635..d179ec0 100644 --- a/googleworkspace/table_googleworkspace_gmail_draft.go +++ b/googleworkspace/table_googleworkspace_gmail_draft.go @@ -124,7 +124,8 @@ func tableGoogleWorkspaceGmailDraft(_ context.Context) *plugin.Table { func listGmailDrafts(ctx context.Context, d *plugin.QueryData, _ *plugin.HydrateData) (interface{}, error) { // Create service - service, err := GmailService(ctx, d) + // https://developers.google.com/workspace/gmail/api/reference/rest/v1/users.drafts/list#authorization-scopes + service, err := GmailServiceWithScope(ctx, d, gmail.GmailReadonlyScope) if err != nil { return nil, err } @@ -200,7 +201,8 @@ func listGmailDrafts(ctx context.Context, d *plugin.QueryData, _ *plugin.Hydrate func getGmailDraft(ctx context.Context, d *plugin.QueryData, h *plugin.HydrateData) (interface{}, error) { // Create service - service, err := GmailService(ctx, d) + // https://developers.google.com/workspace/gmail/api/reference/rest/v1/users.drafts/get#authorization-scopes + service, err := GmailServiceWithScope(ctx, d, gmail.GmailReadonlyScope) if err != nil { return nil, err } diff --git a/googleworkspace/table_googleworkspace_gmail_message.go b/googleworkspace/table_googleworkspace_gmail_message.go index 3df5341..88033fa 100644 --- a/googleworkspace/table_googleworkspace_gmail_message.go +++ b/googleworkspace/table_googleworkspace_gmail_message.go @@ -43,8 +43,8 @@ func tableGoogleWorkspaceGmailMessage(_ context.Context) *plugin.Table { }, }, Get: &plugin.GetConfig{ - KeyColumns: plugin.AllColumns([]string{"id", "user_id"}), - Hydrate: getGmailMessage, + KeyColumns: plugin.AllColumns([]string{"id", "user_id"}), + Hydrate: getGmailMessage, MaxConcurrency: 50, }, Columns: []*plugin.Column{ @@ -128,7 +128,8 @@ func tableGoogleWorkspaceGmailMessage(_ context.Context) *plugin.Table { func listGmailMessages(ctx context.Context, d *plugin.QueryData, _ *plugin.HydrateData) (interface{}, error) { // Create service - service, err := GmailService(ctx, d) + // https://developers.google.com/workspace/gmail/api/reference/rest/v1/users.messages/list#authorization-scopes + service, err := GmailServiceWithScope(ctx, d, gmail.GmailReadonlyScope) if err != nil { return nil, err } @@ -209,7 +210,8 @@ func listGmailMessages(ctx context.Context, d *plugin.QueryData, _ *plugin.Hydra func getGmailMessage(ctx context.Context, d *plugin.QueryData, h *plugin.HydrateData) (interface{}, error) { // Create service - service, err := GmailService(ctx, d) + // https://developers.google.com/workspace/gmail/api/reference/rest/v1/users.messages/get#authorization-scopes + service, err := GmailServiceWithScope(ctx, d, gmail.GmailReadonlyScope) if err != nil { return nil, err } diff --git a/googleworkspace/table_googleworkspace_gmail_my_draft.go b/googleworkspace/table_googleworkspace_gmail_my_draft.go index 6c88167..2471ea9 100644 --- a/googleworkspace/table_googleworkspace_gmail_my_draft.go +++ b/googleworkspace/table_googleworkspace_gmail_my_draft.go @@ -119,7 +119,8 @@ func tableGoogleWorkspaceGmailMyDraft(_ context.Context) *plugin.Table { func listGmailMyDrafts(ctx context.Context, d *plugin.QueryData, _ *plugin.HydrateData) (interface{}, error) { // Create service - service, err := GmailService(ctx, d) + // https://developers.google.com/workspace/gmail/api/reference/rest/v1/users.drafts/list#authorization-scopes + service, err := GmailServiceWithScope(ctx, d, gmail.GmailReadonlyScope) if err != nil { return nil, err } @@ -190,7 +191,8 @@ func listGmailMyDrafts(ctx context.Context, d *plugin.QueryData, _ *plugin.Hydra func getGmailMyDraft(ctx context.Context, d *plugin.QueryData, h *plugin.HydrateData) (interface{}, error) { // Create service - service, err := GmailService(ctx, d) + // https://developers.google.com/workspace/gmail/api/reference/rest/v1/users.drafts/get#authorization-scopes + service, err := GmailServiceWithScope(ctx, d, gmail.GmailReadonlyScope) if err != nil { return nil, err } diff --git a/googleworkspace/table_googleworkspace_gmail_my_message.go b/googleworkspace/table_googleworkspace_gmail_my_message.go index a3a4dc7..546b9b1 100644 --- a/googleworkspace/table_googleworkspace_gmail_my_message.go +++ b/googleworkspace/table_googleworkspace_gmail_my_message.go @@ -38,8 +38,8 @@ func tableGoogleWorkspaceGmailMyMessage(_ context.Context) *plugin.Table { }, }, Get: &plugin.GetConfig{ - KeyColumns: plugin.SingleColumn("id"), - Hydrate: getGmailMyMessage, + KeyColumns: plugin.SingleColumn("id"), + Hydrate: getGmailMyMessage, MaxConcurrency: 50, }, Columns: []*plugin.Column{ @@ -117,7 +117,8 @@ func tableGoogleWorkspaceGmailMyMessage(_ context.Context) *plugin.Table { func listGmailMyMessages(ctx context.Context, d *plugin.QueryData, _ *plugin.HydrateData) (interface{}, error) { // Create service - service, err := GmailService(ctx, d) + // https://developers.google.com/workspace/gmail/api/reference/rest/v1/users.messages/list#authorization-scopes + service, err := GmailServiceWithScope(ctx, d, gmail.GmailReadonlyScope) if err != nil { return nil, err } @@ -193,7 +194,8 @@ func listGmailMyMessages(ctx context.Context, d *plugin.QueryData, _ *plugin.Hyd func getGmailMyMessage(ctx context.Context, d *plugin.QueryData, h *plugin.HydrateData) (interface{}, error) { // Create service - service, err := GmailService(ctx, d) + // https://developers.google.com/workspace/gmail/api/reference/rest/v1/users.messages/get#authorization-scopes + service, err := GmailServiceWithScope(ctx, d, gmail.GmailReadonlyScope) if err != nil { return nil, err } diff --git a/googleworkspace/table_googleworkspace_gmail_my_settings.go b/googleworkspace/table_googleworkspace_gmail_my_settings.go index 15b15cf..f84b421 100644 --- a/googleworkspace/table_googleworkspace_gmail_my_settings.go +++ b/googleworkspace/table_googleworkspace_gmail_my_settings.go @@ -6,6 +6,7 @@ import ( "github.com/turbot/steampipe-plugin-sdk/v5/grpc/proto" "github.com/turbot/steampipe-plugin-sdk/v5/plugin" "github.com/turbot/steampipe-plugin-sdk/v5/plugin/transform" + "google.golang.org/api/gmail/v1" "google.golang.org/api/googleapi" ) @@ -74,7 +75,8 @@ func tableGoogleWorkspaceGmailMySettings(_ context.Context) *plugin.Table { func listGmailMyUser(ctx context.Context, d *plugin.QueryData, _ *plugin.HydrateData) (interface{}, error) { // Create service - service, err := GmailService(ctx, d) + // https://developers.google.com/workspace/gmail/api/reference/rest/v1/users/getProfile#authorization-scopes + service, err := GmailServiceWithScope(ctx, d, gmail.GmailReadonlyScope) if err != nil { return nil, err } @@ -94,7 +96,8 @@ func listGmailMyUser(ctx context.Context, d *plugin.QueryData, _ *plugin.Hydrate // Note: This method is only available to service account clients that have been delegated domain-wide authority. func listGmailMyDelegateSettings(ctx context.Context, d *plugin.QueryData, _ *plugin.HydrateData) (interface{}, error) { // Create service - service, err := GmailService(ctx, d) + // https://developers.google.com/workspace/gmail/api/reference/rest/v1/users.settings.delegates/list#authorization-scopes + service, err := GmailServiceWithScope(ctx, d, gmail.GmailReadonlyScope) if err != nil { return nil, err } @@ -117,7 +120,8 @@ func listGmailMyDelegateSettings(ctx context.Context, d *plugin.QueryData, _ *pl // Gets the auto-forwarding setting for the current authenticated user's account. func getGmailMyAutoForwardingSetting(ctx context.Context, d *plugin.QueryData, _ *plugin.HydrateData) (interface{}, error) { // Create service - service, err := GmailService(ctx, d) + // https://developers.google.com/workspace/gmail/api/reference/rest/v1/users.settings/getAutoForwarding#authorization-scopes + service, err := GmailServiceWithScope(ctx, d, gmail.GmailReadonlyScope) if err != nil { return nil, err } @@ -143,7 +147,8 @@ func getGmailMyAutoForwardingSetting(ctx context.Context, d *plugin.QueryData, _ // Gets IMAP settings. func getGmailMyImapSetting(ctx context.Context, d *plugin.QueryData, _ *plugin.HydrateData) (interface{}, error) { // Create service - service, err := GmailService(ctx, d) + // https://developers.google.com/workspace/gmail/api/reference/rest/v1/users.settings/getImap#authorization-scopes + service, err := GmailServiceWithScope(ctx, d, gmail.GmailReadonlyScope) if err != nil { return nil, err } @@ -170,7 +175,8 @@ func getGmailMyImapSetting(ctx context.Context, d *plugin.QueryData, _ *plugin.H // Gets language settings. func getGmailMyLanguage(ctx context.Context, d *plugin.QueryData, _ *plugin.HydrateData) (interface{}, error) { // Create service - service, err := GmailService(ctx, d) + // https://developers.google.com/workspace/gmail/api/reference/rest/v1/users.settings/getLanguage#authorization-scopes + service, err := GmailServiceWithScope(ctx, d, gmail.GmailReadonlyScope) if err != nil { return nil, err } @@ -186,7 +192,8 @@ func getGmailMyLanguage(ctx context.Context, d *plugin.QueryData, _ *plugin.Hydr // Gets POP settings. func getGmailMyPopSetting(ctx context.Context, d *plugin.QueryData, _ *plugin.HydrateData) (interface{}, error) { // Create service - service, err := GmailService(ctx, d) + // https://developers.google.com/workspace/gmail/api/reference/rest/v1/users.settings/getPop#authorization-scopes + service, err := GmailServiceWithScope(ctx, d, gmail.GmailReadonlyScope) if err != nil { return nil, err } @@ -202,7 +209,8 @@ func getGmailMyPopSetting(ctx context.Context, d *plugin.QueryData, _ *plugin.Hy // Gets vacation responder settings. func getGmailMyVacationSetting(ctx context.Context, d *plugin.QueryData, _ *plugin.HydrateData) (interface{}, error) { // Create service - service, err := GmailService(ctx, d) + // https://developers.google.com/workspace/gmail/api/reference/rest/v1/users.settings/getVacation#authorization-scopes + service, err := GmailServiceWithScope(ctx, d, gmail.GmailReadonlyScope) if err != nil { return nil, err } diff --git a/googleworkspace/table_googleworkspace_gmail_settings.go b/googleworkspace/table_googleworkspace_gmail_settings.go index 972157a..85e3403 100644 --- a/googleworkspace/table_googleworkspace_gmail_settings.go +++ b/googleworkspace/table_googleworkspace_gmail_settings.go @@ -77,7 +77,8 @@ func tableGoogleWorkspaceGmailSettings(_ context.Context) *plugin.Table { func listGmailUsers(ctx context.Context, d *plugin.QueryData, _ *plugin.HydrateData) (interface{}, error) { // Create service - service, err := GmailService(ctx, d) + // https://developers.google.com/workspace/gmail/api/reference/rest/v1/users/getProfile#authorization-scopes + service, err := GmailServiceWithScope(ctx, d, gmail.GmailReadonlyScope) if err != nil { return nil, err } @@ -102,7 +103,8 @@ func listGmailUsers(ctx context.Context, d *plugin.QueryData, _ *plugin.HydrateD // Note: This method is only available to service account clients that have been delegated domain-wide authority. func listGmailDelegateSettings(ctx context.Context, d *plugin.QueryData, h *plugin.HydrateData) (interface{}, error) { // Create service - service, err := GmailService(ctx, d) + // https://developers.google.com/workspace/gmail/api/reference/rest/v1/users.settings.delegates/list#authorization-scopes + service, err := GmailServiceWithScope(ctx, d, gmail.GmailReadonlyScope) if err != nil { return nil, err } @@ -126,7 +128,8 @@ func listGmailDelegateSettings(ctx context.Context, d *plugin.QueryData, h *plug // Gets the auto-forwarding setting for the specified account. func getGmailSettingAutoForwarding(ctx context.Context, d *plugin.QueryData, h *plugin.HydrateData) (interface{}, error) { // Create service - service, err := GmailService(ctx, d) + // https://developers.google.com/workspace/gmail/api/reference/rest/v1/users.settings/getAutoForwarding#response-body + service, err := GmailServiceWithScope(ctx, d, gmail.GmailReadonlyScope) if err != nil { return nil, err } @@ -153,7 +156,8 @@ func getGmailSettingAutoForwarding(ctx context.Context, d *plugin.QueryData, h * // Gets IMAP settings. func getGmailSettingImap(ctx context.Context, d *plugin.QueryData, h *plugin.HydrateData) (interface{}, error) { // Create service - service, err := GmailService(ctx, d) + // https://developers.google.com/workspace/gmail/api/reference/rest/v1/users.settings/getImap#authorization-scopes + service, err := GmailServiceWithScope(ctx, d, gmail.GmailReadonlyScope) if err != nil { return nil, err } @@ -181,7 +185,8 @@ func getGmailSettingImap(ctx context.Context, d *plugin.QueryData, h *plugin.Hyd // Gets language settings. func getGmailLanguage(ctx context.Context, d *plugin.QueryData, h *plugin.HydrateData) (interface{}, error) { // Create service - service, err := GmailService(ctx, d) + // https://developers.google.com/workspace/gmail/api/reference/rest/v1/users.settings/getLanguage#authorization-scopes + service, err := GmailServiceWithScope(ctx, d, gmail.GmailReadonlyScope) if err != nil { return nil, err } @@ -198,7 +203,8 @@ func getGmailLanguage(ctx context.Context, d *plugin.QueryData, h *plugin.Hydrat // Gets POP settings. func getGmailPopSetting(ctx context.Context, d *plugin.QueryData, h *plugin.HydrateData) (interface{}, error) { // Create service - service, err := GmailService(ctx, d) + // https://developers.google.com/workspace/gmail/api/reference/rest/v1/users.settings/getPop#authorization-scopes + service, err := GmailServiceWithScope(ctx, d, gmail.GmailReadonlyScope) if err != nil { return nil, err } @@ -215,7 +221,8 @@ func getGmailPopSetting(ctx context.Context, d *plugin.QueryData, h *plugin.Hydr // Gets vacation responder settings. func getGmailVacationSetting(ctx context.Context, d *plugin.QueryData, h *plugin.HydrateData) (interface{}, error) { // Create service - service, err := GmailService(ctx, d) + // https://developers.google.com/workspace/gmail/api/reference/rest/v1/users.settings/getVacation#authorization-scopes + service, err := GmailServiceWithScope(ctx, d, gmail.GmailReadonlyScope) if err != nil { return nil, err } diff --git a/googleworkspace/table_googleworkspace_people_contact.go b/googleworkspace/table_googleworkspace_people_contact.go index b757881..ed54f96 100644 --- a/googleworkspace/table_googleworkspace_people_contact.go +++ b/googleworkspace/table_googleworkspace_people_contact.go @@ -161,7 +161,8 @@ type contacts = struct { func listPeopleContacts(ctx context.Context, d *plugin.QueryData, _ *plugin.HydrateData) (interface{}, error) { // Create service - service, err := PeopleService(ctx, d) + // API: https://developers.google.com/people/api/rest/v1/people.connections/list#authorization-scopes + service, err := PeopleServiceWithScope(ctx, d, people.ContactsReadonlyScope) if err != nil { return nil, err } diff --git a/googleworkspace/table_googleworkspace_people_contact_group.go b/googleworkspace/table_googleworkspace_people_contact_group.go index fabaae9..3eaca2c 100644 --- a/googleworkspace/table_googleworkspace_people_contact_group.go +++ b/googleworkspace/table_googleworkspace_people_contact_group.go @@ -89,7 +89,8 @@ func tableGoogleWorkspacePeopleContactGroup(_ context.Context) *plugin.Table { func listPeopleContactGroups(ctx context.Context, d *plugin.QueryData, _ *plugin.HydrateData) (interface{}, error) { // Create service - service, err := PeopleService(ctx, d) + // API: https://developers.google.com/people/api/rest/v1/contactGroups/list#authorization-scopes + service, err := PeopleServiceWithScope(ctx, d, people.ContactsReadonlyScope) if err != nil { return nil, err } diff --git a/googleworkspace/table_googleworkspace_people_directory_people.go b/googleworkspace/table_googleworkspace_people_directory_people.go index 7b7de27..e1d48de 100644 --- a/googleworkspace/table_googleworkspace_people_directory_people.go +++ b/googleworkspace/table_googleworkspace_people_directory_people.go @@ -26,7 +26,8 @@ func tableGoogleWorkspacePeopleDirectoryPeople(_ context.Context) *plugin.Table func listPeopleDirecoryPeople(ctx context.Context, d *plugin.QueryData, _ *plugin.HydrateData) (interface{}, error) { // Create service - service, err := PeopleService(ctx, d) + // API: https://developers.google.com/people/api/rest/v1/people/listDirectoryPeople#authorization-scopes + service, err := PeopleServiceWithScope(ctx, d, people.DirectoryReadonlyScope) if err != nil { return nil, err }