Class: SOLID::CommunityClient
- Inherits:
-
Object
- Object
- SOLID::CommunityClient
- Defined in:
- lib/solid-community-client-simple/communityclient.rb
Constant Summary collapse
- VERSION =
"0.0.5"
Instance Attribute Summary collapse
-
#account_meta ⇒ Object
Returns the value of attribute account_meta.
-
#auth_string ⇒ Object
Returns the value of attribute auth_string.
-
#credentials_url ⇒ Object
Returns the value of attribute credentials_url.
-
#css_account_token ⇒ Object
Returns the value of attribute css_account_token.
-
#current_access_token ⇒ Object
Returns the value of attribute current_access_token.
-
#encoded_auth ⇒ Object
Returns the value of attribute encoded_auth.
-
#login_meta ⇒ Object
Returns the value of attribute login_meta.
-
#password ⇒ Object
Returns the value of attribute password.
-
#secret ⇒ Object
Returns the value of attribute secret.
-
#server ⇒ Object
Returns the value of attribute server.
-
#tokenid ⇒ Object
Returns the value of attribute tokenid.
-
#username ⇒ Object
Returns the value of attribute username.
-
#webid_url ⇒ Object
Returns the value of attribute webid_url.
-
#webids ⇒ Object
Returns the value of attribute webids.
Instance Method Summary collapse
-
#create_access_token(webid:, name: 'my-token') ⇒ String
Create the access token for this POD based in your WebID.
-
#execute_with_proof(dpop:, data:, content_type:, current_access_token:) ⇒ RestClient::Response
Execute an interaction with a POD (e.g. read or create a resource or container).
-
#get_current_access_token(webid:, name: "my-token") ⇒ String
Either retrieve or create a valid access token.
-
#get_webids ⇒ Array[String]
Retrieve the list of WebIDs that have access to this POD.
-
#initialize(server:, username: ENV['SOLIDUSER'], password: ENV['SOLIDPASSWORD'], webid: nil) ⇒ SOLID::CommunityClient
constructor
Initialize the SOLID Community Client Object.
-
#login ⇒ Boolean
Login to the POD.
-
#prepare_dpop(url:, method:) ⇒ SOLID::DPOP
Get the CommunityClient ready to do a specific DPoP interaction.
Constructor Details
#initialize(server:, username: ENV['SOLIDUSER'], password: ENV['SOLIDPASSWORD'], webid: nil) ⇒ SOLID::CommunityClient
Initialize the SOLID Community Client Object
20 21 22 23 24 25 26 |
# File 'lib/solid-community-client-simple/communityclient.rb', line 20 def initialize(server:, username: ENV['SOLIDUSER'], password: ENV['SOLIDPASSWORD'], webid: nil) @username = username @password = password @server = server abort "can't proceed without usernme password" unless @username && @password @webid = webid end |
Instance Attribute Details
#account_meta ⇒ Object
Returns the value of attribute account_meta.
8 9 10 |
# File 'lib/solid-community-client-simple/communityclient.rb', line 8 def @account_meta end |
#auth_string ⇒ Object
Returns the value of attribute auth_string.
8 9 10 |
# File 'lib/solid-community-client-simple/communityclient.rb', line 8 def auth_string @auth_string end |
#credentials_url ⇒ Object
Returns the value of attribute credentials_url.
8 9 10 |
# File 'lib/solid-community-client-simple/communityclient.rb', line 8 def credentials_url @credentials_url end |
#css_account_token ⇒ Object
Returns the value of attribute css_account_token.
8 9 10 |
# File 'lib/solid-community-client-simple/communityclient.rb', line 8 def css_account_token @css_account_token end |
#current_access_token ⇒ Object
Returns the value of attribute current_access_token.
8 9 10 |
# File 'lib/solid-community-client-simple/communityclient.rb', line 8 def current_access_token @current_access_token end |
#encoded_auth ⇒ Object
Returns the value of attribute encoded_auth.
8 9 10 |
# File 'lib/solid-community-client-simple/communityclient.rb', line 8 def encoded_auth @encoded_auth end |
#login_meta ⇒ Object
Returns the value of attribute login_meta.
8 9 10 |
# File 'lib/solid-community-client-simple/communityclient.rb', line 8 def @login_meta end |
#password ⇒ Object
Returns the value of attribute password.
8 9 10 |
# File 'lib/solid-community-client-simple/communityclient.rb', line 8 def password @password end |
#secret ⇒ Object
Returns the value of attribute secret.
8 9 10 |
# File 'lib/solid-community-client-simple/communityclient.rb', line 8 def secret @secret end |
#server ⇒ Object
Returns the value of attribute server.
8 9 10 |
# File 'lib/solid-community-client-simple/communityclient.rb', line 8 def server @server end |
#tokenid ⇒ Object
Returns the value of attribute tokenid.
8 9 10 |
# File 'lib/solid-community-client-simple/communityclient.rb', line 8 def tokenid @tokenid end |
#username ⇒ Object
Returns the value of attribute username.
8 9 10 |
# File 'lib/solid-community-client-simple/communityclient.rb', line 8 def username @username end |
#webid_url ⇒ Object
Returns the value of attribute webid_url.
8 9 10 |
# File 'lib/solid-community-client-simple/communityclient.rb', line 8 def webid_url @webid_url end |
#webids ⇒ Object
Returns the value of attribute webids.
8 9 10 |
# File 'lib/solid-community-client-simple/communityclient.rb', line 8 def webids @webids end |
Instance Method Details
#create_access_token(webid:, name: 'my-token') ⇒ String
Create the access token for this POD based in your WebID
110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 |
# File 'lib/solid-community-client-simple/communityclient.rb', line 110 def create_access_token(webid:, name: 'my-token') payload = { "name": name, "webId": webid }.to_json warn "", "", credentials_url, css_account_token, payload, "", "" resp = RestClient::Request.new({ method: :post, url: credentials_url, headers: { content_type: 'application/json', accept: 'application/json', authorization: "CSS-Account-Token #{css_account_token}" }, payload: payload }).execute # puts resp.body j = JSON.parse(resp.body) @tokenid = j['id'] # this is the ID that you see on the localhost:3000/yourpod Web page.... @secret = j['secret'] # concatenate tokenid and secret with a ":" @auth_string = "#{tokenid}:#{secret}" # BE CAREFUL! Base64 encoders may add newline characters # pick an encoding method that does NOT do this! @encoded_auth = Base64.strict_encode64(auth_string) # where do I get a token? tokenurl = "#{server}.well-known/openid-configuration" resp = RestClient.get(tokenurl) j = JSON.parse(resp.body) token_endpoint = j['token_endpoint'] warn "token endpoint #{token_endpoint}" payload = 'grant_type=client_credentials&scope=webid' resp = RestClient::Request.new({ method: :post, url: token_endpoint, headers: { content_type: 'application/x-www-form-urlencoded', accept: 'application/json', authorization: "Basic #{encoded_auth}" # BASIC Auth # 'dpop': proof }, payload: payload }).execute # puts resp.body j = JSON.parse(resp.body) @current_access_token = j['access_token'] end |
#execute_with_proof(dpop:, data:, content_type:, current_access_token:) ⇒ RestClient::Response
Execute an interaction with a POD (e.g. read or create a resource or container)
211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 |
# File 'lib/solid-community-client-simple/communityclient.rb', line 211 def execute_with_proof(dpop:, data:, content_type:, current_access_token:) req = RestClient::Request.new({ method: dpop.method.downcase.to_sym, # htm: 'POST', url: dpop.url, # htu: 'http://localhost:3000/markw/' headers: { # "Link": "<http://www.w3.org/ns/ldp/BasicContainer>; rel='type'", content_type: content_type, # if you're sending turtle # content_type: 'application/json', accept: 'text/turtle', # slug: "container8", # I am allowed to select my preferred resource name authorization: "Bearer #{current_access_token}", # Note switch to Bearer auth! 'DPoP': dpop.proof }, payload: data }) req.execute end |
#get_current_access_token(webid:, name: "my-token") ⇒ String
Either retrieve or create a valid access token. This should be used in preference to create_access_token, because it has logic to test the validity of the current token, and renew if it has a remaining lifespan of less than 30 seconds.
163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 |
# File 'lib/solid-community-client-simple/communityclient.rb', line 163 def get_current_access_token(webid:, name: "my-token") create_access_token(webid: webid, name: name) unless current_access_token && !(current_access_token.empty?) # by default, I find the community server to make tokens that last for 10 minutes decoded_token = JWT.decode(current_access_token, nil, false) # Access the payload (claims) payload = decoded_token[0] # Print the entire payload puts "Token Payload: #{payload}"\ # Check the expiry time if payload['exp'] expiry_time = Time.at(payload['exp']) warn "Token Expiry Time: #{expiry_time} (#{expiry_time.utc})" if (expiry_time - Time.now) < 30 puts "token will expire. Getting new one." create_access_token(webid: webid, name: name) else puts "The access token is still valid." end else puts "No expiration time (exp) claim found." end current_access_token end |
#get_webids ⇒ Array[String]
Retrieve the list of WebIDs that have access to this POD
87 88 89 90 91 92 93 94 95 96 97 98 99 100 |
# File 'lib/solid-community-client-simple/communityclient.rb', line 87 def get_webids resp = RestClient::Request.new({ method: :get, url: webid_url, headers: { accept: 'application/json', authorization: "CSS-Account-Token #{css_account_token}" } }).execute j = JSON.parse(resp.body) @webids = j['webIdLinks'].keys webids end |
#login ⇒ Boolean
Login to the POD. This creates additional accessors in the SOLID::CommunityClient Including:
#account_meta - this contains the parsed JSON from a GET on the PODs ./accout endpoint
#login_meta - this contains the parsed JSON from a GET on the PODs login_url (part of the #account_meta)
#credentials_url - the URL to be used to get credentials for the POD
#webid_url - the URL to call to get the list of WebIDs that have access to this POD
39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 |
# File 'lib/solid-community-client-simple/communityclient.rb', line 39 def login account = server + '.account/' resp = RestClient::Request.new({ method: :get, url: account, headers: { accept: 'application/json' } }).execute @account_meta = SOLID::Account.new(json: JSON.parse(resp.body)) login_url = .login_url # I take my username and password from the environment payload = { "email": username, "password": password }.to_json resp = RestClient::Request.new({ method: :post, url: login_url, headers: { content_type: 'application/json', accept: 'application/json' }, payload: payload }).execute @login_meta = SOLID::Login.new(json: JSON.parse(resp.body)) @css_account_token = .login_token # with the authoization, the return message for the /.account GET call is richer resp = RestClient::Request.new({ method: :get, url: 'http://localhost:3000/.account/', headers: { accept: 'application/json', authorization: "CSS-Account-Token #{css_account_token}" } }).execute @account_meta = SOLID::Account.new(json: JSON.parse(resp.body)) @credentials_url = .credentials_url @webid_url = .webid_url true end |
#prepare_dpop(url:, method:) ⇒ SOLID::DPOP
Get the CommunityClient ready to do a specific DPoP interaction. DPoP requires the URL that you will interact with, adn the HTEP method you will use. You have to call this method prior to every new kind of interaction with the POD
196 197 198 |
# File 'lib/solid-community-client-simple/communityclient.rb', line 196 def prepare_dpop(url:, method:) SOLID::DPOP.new(url: url, method: method) end |