lifen 0.2.1 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (43) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +3 -1
  3. data/README.md +11 -11
  4. data/lib/lifen.rb +7 -4
  5. data/lib/lifen/app_authenticated_client.rb +15 -27
  6. data/lib/lifen/client.rb +44 -0
  7. data/lib/lifen/configuration.rb +1 -1
  8. data/lib/lifen/error.rb +1 -0
  9. data/lib/lifen/flow.rb +41 -44
  10. data/lib/lifen/flows.rb +4 -8
  11. data/lib/lifen/status.rb +5 -3
  12. data/lib/lifen/token.rb +44 -0
  13. data/lib/lifen/user.rb +34 -23
  14. data/lib/lifen/user_authenticated_client.rb +17 -27
  15. data/lib/lifen/version.rb +1 -1
  16. data/lifen.gemspec +1 -0
  17. data/spec/cassettes/flows/attach_users/invalid_flow_uuid.yml +11 -13
  18. data/spec/cassettes/flows/attach_users/invalid_user_uuid.yml +12 -14
  19. data/spec/cassettes/flows/attach_users/valid.yml +14 -16
  20. data/spec/cassettes/flows/create.yml +13 -15
  21. data/spec/cassettes/flows/create_with_users.yml +12 -13
  22. data/spec/cassettes/flows/detach_users/valid.yml +14 -16
  23. data/spec/cassettes/flows/internal_error.yml +4 -2
  24. data/spec/cassettes/flows/internal_error_without_trace_id.yml +4 -2
  25. data/spec/cassettes/flows/invalid_token.yml +18 -14
  26. data/spec/cassettes/flows/valid_token.yml +14 -17
  27. data/spec/cassettes/messages/valid_message.yml +13 -15
  28. data/spec/cassettes/users/create/existing_user.yml +11 -11
  29. data/spec/cassettes/users/create/invalid_token.yml +16 -10
  30. data/spec/cassettes/users/create/missing_fields.yml +19 -14
  31. data/spec/cassettes/users/create/valid_attributes.yml +12 -12
  32. data/spec/cassettes/users/{refresh_unread_messages → status/refresh}/invalid_token.yml +16 -12
  33. data/spec/cassettes/users/{refresh_unread_messages → status/refresh}/valid_token.yml +10 -12
  34. data/spec/cassettes/users/token/refresh/invalid_user_uuid.yml +40 -0
  35. data/spec/cassettes/users/{refresh/invalid_user_uuid.yml → token/refresh/valid_user_uuid.yml} +16 -15
  36. data/spec/flows_spec.rb +43 -25
  37. data/spec/messages_spec.rb +10 -5
  38. data/spec/spec_helper.rb +1 -1
  39. data/spec/users_spec.rb +46 -26
  40. metadata +25 -13
  41. data/lib/lifen/authentication.rb +0 -29
  42. data/spec/cassettes/flows/detach_users/valid_again.yml +0 -57
  43. data/spec/cassettes/users/refresh/valid_user_uuid.yml +0 -54
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 75f915f68d0f6d3185d5830ffb7d35519516a306
4
- data.tar.gz: bccbde30e8be900129a9752f9735024a73335707
3
+ metadata.gz: a67207628744fa9170010479e696b05545a73568
4
+ data.tar.gz: c88fc831f27439acd3df13d6eca873b159cf8d5d
5
5
  SHA512:
6
- metadata.gz: 22b519b174c804ec29e6670be2b0dc48b595d4166af8df4537b831cef28e898f6fd1e1d5f3b9843e1ae2e8892555018262130d6112bc7c39d4debd73ea9313cb
7
- data.tar.gz: 2416769de82ff4d2cdc68ab766e35ce6f171d6c4c41826b061efe189b70640f07ed79daa235ec418e7f37af954acbe419617e45eebf9b9f79d95a6b66780f4fd
6
+ metadata.gz: 7fbd97528d92d51504930198d3eee85e50b06c2ed530a7597458770a7fe874373d7359af64d032d72d386a983dde4632521a0ae642d7d1bf32813724f1f2c0b0
7
+ data.tar.gz: d4430833c1e7849de2446b6b38f14d99a33d5a0a27130a43676f9f8a05c2504e2690908f4bd86ed5d7df3ee0e1e4cdf19548cd2091458412c56f5ba7a7c9e923
data/Gemfile.lock CHANGED
@@ -1,8 +1,9 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- lifen (0.2.1)
4
+ lifen (1.0.0)
5
5
  faraday (>= 0.9)
6
+ inflecto
6
7
  virtus (>= 1.0)
7
8
 
8
9
  GEM
@@ -27,6 +28,7 @@ GEM
27
28
  multipart-post (>= 1.2, < 3)
28
29
  hashdiff (0.3.0)
29
30
  ice_nine (0.11.2)
31
+ inflecto (0.0.2)
30
32
  multipart-post (2.0.0)
31
33
  public_suffix (2.0.4)
32
34
  rake (10.5.0)
data/README.md CHANGED
@@ -23,31 +23,31 @@ Or install it yourself as:
23
23
  Lifen can be configured (ideally inside an initializer) like so:
24
24
 
25
25
  Lifen.configure do |config|
26
- config.site = "https://develop.lifen.fr/"
27
- config.secret_key = "secret_key"
28
- config.proxy_url = "http://my.proxy.fr/"
26
+ config.site = "https://develop.lifen.fr/"
27
+ config.application_access_token = "application_access_token"
28
+ config.proxy_url = "http://my.proxy.fr/"
29
29
  end
30
30
 
31
- `site` and `secret_key` are mandatory attributes.
31
+ `site` and `application_access_token` are mandatory attributes.
32
32
 
33
33
  ### Managing users
34
34
 
35
35
  user = Lifen::User.new(email: "email@domain.tld", first_name: "Jean", last_name: "Dupont")
36
- user.create!
37
- user.refresh_token
38
- user.refresh_unread_messages
36
+ user.create
37
+ user.token.refresh
38
+ user.status.refresh
39
39
 
40
40
  ### Managing flows
41
41
 
42
- user = Lifen::User.new(token: "valid_token", uuid: "valid_uuid")
42
+ user = Lifen::User.new(uuid: "valid_uuid")
43
43
  user.flows
44
44
 
45
45
  flow = Lifen::Flow.new(user: user, title: "honestica Rocks !")
46
46
  flow.create
47
- flow.attach_users!(user)
48
- flow.detach_users!(user)
47
+ flow.attach_users(user)
48
+ flow.detach_users(user)
49
49
 
50
- flow = Lifen::Flow.new(user: user, title: "honestica Rocks !", active_users: [user_1, user_2])
50
+ flow = Lifen::Flow.new(user: user, title: "honestica Rocks !", users: [user_1, user_2])
51
51
  flow.create
52
52
 
53
53
  ### Managing messages
data/lib/lifen.rb CHANGED
@@ -2,20 +2,23 @@ module Lifen
2
2
 
3
3
  require 'virtus'
4
4
  require 'faraday'
5
+ require 'inflecto'
5
6
 
6
7
  require "lifen/version"
7
8
 
8
- require "lifen/error"
9
+ require 'lifen/error'
9
10
  require 'lifen/client'
10
11
  require 'lifen/user_authenticated_client'
11
12
  require 'lifen/app_authenticated_client'
12
13
  require 'lifen/configuration'
13
- require "lifen/base"
14
+ require 'lifen/base'
15
+ require 'lifen/token'
16
+ require 'lifen/status'
14
17
  require 'lifen/user'
15
18
  require 'lifen/flow'
16
19
  require 'lifen/flows'
17
- require 'lifen/authentication'
18
- require 'lifen/status'
19
20
  require 'lifen/message'
20
21
 
22
+ Virtus.finalize
23
+
21
24
  end
@@ -1,38 +1,26 @@
1
1
  module Lifen
2
2
  class AppAuthenticatedClient < Client
3
3
 
4
- def post(url, params = {})
4
+ private
5
5
 
6
- response = faraday_client.post do |req|
7
- req.url url
6
+ def handle_status!(response)
7
+ super(response)
8
8
 
9
- req.headers['secret_key'] = secret_key
10
- req.headers['Content-Type'] = "application/json"
9
+ case response.status
10
+ when 400
11
+ raise Error, "Error 400"
12
+ when 401
13
+ raise InvalidSecretTokenError
14
+ when 403
15
+ raise UserAlreadyExistingError
16
+ when 404
17
+ raise Error, "Error 404, Page not found"
18
+ end
11
19
 
12
- req.body = JSON.generate(params)
13
20
  end
14
21
 
15
- if response.status == 500
16
- json = JSON.parse response.body
17
-
18
- trace_id = json.fetch("X-B3-TraceId", "unknown")
19
- raise Error, "Error 500, Internal server error (trace ID: #{trace_id})"
20
- end
21
-
22
- raise Error, "Error 400" if response.status == 400
23
- raise Error, "Error 404, Page not found" if response.status == 404
24
- raise InvalidSecretTokenError if response.status == 401
25
- raise UserAlreadyExistingError if response.status == 403
26
-
27
- json = JSON.parse response.body
28
-
29
- json
30
- end
31
-
32
- private
33
-
34
- def secret_key
35
- Lifen.configuration.secret_key
22
+ def bearer
23
+ Lifen.configuration.application_access_token
36
24
  end
37
25
 
38
26
  end
data/lib/lifen/client.rb CHANGED
@@ -1,8 +1,45 @@
1
1
  module Lifen
2
2
  class Client
3
3
 
4
+ def request(mode, url, params = {})
5
+ before_request
6
+
7
+ response = faraday_client.send(mode) do |req|
8
+ req.url url
9
+
10
+ req.headers['Authorization'] = "Bearer #{bearer}"
11
+ req.headers['Content-Type'] = "application/json"
12
+ req.headers['Accept'] = "application/json"
13
+
14
+ req.body = JSON.generate(params)
15
+ end
16
+
17
+ handle_status!(response)
18
+
19
+ json = JSON.parse response.body
20
+
21
+ json
22
+ end
23
+
24
+ def post(url, params = {})
25
+ request(:post, url, params)
26
+ end
27
+
28
+ def get(url, params = {})
29
+ request(:get, url, params)
30
+ end
31
+
4
32
  private
5
33
 
34
+ def handle_status!(response)
35
+ if response.status == 500
36
+ json = JSON.parse response.body
37
+
38
+ trace_id = json.fetch("X-B3-TraceId", "unknown")
39
+ raise Error, "Error 500, Internal server error (trace ID: #{trace_id})"
40
+ end
41
+ end
42
+
6
43
  def faraday_client
7
44
  @faraday_client ||= Faraday.new(faraday_options) do |faraday|
8
45
  faraday.request :url_encoded # form-encode POST params
@@ -26,5 +63,12 @@ module Lifen
26
63
  Lifen.configuration.proxy_url
27
64
  end
28
65
 
66
+ def before_request
67
+ end
68
+
69
+ def bearer
70
+ raise "A bearer method must be defined"
71
+ end
72
+
29
73
  end
30
74
  end
@@ -1,6 +1,6 @@
1
1
  module Lifen
2
2
  class Configuration
3
- attr_accessor :site, :secret_key, :proxy_url
3
+ attr_accessor :site, :application_access_token, :proxy_url
4
4
  end
5
5
 
6
6
  def self.configuration
data/lib/lifen/error.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  module Lifen
2
+
2
3
  class Error < StandardError
3
4
  end
4
5
 
data/lib/lifen/flow.rb CHANGED
@@ -4,16 +4,12 @@ module Lifen
4
4
  attribute :uuid, String
5
5
  attribute :title, String
6
6
  attribute :user, Lifen::User
7
- attribute :active_users, Array[Lifen::User]
7
+ attribute :users, Array[Lifen::User]
8
8
 
9
9
  def create
10
- params = {title: title}
10
+ users_to_attach = users
11
11
 
12
- users_to_attach = []
13
- if !active_users.empty?
14
- users_to_attach = active_users
15
- params[:users] = active_users.map(&:uuid)
16
- end
12
+ params = {title: title, users: extract_users_uuids(users_to_attach)}
17
13
 
18
14
  json = client.post("central/api/chats?rel=activeUsers", params)
19
15
 
@@ -23,61 +19,35 @@ module Lifen
23
19
 
24
20
  self.user = user
25
21
  self.uuid = flow.uuid
22
+ self.title = flow.title
26
23
 
27
- self.active_users = []
28
- Array(json_flow["activeUsers"]).each do |element|
29
- element[:first_name] = element["firstName"]
30
- element[:last_name] = element["lastName"]
31
-
32
- self.active_users << Lifen::User.new(element)
33
- end
34
-
35
- users_to_attach.each do |user|
36
- raise Lifen::Error, "User #{user.uuid} was not attached to this flow" if !active_users.map(&:uuid).include? user.uuid
37
- end
24
+ build_users(json_flow)
38
25
 
39
- self.title = flow.title
26
+ check_if_users_were_attached!(users_to_attach)
40
27
 
41
28
  self
42
29
  end
43
30
 
44
- def attach_users!(users)
45
- users = Array(users)
46
-
47
- params = users.map(&:uuid).compact.uniq
31
+ def attach_users(users_to_attach)
32
+ params = extract_users_uuids(users_to_attach)
48
33
 
49
34
  json = client.post("central/api/chats/#{uuid}/attach_users?rel=activeUsers", params)
50
35
 
51
- Array(json["activeUsers"]).each do |element|
52
- element[:first_name] = element["firstName"]
53
- element[:last_name] = element["lastName"]
54
-
55
- self.active_users << Lifen::User.new(element)
56
- end
36
+ build_users(json)
57
37
 
58
- users.each do |user|
59
- raise Lifen::Error, "User #{user.uuid} was not attached to this flow" if !active_users.map(&:uuid).include? user.uuid
60
- end
38
+ check_if_users_were_attached!(users_to_attach)
61
39
 
62
40
  self
63
41
  end
64
42
 
65
- def detach_users!(users)
66
- users = Array(users)
67
-
68
- params = users.map(&:uuid).compact.uniq
43
+ def detach_users(users_to_detach)
44
+ params = extract_users_uuids(users_to_detach)
69
45
 
70
46
  json = client.post("central/api/chats/#{uuid}/detach_users?rel=activeUsers", params)
71
47
 
72
- self.active_users = []
48
+ build_users(json)
73
49
 
74
- Array(json["activeUsers"]).each do |element|
75
- self.active_users << Lifen::User.new(element)
76
- end
77
-
78
- users.each do |user|
79
- raise Lifen::Error, "User #{user.uuid} was not detached to this flow" if active_users.map(&:uuid).include? user.uuid
80
- end
50
+ check_if_users_were_detached!(users_to_detach)
81
51
 
82
52
  self
83
53
  end
@@ -88,5 +58,32 @@ module Lifen
88
58
  @client ||= user.client
89
59
  end
90
60
 
61
+ def build_users(json)
62
+ self.users = []
63
+
64
+ Array(json["activeUsers"]).each do |element|
65
+ element[:first_name] = element["firstName"]
66
+ element[:last_name] = element["lastName"]
67
+
68
+ self.users << Lifen::User.new(element)
69
+ end
70
+ end
71
+
72
+ def extract_users_uuids(users)
73
+ Array(users).map(&:uuid).compact.uniq
74
+ end
75
+
76
+ def check_if_users_were_attached!(users_to_attach)
77
+ missing_users = Array(users_to_attach).map(&:uuid) - users.map(&:uuid)
78
+
79
+ raise Lifen::Error, "Users #{missing_users.join(', ')} were not attached to this flow" if !missing_users.empty?
80
+ end
81
+
82
+ def check_if_users_were_detached!(users_to_detach)
83
+ extra_users = users.map(&:uuid) & Array(users_to_detach).map(&:uuid)
84
+
85
+ raise Lifen::Error, "Users #{extra_users.join(', ')} were not detached from this flow" if !extra_users.empty?
86
+ end
87
+
91
88
  end
92
89
  end
data/lib/lifen/flows.rb CHANGED
@@ -1,12 +1,8 @@
1
1
  module Lifen
2
2
  class Flows < Base
3
3
 
4
- def initialize(user)
5
- @user = user
6
- @collection = []
7
- end
8
-
9
- attr_reader :collection, :user
4
+ attribute :user, Lifen::User
5
+ attribute :elements, Array[Lifen::Flow], default: []
10
6
 
11
7
  def all
12
8
  json = client.get("central/api/chats")
@@ -15,10 +11,10 @@ module Lifen
15
11
  flow = Flow.new(element)
16
12
  flow.user = user
17
13
 
18
- @collection << flow
14
+ elements << flow
19
15
  end
20
16
 
21
- collection
17
+ elements
22
18
  end
23
19
 
24
20
  private
data/lib/lifen/status.rb CHANGED
@@ -1,9 +1,11 @@
1
1
  module Lifen
2
- class Status < Base
2
+ class Status
3
3
 
4
- attribute :user, Lifen::User
4
+ include Virtus.model(finalize: false)
5
5
 
6
- attribute :unread, Integer
6
+ attribute :user, "Lifen::User"
7
+
8
+ attribute :unread, Integer, default: 0
7
9
 
8
10
  def refresh
9
11
  json = client.get("central/api/chats/status")
@@ -0,0 +1,44 @@
1
+ module Lifen
2
+ class Token
3
+ include Virtus.model(finalize: false)
4
+
5
+ attribute :user, "Lifen::User"
6
+
7
+ attribute :value, String
8
+ attribute :expires_at, Integer
9
+
10
+ def to_s
11
+ value
12
+ end
13
+
14
+ def has_expired?
15
+ return true if expires_at.nil?
16
+
17
+ return expires_at < Time.now.to_i
18
+ end
19
+
20
+ def refresh
21
+ # params = {accountUuid: user.uuid}
22
+
23
+ json = client.post("/oauth/admin/third_party/access_token?accountUuid=#{user.uuid}")
24
+
25
+ self.value = json["access_token"]
26
+ self.expires_at = Time.now.to_i + json["expires_in"].to_i
27
+ end
28
+
29
+ def refresh_once_if_needed
30
+ return if !has_expired?
31
+
32
+ refresh
33
+
34
+ raise Error, "Token can't be refreshed" if has_expired?
35
+ end
36
+
37
+ private
38
+
39
+ def client
40
+ @client ||= AppAuthenticatedClient.new
41
+ end
42
+
43
+ end
44
+ end