diff --git a/Project.toml b/Project.toml index a696ebb..83d313d 100644 --- a/Project.toml +++ b/Project.toml @@ -1,25 +1,14 @@ name = "Jolin" uuid = "87100c7f-5f96-485a-944e-f6ba66ec4971" authors = ["Stephan Sahm and contributors"] -version = "0.1.3" +version = "0.1.4" [deps] -Dates = "ade2ca70-3891-5945-98fb-dc099432e06a" -Git = "d7ba0133-e1db-5d97-8f8c-041e4b3a1eb2" -HTTP = "cd3eb016-35fb-5094-929b-558a96fad6f3" -JSON3 = "0f8b85d8-7281-11e9-16c2-39a750bddbf1" -JWTs = "d850fbd6-035d-5a70-a269-1ca2e636ac6c" JolinPluto = "5b0b4ef8-f4e6-4363-b674-3f031f7b9530" PlutoPlotly = "8e989ff0-3d88-8e9f-f020-2b208a939ff0" PlutoUI = "7f904dfe-b85e-4ff6-b463-dae2292396a8" Reexport = "189a3867-3050-52da-a836-e630ba90ab69" -[weakdeps] -AWS = "fbe9abb3-538b-5e4e-ba9e-bc94f4f92ebc" - -[extensions] -AWSExt = "AWS" - [compat] julia = "1.7" diff --git a/ext/AWSExt.jl b/ext/AWSExt.jl deleted file mode 100644 index 8360599..0000000 --- a/ext/AWSExt.jl +++ /dev/null @@ -1,46 +0,0 @@ -module AWSExt -import Jolin, AWS, JSON3 -using Dates - -function Jolin.authenticate_aws(args...) - mydateformat = Dates.dateformat"yyyymmdd\THHMMSS\Z" - # we define a function in a macro, so that we can use @get_jwt macro (which needs the location) - # as well as use `renew`` argument, which requires a function - function _authenticate_aws(role_arn; audience="", role_session::Union{AbstractString,Nothing}=nothing) - if isnothing(role_session) - role_session = AWS._role_session_name( - "jolincloud-role-", - basename(role_arn), - "-" * Dates.format(Dates.now(Dates.UTC), mydateformat), - ) - end - # we need to be cautious that @get_jwt is called with the same __source__ - web_identity = Jolin.jolin_token(audience) - - response = AWS.AWSServices.sts( - "AssumeRoleWithWebIdentity", - Dict( - "RoleArn" => role_arn, - "RoleSessionName" => role_session, # Required by AssumeRoleWithWebIdentity - "WebIdentityToken" => web_identity, - ); - aws_config=AWS.AWSConfig(; creds=nothing), - feature_set=AWS.FeatureSet(; use_response_type=true), - ) - dict = JSON3.read(response) - role_creds = dict["AssumeRoleWithWebIdentityResult"]["Credentials"] - assumed_role_user = dict["AssumeRoleWithWebIdentityResult"]["AssumedRoleUser"] - - return AWS.global_aws_config(creds=AWS.AWSCredentials( - role_creds["AccessKeyId"], - role_creds["SecretAccessKey"], - role_creds["SessionToken"], - assumed_role_user["Arn"]; - expiry=Dates.DateTime(rstrip(role_creds["Expiration"], 'Z')), - renew=() -> _authenticate_aws(role_arn; audience, role_session).credentials, - )) - end - _authenticate_aws(args...) -end - -end # module \ No newline at end of file diff --git a/src/Jolin.jl b/src/Jolin.jl index ca176e2..94a632d 100644 --- a/src/Jolin.jl +++ b/src/Jolin.jl @@ -3,7 +3,7 @@ using Reexport @reexport using JolinPluto export JolinPluto -@reexport using PlutoUI +import PlutoUI export PlutoUI @reexport using PlutoPlotly export PlutoPlotly @@ -12,6 +12,4 @@ export PlutoPlotly # https://github.com/JuliaComputing/TableView.jl looks like the way to go, it is even still maintained - however this does not run in Pluto... # https://github.com/lungben/PlutoGrid.jl - is not even registered, but uses the same underlying ag-grid javascript module and works in Pluto -include("authentication.jl") - end diff --git a/src/authentication.jl b/src/authentication.jl deleted file mode 100644 index cdf728c..0000000 --- a/src/authentication.jl +++ /dev/null @@ -1,70 +0,0 @@ -export jolin_token, authorize_aws - -import HTTP -import JSON3 -using JWTs: JWT -using Git: git - -""" - jolin_token() - jolin_token("exampleaudience") - -Creates a JSON Web Token which can be used for authentication at common cloud providers. - -On cloud.jolin.io the token will be issued and signed by cloud.jolin.io, -on Github Actions (used for automated tests), a respective github token is returned. -""" -function jolin_token(audience="") - # Jolin Cloud - if parse(Bool, get(ENV, "JOLIN_CLOUD", "false")) - serviceaccount_token = readchomp("/var/run/secrets/kubernetes.io/serviceaccount/token") - path = Main.PlutoRunner.notebook_path[] - project_dir = readchomp(`$(git()) -C $(dirname(path)) rev-parse --show-toplevel`) - @assert startswith(path, project_dir) "invalid workflow location" - workflowpath = path[length(project_dir)+2:end] - - response = HTTP.get("http://jolin-workspace-server-jwts.jolin-workspace-server/request_jwt", - query=["serviceaccount_token" => serviceaccount_token, - "workflowpath" => workflowpath, - "audience" => audience]) - return JSON3.read(response.body).token - - # Github Actions - elseif (parse(Bool, get(ENV, "CI", "false")) - && haskey(ENV, "ACTIONS_ID_TOKEN_REQUEST_TOKEN") - && haskey(ENV, "ACTIONS_ID_TOKEN_REQUEST_URL")) - response = HTTP.get(ENV["ACTIONS_ID_TOKEN_REQUEST_URL"], - query=["audience" => audience], - headers=["Authorization" => "bearer " * ENV["ACTIONS_ID_TOKEN_REQUEST_TOKEN"]]) - # the token is in subfield value https://blog.alexellis.io/deploy-without-credentials-using-oidc-and-github-actions/ - return JSON3.read(response.body).value - - # using a specific environment variable to set the token from the outside for local development purposes - elseif haskey(ENV, "JOLIN_JWT_FALLBACK") - return ENV["JOLIN_JWT_FALLBACK"] - - # Fallback with Dummy Value - else - payload = Dict( - "iss" => "http://www.example.com/", - "sub" => "/env/YOUR_ENV/github.com/YOUR_ORGANIZATION/YOUR_REPO/PATH/TO/WORKFLOW", - "aud" => audience, - "exp" => 1536080651, - "iat" => 1535994251, - ) - # for details see https://github.com/tanmaykm/JWTs.jl/issues/22 - jwt = JWT(; payload) - return ".$jwt." - end -end - - -""" - authenticate_aws(role_arn; audience="") - -Assume role via web identity. How to define such a role can be found here -https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-role.html#cli-configure-role-oidc -""" -function authenticate_aws end - -# TODO add Azure, Google Cloud and HashiCorp