mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-29 21:21:12 +00:00
gs: Add support for authenticating via Service Account Credentials
This allows authenticating directly with Server Account credentials instead of having it configured on host system separately, and thus allows using arbitrary accounts configured/selected at runtime. Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/934>
This commit is contained in:
parent
c514f939c9
commit
a12762a29a
4 changed files with 118 additions and 12 deletions
|
@ -58,18 +58,35 @@ static inline gchar* g_date_time_format_iso8601(GDateTime* datetime) {
|
||||||
|
|
||||||
std::unique_ptr<google::cloud::storage::Client> gst_gs_create_client(
|
std::unique_ptr<google::cloud::storage::Client> gst_gs_create_client(
|
||||||
const gchar* service_account_email,
|
const gchar* service_account_email,
|
||||||
|
const gchar* service_account_credentials,
|
||||||
GError** error) {
|
GError** error) {
|
||||||
if (service_account_email) {
|
if (service_account_email || service_account_credentials) {
|
||||||
|
google::cloud::StatusOr<std::shared_ptr<gcs::oauth2::Credentials>> creds;
|
||||||
|
if (service_account_credentials) {
|
||||||
|
creds = gcs::oauth2::CreateServiceAccountCredentialsFromJsonContents(
|
||||||
|
service_account_credentials,
|
||||||
|
{{"https://www.googleapis.com/auth/devstorage.full_control"}},
|
||||||
|
absl::nullopt);
|
||||||
|
} else {
|
||||||
// Meant to be used from a container running in the Cloud.
|
// Meant to be used from a container running in the Cloud.
|
||||||
|
creds =
|
||||||
|
gcs::oauth2::CreateComputeEngineCredentials(service_account_email);
|
||||||
|
}
|
||||||
|
|
||||||
google::cloud::StatusOr<std::shared_ptr<gcs::oauth2::Credentials>> creds(
|
|
||||||
std::make_shared<gcs::oauth2::ComputeEngineCredentials<>>(
|
|
||||||
service_account_email));
|
|
||||||
if (!creds) {
|
if (!creds) {
|
||||||
g_set_error(error, GST_RESOURCE_ERROR, GST_RESOURCE_ERROR_NOT_AUTHORIZED,
|
if (service_account_email) {
|
||||||
|
g_set_error(error, GST_RESOURCE_ERROR,
|
||||||
|
GST_RESOURCE_ERROR_NOT_AUTHORIZED,
|
||||||
"Could not retrieve credentials for the given service "
|
"Could not retrieve credentials for the given service "
|
||||||
"account %s (%s)",
|
"account %s (%s)",
|
||||||
service_account_email, creds.status().message().c_str());
|
service_account_email, creds.status().message().c_str());
|
||||||
|
} else {
|
||||||
|
g_set_error(error, GST_RESOURCE_ERROR,
|
||||||
|
GST_RESOURCE_ERROR_NOT_AUTHORIZED,
|
||||||
|
"Could not retrieve credentials for the given service "
|
||||||
|
"account credentials JSON (%s)",
|
||||||
|
creds.status().message().c_str());
|
||||||
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -30,6 +30,7 @@
|
||||||
|
|
||||||
std::unique_ptr<google::cloud::storage::Client> gst_gs_create_client(
|
std::unique_ptr<google::cloud::storage::Client> gst_gs_create_client(
|
||||||
const gchar* service_account_email,
|
const gchar* service_account_email,
|
||||||
|
const gchar* service_account_credentials,
|
||||||
GError** error);
|
GError** error);
|
||||||
|
|
||||||
gboolean gst_gs_get_buffer_date(GstBuffer* buffer,
|
gboolean gst_gs_get_buffer_date(GstBuffer* buffer,
|
||||||
|
|
|
@ -110,6 +110,7 @@ enum {
|
||||||
PROP_NEXT_FILE,
|
PROP_NEXT_FILE,
|
||||||
PROP_SERVICE_ACCOUNT_EMAIL,
|
PROP_SERVICE_ACCOUNT_EMAIL,
|
||||||
PROP_START_DATE,
|
PROP_START_DATE,
|
||||||
|
PROP_SERVICE_ACCOUNT_CREDENTIALS,
|
||||||
};
|
};
|
||||||
|
|
||||||
class GSWriteStream;
|
class GSWriteStream;
|
||||||
|
@ -120,6 +121,7 @@ struct _GstGsSink {
|
||||||
std::unique_ptr<google::cloud::storage::Client> gcs_client;
|
std::unique_ptr<google::cloud::storage::Client> gcs_client;
|
||||||
std::unique_ptr<GSWriteStream> gcs_stream;
|
std::unique_ptr<GSWriteStream> gcs_stream;
|
||||||
gchar* service_account_email;
|
gchar* service_account_email;
|
||||||
|
gchar* service_account_credentials;
|
||||||
gchar* bucket_name;
|
gchar* bucket_name;
|
||||||
gchar* object_name;
|
gchar* object_name;
|
||||||
gchar* start_date_str;
|
gchar* start_date_str;
|
||||||
|
@ -283,6 +285,22 @@ static void gst_gs_sink_class_init(GstGsSinkClass* klass) {
|
||||||
(GParamFlags)(G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
|
(GParamFlags)(G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
|
||||||
GST_PARAM_MUTABLE_READY)));
|
GST_PARAM_MUTABLE_READY)));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GstGsSink:service-account-credentials:
|
||||||
|
*
|
||||||
|
* Service Account Credentials as a JSON string to use for credentials.
|
||||||
|
*
|
||||||
|
* Since: 1.20
|
||||||
|
*/
|
||||||
|
g_object_class_install_property(
|
||||||
|
gobject_class, PROP_SERVICE_ACCOUNT_CREDENTIALS,
|
||||||
|
g_param_spec_string(
|
||||||
|
"service-account-credentials", "Service Account Credentials",
|
||||||
|
"Service Account Credentials as a JSON string to use for credentials",
|
||||||
|
NULL,
|
||||||
|
(GParamFlags)(G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
|
||||||
|
GST_PARAM_MUTABLE_READY)));
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GstGsSink:start-date:
|
* GstGsSink:start-date:
|
||||||
*
|
*
|
||||||
|
@ -322,6 +340,7 @@ static void gst_gs_sink_init(GstGsSink* sink) {
|
||||||
sink->index = DEFAULT_INDEX;
|
sink->index = DEFAULT_INDEX;
|
||||||
sink->post_messages = DEFAULT_POST_MESSAGES;
|
sink->post_messages = DEFAULT_POST_MESSAGES;
|
||||||
sink->service_account_email = NULL;
|
sink->service_account_email = NULL;
|
||||||
|
sink->service_account_credentials = NULL;
|
||||||
sink->bucket_name = NULL;
|
sink->bucket_name = NULL;
|
||||||
sink->object_name = g_strdup(DEFAULT_OBJECT_NAME);
|
sink->object_name = g_strdup(DEFAULT_OBJECT_NAME);
|
||||||
sink->start_date_str = NULL;
|
sink->start_date_str = NULL;
|
||||||
|
@ -341,6 +360,8 @@ static void gst_gs_sink_finalize(GObject* object) {
|
||||||
sink->gcs_stream = nullptr;
|
sink->gcs_stream = nullptr;
|
||||||
g_free(sink->service_account_email);
|
g_free(sink->service_account_email);
|
||||||
sink->service_account_email = NULL;
|
sink->service_account_email = NULL;
|
||||||
|
g_free(sink->service_account_credentials);
|
||||||
|
sink->service_account_credentials = NULL;
|
||||||
g_free(sink->bucket_name);
|
g_free(sink->bucket_name);
|
||||||
sink->bucket_name = NULL;
|
sink->bucket_name = NULL;
|
||||||
g_free(sink->object_name);
|
g_free(sink->object_name);
|
||||||
|
@ -427,6 +448,10 @@ static void gst_gs_sink_set_property(GObject* object,
|
||||||
g_free(sink->service_account_email);
|
g_free(sink->service_account_email);
|
||||||
sink->service_account_email = g_strdup(g_value_get_string(value));
|
sink->service_account_email = g_strdup(g_value_get_string(value));
|
||||||
break;
|
break;
|
||||||
|
case PROP_SERVICE_ACCOUNT_CREDENTIALS:
|
||||||
|
g_free(sink->service_account_credentials);
|
||||||
|
sink->service_account_credentials = g_strdup(g_value_get_string(value));
|
||||||
|
break;
|
||||||
case PROP_START_DATE:
|
case PROP_START_DATE:
|
||||||
g_free(sink->start_date_str);
|
g_free(sink->start_date_str);
|
||||||
if (sink->start_date)
|
if (sink->start_date)
|
||||||
|
@ -472,6 +497,9 @@ static void gst_gs_sink_get_property(GObject* object,
|
||||||
case PROP_SERVICE_ACCOUNT_EMAIL:
|
case PROP_SERVICE_ACCOUNT_EMAIL:
|
||||||
g_value_set_string(value, sink->service_account_email);
|
g_value_set_string(value, sink->service_account_email);
|
||||||
break;
|
break;
|
||||||
|
case PROP_SERVICE_ACCOUNT_CREDENTIALS:
|
||||||
|
g_value_set_string(value, sink->service_account_credentials);
|
||||||
|
break;
|
||||||
case PROP_START_DATE:
|
case PROP_START_DATE:
|
||||||
g_value_set_string(value, sink->start_date_str);
|
g_value_set_string(value, sink->start_date_str);
|
||||||
break;
|
break;
|
||||||
|
@ -499,7 +527,8 @@ static gboolean gst_gs_sink_start(GstBaseSink* bsink) {
|
||||||
|
|
||||||
sink->content_type = "";
|
sink->content_type = "";
|
||||||
|
|
||||||
sink->gcs_client = gst_gs_create_client(sink->service_account_email, &err);
|
sink->gcs_client = gst_gs_create_client(
|
||||||
|
sink->service_account_email, sink->service_account_credentials, &err);
|
||||||
if (err) {
|
if (err) {
|
||||||
GST_ELEMENT_ERROR(sink, RESOURCE, OPEN_READ,
|
GST_ELEMENT_ERROR(sink, RESOURCE, OPEN_READ,
|
||||||
("Could not create client (%s)", err->message),
|
("Could not create client (%s)", err->message),
|
||||||
|
|
|
@ -63,7 +63,12 @@ enum { LAST_SIGNAL };
|
||||||
|
|
||||||
#define DEFAULT_BLOCKSIZE 4 * 1024
|
#define DEFAULT_BLOCKSIZE 4 * 1024
|
||||||
|
|
||||||
enum { PROP_0, PROP_LOCATION, PROP_SERVICE_ACCOUNT_EMAIL };
|
enum {
|
||||||
|
PROP_0,
|
||||||
|
PROP_LOCATION,
|
||||||
|
PROP_SERVICE_ACCOUNT_EMAIL,
|
||||||
|
PROP_SERVICE_ACCOUNT_CREDENTIALS
|
||||||
|
};
|
||||||
|
|
||||||
class GSReadStream;
|
class GSReadStream;
|
||||||
|
|
||||||
|
@ -74,6 +79,7 @@ struct _GstGsSrc {
|
||||||
std::unique_ptr<GSReadStream> gcs_stream;
|
std::unique_ptr<GSReadStream> gcs_stream;
|
||||||
gchar* uri;
|
gchar* uri;
|
||||||
gchar* service_account_email;
|
gchar* service_account_email;
|
||||||
|
gchar* service_account_credentials;
|
||||||
std::string bucket_name;
|
std::string bucket_name;
|
||||||
std::string object_name;
|
std::string object_name;
|
||||||
guint64 read_position;
|
guint64 read_position;
|
||||||
|
@ -166,6 +172,22 @@ static void gst_gs_src_class_init(GstGsSrcClass* klass) {
|
||||||
(GParamFlags)(G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
|
(GParamFlags)(G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
|
||||||
GST_PARAM_MUTABLE_READY)));
|
GST_PARAM_MUTABLE_READY)));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GstGsSrc:service-account-credentials:
|
||||||
|
*
|
||||||
|
* Service Account Credentials as a JSON string to use for credentials.
|
||||||
|
*
|
||||||
|
* Since: 1.20
|
||||||
|
*/
|
||||||
|
g_object_class_install_property(
|
||||||
|
gobject_class, PROP_SERVICE_ACCOUNT_CREDENTIALS,
|
||||||
|
g_param_spec_string(
|
||||||
|
"service-account-credentials", "Service Account Credentials",
|
||||||
|
"Service Account Credentials as a JSON string to use for credentials",
|
||||||
|
NULL,
|
||||||
|
(GParamFlags)(G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
|
||||||
|
GST_PARAM_MUTABLE_READY)));
|
||||||
|
|
||||||
gobject_class->finalize = gst_gs_src_finalize;
|
gobject_class->finalize = gst_gs_src_finalize;
|
||||||
|
|
||||||
gst_element_class_set_static_metadata(
|
gst_element_class_set_static_metadata(
|
||||||
|
@ -186,6 +208,7 @@ static void gst_gs_src_init(GstGsSrc* src) {
|
||||||
src->gcs_stream = nullptr;
|
src->gcs_stream = nullptr;
|
||||||
src->uri = NULL;
|
src->uri = NULL;
|
||||||
src->service_account_email = NULL;
|
src->service_account_email = NULL;
|
||||||
|
src->service_account_credentials = NULL;
|
||||||
src->read_position = 0;
|
src->read_position = 0;
|
||||||
src->object_size = 0;
|
src->object_size = 0;
|
||||||
|
|
||||||
|
@ -201,6 +224,8 @@ static void gst_gs_src_finalize(GObject* object) {
|
||||||
src->uri = NULL;
|
src->uri = NULL;
|
||||||
g_free(src->service_account_email);
|
g_free(src->service_account_email);
|
||||||
src->service_account_email = NULL;
|
src->service_account_email = NULL;
|
||||||
|
g_free(src->service_account_credentials);
|
||||||
|
src->service_account_credentials = NULL;
|
||||||
src->read_position = 0;
|
src->read_position = 0;
|
||||||
src->object_size = 0;
|
src->object_size = 0;
|
||||||
|
|
||||||
|
@ -294,6 +319,30 @@ static gboolean gst_gs_src_set_service_account_email(
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean gst_gs_src_set_service_account_credentials(
|
||||||
|
GstGsSrc* src,
|
||||||
|
const gchar* service_account_credentials) {
|
||||||
|
if (GST_STATE(src) == GST_STATE_PLAYING ||
|
||||||
|
GST_STATE(src) == GST_STATE_PAUSED) {
|
||||||
|
GST_WARNING_OBJECT(
|
||||||
|
src,
|
||||||
|
"Setting a new service account credentials not supported in "
|
||||||
|
"PLAYING or PAUSED state");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
GST_OBJECT_LOCK(src);
|
||||||
|
g_free(src->service_account_credentials);
|
||||||
|
src->service_account_credentials = NULL;
|
||||||
|
|
||||||
|
if (service_account_credentials)
|
||||||
|
src->service_account_credentials = g_strdup(service_account_credentials);
|
||||||
|
|
||||||
|
GST_OBJECT_UNLOCK(src);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
static void gst_gs_src_set_property(GObject* object,
|
static void gst_gs_src_set_property(GObject* object,
|
||||||
guint prop_id,
|
guint prop_id,
|
||||||
const GValue* value,
|
const GValue* value,
|
||||||
|
@ -309,6 +358,10 @@ static void gst_gs_src_set_property(GObject* object,
|
||||||
case PROP_SERVICE_ACCOUNT_EMAIL:
|
case PROP_SERVICE_ACCOUNT_EMAIL:
|
||||||
gst_gs_src_set_service_account_email(src, g_value_get_string(value));
|
gst_gs_src_set_service_account_email(src, g_value_get_string(value));
|
||||||
break;
|
break;
|
||||||
|
case PROP_SERVICE_ACCOUNT_CREDENTIALS:
|
||||||
|
gst_gs_src_set_service_account_credentials(src,
|
||||||
|
g_value_get_string(value));
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
|
||||||
break;
|
break;
|
||||||
|
@ -334,6 +387,11 @@ static void gst_gs_src_get_property(GObject* object,
|
||||||
g_value_set_string(value, src->service_account_email);
|
g_value_set_string(value, src->service_account_email);
|
||||||
GST_OBJECT_UNLOCK(src);
|
GST_OBJECT_UNLOCK(src);
|
||||||
break;
|
break;
|
||||||
|
case PROP_SERVICE_ACCOUNT_CREDENTIALS:
|
||||||
|
GST_OBJECT_LOCK(src);
|
||||||
|
g_value_set_string(value, src->service_account_credentials);
|
||||||
|
GST_OBJECT_UNLOCK(src);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
|
||||||
break;
|
break;
|
||||||
|
@ -470,7 +528,8 @@ static gboolean gst_gs_src_start(GstBaseSrc* basesrc) {
|
||||||
|
|
||||||
GST_INFO_OBJECT(src, "Opening file %s", src->uri);
|
GST_INFO_OBJECT(src, "Opening file %s", src->uri);
|
||||||
|
|
||||||
src->gcs_client = gst_gs_create_client(src->service_account_email, &err);
|
src->gcs_client = gst_gs_create_client(
|
||||||
|
src->service_account_email, src->service_account_credentials, &err);
|
||||||
if (err) {
|
if (err) {
|
||||||
GST_ELEMENT_ERROR(src, RESOURCE, OPEN_READ,
|
GST_ELEMENT_ERROR(src, RESOURCE, OPEN_READ,
|
||||||
("Could not create client (%s)", err->message),
|
("Could not create client (%s)", err->message),
|
||||||
|
|
Loading…
Reference in a new issue