1 /* GStreamer
2 * Copyright (C) 2020 Julien Isorce <jisorce@oblong.com>
3 *
4 * gstgscommon.h:
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
19 * Boston, MA 02110-1301, USA.
20 */
21
22 #include "gstgscommon.h"
23
24 #include "google/cloud/storage/oauth2/compute_engine_credentials.h"
25
26 namespace gcs = google::cloud::storage;
27
28 namespace {
29
30 #if !GLIB_CHECK_VERSION(2, 62, 0)
g_date_time_format_iso8601(GDateTime * datetime)31 static inline gchar* g_date_time_format_iso8601(GDateTime* datetime) {
32 GString* outstr = NULL;
33 gchar* main_date = NULL;
34 gint64 offset;
35
36 // Main date and time.
37 main_date = g_date_time_format(datetime, "%Y-%m-%dT%H:%M:%S");
38 outstr = g_string_new(main_date);
39 g_free(main_date);
40
41 // Timezone. Format it as `%:::z` unless the offset is zero, in which case
42 // we can simply use `Z`.
43 offset = g_date_time_get_utc_offset(datetime);
44
45 if (offset == 0) {
46 g_string_append_c(outstr, 'Z');
47 } else {
48 gchar* time_zone = g_date_time_format(datetime, "%:::z");
49 g_string_append(outstr, time_zone);
50 g_free(time_zone);
51 }
52
53 return g_string_free(outstr, FALSE);
54 }
55 #endif
56
57 } // namespace
58
gst_gs_create_client(const gchar * service_account_email,const gchar * service_account_credentials,GError ** error)59 std::unique_ptr<google::cloud::storage::Client> gst_gs_create_client(
60 const gchar* service_account_email,
61 const gchar* service_account_credentials,
62 GError** error) {
63 if (service_account_email || service_account_credentials) {
64 google::cloud::StatusOr<std::shared_ptr<gcs::oauth2::Credentials>> creds;
65 if (service_account_credentials) {
66 creds = gcs::oauth2::CreateServiceAccountCredentialsFromJsonContents(
67 service_account_credentials,
68 {{"https://www.googleapis.com/auth/devstorage.full_control"}},
69 absl::nullopt);
70 } else {
71 // Meant to be used from a container running in the Cloud.
72 creds =
73 gcs::oauth2::CreateComputeEngineCredentials(service_account_email);
74 }
75
76 if (!creds) {
77 if (service_account_email) {
78 g_set_error(error, GST_RESOURCE_ERROR,
79 GST_RESOURCE_ERROR_NOT_AUTHORIZED,
80 "Could not retrieve credentials for the given service "
81 "account %s (%s)",
82 service_account_email, creds.status().message().c_str());
83 } else {
84 g_set_error(error, GST_RESOURCE_ERROR,
85 GST_RESOURCE_ERROR_NOT_AUTHORIZED,
86 "Could not retrieve credentials for the given service "
87 "account credentials JSON (%s)",
88 creds.status().message().c_str());
89 }
90 return nullptr;
91 }
92
93 gcs::ClientOptions client_options(std::move(creds.value()));
94 return std::make_unique<gcs::Client>(client_options,
95 gcs::StrictIdempotencyPolicy());
96 }
97 // Default account. This is meant to retrieve the credentials automatically
98 // using diffrent methods.
99 google::cloud::StatusOr<gcs::ClientOptions> client_options =
100 gcs::ClientOptions::CreateDefaultClientOptions();
101
102 if (!client_options) {
103 g_set_error(error, GST_RESOURCE_ERROR, GST_RESOURCE_ERROR_NOT_AUTHORIZED,
104 "Could not create default client options (%s)",
105 client_options.status().message().c_str());
106 return nullptr;
107 }
108 return std::make_unique<gcs::Client>(client_options.value(),
109 gcs::StrictIdempotencyPolicy());
110 }
111
gst_gs_get_buffer_date(GstBuffer * buffer,GDateTime * start_date,gchar ** buffer_date_str_ptr)112 gboolean gst_gs_get_buffer_date(GstBuffer* buffer,
113 GDateTime* start_date,
114 gchar** buffer_date_str_ptr) {
115 gchar* buffer_date_str = NULL;
116 GstClockTime buffer_timestamp = GST_CLOCK_TIME_NONE;
117 GTimeSpan buffer_timespan = 0;
118
119 if (!buffer || !start_date)
120 return FALSE;
121
122 buffer_timestamp = GST_BUFFER_PTS(buffer);
123
124 // GTimeSpan is in micro seconds.
125 buffer_timespan = GST_TIME_AS_USECONDS(buffer_timestamp);
126
127 GDateTime* buffer_date = g_date_time_add(start_date, buffer_timespan);
128 if (!buffer_date)
129 return FALSE;
130
131 buffer_date_str = g_date_time_format_iso8601(buffer_date);
132 g_date_time_unref(buffer_date);
133
134 if (!buffer_date_str)
135 return FALSE;
136
137 if (buffer_date_str_ptr)
138 *buffer_date_str_ptr = buffer_date_str;
139
140 return TRUE;
141 }
142