diff --git a/.github/workflows/build-windows.yml b/.github/workflows/build-windows.yml index 233fc88..133ca8e 100644 --- a/.github/workflows/build-windows.yml +++ b/.github/workflows/build-windows.yml @@ -57,6 +57,12 @@ jobs: mkdir nupkgs nuget.exe pack amazon-s3-gst-plugin.nuspec -Version ${{ steps.build_plugin.outputs.plugin_version }}.${{ github.run_number }} -OutputDirectory nupkgs + - name: Upload NuGet packages + uses: actions/upload-artifact@v3 + with: + name: nuget-packages + path: 'nupkgs/*.nupkg' + - name: Publish if: startsWith(github.ref, 'refs/tags/v') run: | diff --git a/src/gstawscredentials.cpp b/src/gstawscredentials.cpp index 82b64ff..a6a0a30 100644 --- a/src/gstawscredentials.cpp +++ b/src/gstawscredentials.cpp @@ -29,6 +29,8 @@ GST_DEBUG_CATEGORY_STATIC (gst_aws_credentials_debug); using namespace Aws::Auth; +static GstAWSCredentials * _gst_aws_credentials_from_string (const gchar * str); + struct _GstAWSCredentials { _GstAWSCredentials(GstAWSCredentialsProviderFactory factory) : credentials_provider_factory(std::move(factory)) @@ -70,6 +72,14 @@ gst_aws_credentials_free (GstAWSCredentials * credentials) delete credentials; } +GstAWSCredentials * +gst_aws_credentials_new_from_string(const gchar * s) +{ + // gst_aws_credentials_new_default(); + return _gst_aws_credentials_from_string (s); +} + + static bool strings_equal(const gchar* str1, const gchar* str2, size_t len2) { diff --git a/src/gstawscredentials.h b/src/gstawscredentials.h index f16e365..6e2d099 100644 --- a/src/gstawscredentials.h +++ b/src/gstawscredentials.h @@ -37,6 +37,9 @@ void gst_aws_credentials_free (GstAWSCredentials * credentials); GST_EXPORT GType gst_aws_credentials_get_type (void); +GST_EXPORT +GstAWSCredentials * gst_aws_credentials_new_from_string(const gchar * str); + #define GST_TYPE_AWS_CREDENTIALS \ (gst_aws_credentials_get_type()) diff --git a/src/gsts3sink.c b/src/gsts3sink.c index 2483460..b58707e 100644 --- a/src/gsts3sink.c +++ b/src/gsts3sink.c @@ -74,6 +74,7 @@ enum PROP_BUFFER_SIZE, PROP_INIT_AWS_SDK, PROP_CREDENTIALS, + PROP_CREDENTIALS_STRING, PROP_AWS_SDK_ENDPOINT, PROP_AWS_SDK_USE_HTTP, PROP_AWS_SDK_VERIFY_SSL, @@ -221,6 +222,11 @@ gst_s3_sink_class_init (GstS3SinkClass * klass) g_param_spec_boxed ("aws-credentials", "AWS credentials", "The AWS credentials to use", GST_TYPE_AWS_CREDENTIALS, G_PARAM_WRITABLE | GST_PARAM_MUTABLE_READY | G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property (gobject_class, PROP_CREDENTIALS_STRING, + g_param_spec_string("aws-credentials-string", "AWS credentials (string)", + "The AWS credentials to use parsed from string", NULL, + G_PARAM_READWRITE | GST_PARAM_MUTABLE_READY | G_PARAM_STATIC_STRINGS)); g_object_class_install_property (gobject_class, PROP_AWS_SDK_ENDPOINT, g_param_spec_string ("aws-sdk-endpoint", "AWS SDK Endpoint", @@ -418,6 +424,12 @@ gst_s3_sink_set_property (GObject * object, guint prop_id, gst_aws_credentials_free (sink->config.credentials); sink->config.credentials = gst_aws_credentials_copy (g_value_get_boxed (value)); break; + case PROP_CREDENTIALS_STRING: + if (sink->config.credentials) + gst_aws_credentials_free (sink->config.credentials); + gst_s3_sink_set_string_property (sink, g_value_get_string (value), &sink->credentials_string, "aws-credentials-string"); + sink->config.credentials = gst_aws_credentials_new_from_string(sink->credentials_string); + break; case PROP_AWS_SDK_ENDPOINT: gst_s3_sink_set_string_property (sink, g_value_get_string (value), &sink->config.aws_sdk_endpoint, "aws-sdk-endpoint"); @@ -511,6 +523,9 @@ gst_s3_sink_get_property (GObject * object, guint prop_id, GValue * value, case PROP_NUM_CACHE_PARTS: g_value_set_int (value, sink->config.cache_num_parts); break; + case PROP_CREDENTIALS_STRING: + g_value_set_string (value, sink->credentials_string); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; diff --git a/src/gsts3sink.h b/src/gsts3sink.h index b42b2b6..12d1b6b 100644 --- a/src/gsts3sink.h +++ b/src/gsts3sink.h @@ -81,6 +81,8 @@ struct _GstS3Sink { // doing any download/copy-upload -like operations // that would require the uploader to 'complete' gboolean uploader_needs_complete; + + gchar * credentials_string; }; struct _GstS3SinkClass { diff --git a/tests/check/s3sink.c b/tests/check/s3sink.c index 85b9e7f..7a21a9d 100644 --- a/tests/check/s3sink.c +++ b/tests/check/s3sink.c @@ -86,6 +86,30 @@ GST_START_TEST (test_location_property) } GST_END_TEST +GST_START_TEST (test_credentials_property) +{ + GstElement *sink = gst_element_factory_make ("s3sink", "sink"); + const gchar *location = "s3://bucket/key"; + + gchar *returned_credentials = NULL; + gchar * credentialstr = "access-key-id=someAccessKey"; + + fail_if (sink == NULL); + + // Set location, then set bucket and key, verify location is used + g_object_set (sink, "aws-credentials-string", "access-key-id=someAccessKey", NULL); + g_object_set (sink, + "bucket", "new-bucket", + "key", "new-key", + NULL); + g_object_get (sink, "aws-credentials-string", &returned_credentials, NULL); + fail_if (0 != g_ascii_strcasecmp("access-key-id=someAccessKey", returned_credentials)); + g_free (returned_credentials); + + gst_object_unref (sink); +} +GST_END_TEST + GST_START_TEST (test_gst_urihandler_interface) { GstElement *s3Sink = gst_element_make_from_uri(GST_URI_SINK, "s3://bucket/key", "s3sink", NULL); @@ -821,6 +845,7 @@ s3sink_suite (void) suite_add_tcase (s, tc_chain); tcase_add_test (tc_chain, test_no_bucket_and_key_then_start_should_fail); tcase_add_test (tc_chain, test_location_property); + tcase_add_test (tc_chain, test_credentials_property); tcase_add_test (tc_chain, test_gst_urihandler_interface); tcase_add_test (tc_chain, test_change_properties_after_start_should_fail); tcase_add_test (tc_chain, test_send_eos_should_flush_buffer);