diaspora_federation 0.0.8 → 0.0.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +3 -1
  3. data/lib/diaspora_federation.rb +66 -1
  4. data/lib/diaspora_federation/discovery/h_card.rb +2 -3
  5. data/lib/diaspora_federation/discovery/web_finger.rb +3 -6
  6. data/lib/diaspora_federation/entities.rb +18 -0
  7. data/lib/diaspora_federation/entities/account_deletion.rb +14 -0
  8. data/lib/diaspora_federation/entities/comment.rb +26 -0
  9. data/lib/diaspora_federation/entities/conversation.rb +38 -0
  10. data/lib/diaspora_federation/entities/like.rb +35 -0
  11. data/lib/diaspora_federation/entities/location.rb +23 -0
  12. data/lib/diaspora_federation/entities/message.rb +38 -0
  13. data/lib/diaspora_federation/entities/participation.rb +28 -0
  14. data/lib/diaspora_federation/entities/person.rb +6 -3
  15. data/lib/diaspora_federation/entities/photo.rb +59 -0
  16. data/lib/diaspora_federation/entities/poll.rb +24 -0
  17. data/lib/diaspora_federation/entities/poll_answer.rb +19 -0
  18. data/lib/diaspora_federation/entities/poll_participation.rb +28 -0
  19. data/lib/diaspora_federation/entities/profile.rb +10 -8
  20. data/lib/diaspora_federation/entities/relayable.rb +101 -0
  21. data/lib/diaspora_federation/entities/relayable_retraction.rb +95 -0
  22. data/lib/diaspora_federation/entities/request.rb +21 -0
  23. data/lib/diaspora_federation/entities/reshare.rb +49 -0
  24. data/lib/diaspora_federation/entities/retraction.rb +24 -0
  25. data/lib/diaspora_federation/entities/signed_retraction.rb +66 -0
  26. data/lib/diaspora_federation/entities/status_message.rb +55 -0
  27. data/lib/diaspora_federation/entity.rb +5 -6
  28. data/lib/diaspora_federation/fetcher.rb +1 -2
  29. data/lib/diaspora_federation/properties_dsl.rb +18 -8
  30. data/lib/diaspora_federation/salmon.rb +17 -0
  31. data/lib/diaspora_federation/salmon/aes.rb +58 -0
  32. data/lib/diaspora_federation/salmon/encrypted_slap.rb +187 -0
  33. data/lib/diaspora_federation/salmon/exceptions.rb +50 -0
  34. data/lib/diaspora_federation/salmon/magic_envelope.rb +191 -0
  35. data/lib/diaspora_federation/salmon/slap.rb +128 -0
  36. data/lib/diaspora_federation/salmon/xml_payload.rb +158 -0
  37. data/lib/diaspora_federation/signing.rb +56 -0
  38. data/lib/diaspora_federation/validators.rb +20 -0
  39. data/lib/diaspora_federation/validators/account_deletion_validator.rb +10 -0
  40. data/lib/diaspora_federation/validators/comment_validator.rb +17 -0
  41. data/lib/diaspora_federation/validators/conversation_validator.rb +14 -0
  42. data/lib/diaspora_federation/validators/like_validator.rb +14 -0
  43. data/lib/diaspora_federation/validators/location_validator.rb +11 -0
  44. data/lib/diaspora_federation/validators/message_validator.rb +16 -0
  45. data/lib/diaspora_federation/validators/participation_validator.rb +16 -0
  46. data/lib/diaspora_federation/validators/photo_validator.rb +24 -0
  47. data/lib/diaspora_federation/validators/poll_answer_validator.rb +11 -0
  48. data/lib/diaspora_federation/validators/poll_participation_validator.rb +16 -0
  49. data/lib/diaspora_federation/validators/poll_validator.rb +11 -0
  50. data/lib/diaspora_federation/validators/relayable_retraction_validator.rb +15 -0
  51. data/lib/diaspora_federation/validators/relayable_validator.rb +14 -0
  52. data/lib/diaspora_federation/validators/request_validator.rb +11 -0
  53. data/lib/diaspora_federation/validators/reshare_validator.rb +18 -0
  54. data/lib/diaspora_federation/validators/retraction_validator.rb +14 -0
  55. data/lib/diaspora_federation/validators/rules/diaspora_id_count.rb +37 -0
  56. data/lib/diaspora_federation/validators/signed_retraction_validator.rb +15 -0
  57. data/lib/diaspora_federation/validators/status_message_validator.rb +14 -0
  58. data/lib/diaspora_federation/version.rb +1 -1
  59. metadata +49 -4
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4c58b6c0d7617af4b0553b67d89ab34de553559b
4
- data.tar.gz: 1954af247aa2309fbf3abb137ef42056f249747b
3
+ metadata.gz: f1cc502235f056676364d5b56b814650f284c8e5
4
+ data.tar.gz: 2b031425ffe4b1b5d83ac789ee674dc0f31f423a
5
5
  SHA512:
6
- metadata.gz: a6d293bb5e33dbce5549eee3b89165e45f4f556825d9dc2cd5366c8e5a616eda8ea80d780e3b273a0cd66348ea8b517e40196612e086ff8f68d65170d8f6028a
7
- data.tar.gz: 9205d8677d54083e4fdc0cb9c988271b97715b01d58453c7c59a139d9cc3e3661e36940b07333c29f88915a3ce7ba8000f3edd6811b5fe3cad2fcb8991643d3f
6
+ metadata.gz: 0f4691907170170b696306f6c65cfc2855e9b95b166850f1c72c5f96fdbe6657c0cf31cb6b8ab3cf55369da424103388d0e24be445e34cf61daaa1b2ad1a187a
7
+ data.tar.gz: 12e1dde41d27bd0ee229a2befd99a6d6329bd7aca49f822e3d29c0a79e6135892238672321cdf1ad64813b78e441552fc318733729415f32c1f0983b42c4a4b8
data/README.md CHANGED
@@ -2,7 +2,9 @@
2
2
 
3
3
  **A library that provides functionalities needed for the diaspora* federation protocol**
4
4
 
5
- [![Build Status](https://travis-ci.org/SuperTux88/diaspora_federation.svg?branch=master)](https://travis-ci.org/SuperTux88/diaspora_federation)
5
+ **master:** [![Build Status master](https://travis-ci.org/SuperTux88/diaspora_federation.svg?branch=master)](https://travis-ci.org/SuperTux88/diaspora_federation)
6
+ **develop:** [![Build Status develop](https://travis-ci.org/SuperTux88/diaspora_federation.svg?branch=develop)](https://travis-ci.org/SuperTux88/diaspora_federation)
7
+
6
8
  [![Code Climate](https://codeclimate.com/github/SuperTux88/diaspora_federation/badges/gpa.svg)](https://codeclimate.com/github/SuperTux88/diaspora_federation)
7
9
  [![Test Coverage](https://codeclimate.com/github/SuperTux88/diaspora_federation/badges/coverage.svg)](https://codeclimate.com/github/SuperTux88/diaspora_federation/coverage)
8
10
  [![Dependency Status](https://gemnasium.com/SuperTux88/diaspora_federation.svg)](https://gemnasium.com/SuperTux88/diaspora_federation)
@@ -7,9 +7,11 @@ require "diaspora_federation/validators"
7
7
 
8
8
  require "diaspora_federation/fetcher"
9
9
 
10
+ require "diaspora_federation/signing"
10
11
  require "diaspora_federation/entities"
11
12
 
12
13
  require "diaspora_federation/discovery"
14
+ require "diaspora_federation/salmon"
13
15
 
14
16
  # diaspora* federation library
15
17
  module DiasporaFederation
@@ -19,13 +21,18 @@ module DiasporaFederation
19
21
  fetch_person_for_webfinger
20
22
  fetch_person_for_hcard
21
23
  save_person_after_webfinger
24
+ fetch_private_key_by_diaspora_id
25
+ fetch_author_private_key_by_entity_guid
26
+ fetch_public_key_by_diaspora_id
27
+ fetch_author_public_key_by_entity_guid
28
+ entity_author_is_local?
29
+ fetch_entity_author_id_by_guid
22
30
  )
23
31
 
24
32
  class << self
25
33
  # {Callbacks} instance with defined callbacks
26
34
  # @see Callbacks#on
27
35
  # @see Callbacks#trigger
28
- #
29
36
  attr_reader :callbacks
30
37
 
31
38
  # the pod url
@@ -58,6 +65,64 @@ module DiasporaFederation
58
65
 
59
66
  # define the callbacks
60
67
  #
68
+ # In order to communicate with the application which uses the diaspora_federation gem
69
+ # callbacks are introduced. The callbacks are used for getting required data from the
70
+ # application or posting data to the application.
71
+ #
72
+ # Callbacks are implemented at the application side and must follow these specifications:
73
+ #
74
+ # fetch_person_for_webfinger
75
+ # Fetches person data from the application to form a WebFinger reply
76
+ # @param [String] Diaspora ID of the person
77
+ # @return [DiasporaFederation::Discovery::WebFinger] person webfinger data
78
+ #
79
+ # fetch_person_for_hcard
80
+ # Fetches person data from the application to reply for an HCard query
81
+ # @param [String] guid of the person
82
+ # @return [DiasporaFederation::Discovery::HCard] person hcard data
83
+ #
84
+ # save_person_after_webfinger
85
+ # After the gem had made a person discovery using WebFinger it calls this callback
86
+ # so the application saves the person data
87
+ # @param [DiasporaFederation::Entities::Person] person data
88
+ #
89
+ # fetch_private_key_by_diaspora_id
90
+ # Fetches a private key of a person by her Diaspora ID from the application
91
+ # @param [String] Diaspora ID of the person
92
+ # @return [OpenSSL::PKey::RSA] key
93
+ #
94
+ # fetch_author_private_key_by_entity_guid
95
+ # Fetches a private key of the person who authored an entity identified by a given guid
96
+ # @param [String] entity type (Post, Comment, Like, etc)
97
+ # @param [String] guid of the entity
98
+ # @return [OpenSSL::PKey::RSA] key
99
+ #
100
+ # fetch_public_key_by_diaspora_id
101
+ # Fetches a public key of a person by her Diaspora ID from the application
102
+ # @param [String] Diaspora ID of the person
103
+ # @return [OpenSSL::PKey::RSA] key
104
+ #
105
+ # fetch_author_public_key_by_entity_guid
106
+ # Fetches a public key of the person who authored an entity identified by a given guid
107
+ # @param [String] entity type (Post, Comment, Like, etc)
108
+ # @param [String] guid of the entity
109
+ # @return [OpenSSL::PKey::RSA] key
110
+ #
111
+ # entity_author_is_local?
112
+ # Reports if the author of the entity identified by a given guid is local on the pod
113
+ # where we operate.
114
+ # @param [String] entity type (Post, Comment, Like, etc)
115
+ # @param [String] guid of the entity
116
+ # @return [Boolean]
117
+ #
118
+ # fetch_entity_author_id_by_guid
119
+ # Fetches Diaspora ID of the person who authored the entity identified by a given guid
120
+ # @param [String] entity type (Post, Comment, Like, etc)
121
+ # @param [String] guid of the entity
122
+ # @return [String] Diaspora ID of the person
123
+ #
124
+ # @see Callbacks#on
125
+ #
61
126
  # @example
62
127
  # config.define_callbacks do
63
128
  # on :some_event do |arg1|
@@ -41,14 +41,13 @@ module DiasporaFederation
41
41
  # @see http://www.ietf.org/rfc/rfc6350.txt "vCard Format Specification"
42
42
  class HCard < Entity
43
43
  # @!attribute [r] guid
44
- # This is just the guid. When a user creates an account on a pod, the pod
45
- # MUST assign them a guid - a random hexadecimal string of at least 8
46
- # hexadecimal digits.
44
+ # @see Entities::Person#guid
47
45
  # @return [String] guid
48
46
  property :guid
49
47
 
50
48
  # @!attribute [r] nickname
51
49
  # the first part of the diaspora ID
50
+ # @see Entities::Person#diaspora_id
52
51
  # @return [String] nickname
53
52
  property :nickname
54
53
 
@@ -81,10 +81,7 @@ module DiasporaFederation
81
81
  # specification (will affect older Diaspora* installations).
82
82
  #
83
83
  # @see HCard#guid
84
- #
85
- # This is just the guid. When a user creates an account on a pod, the pod
86
- # MUST assign them a guid - a random hexadecimal string of at least 8
87
- # hexadecimal digits.
84
+ # @see Entities::Person#guid
88
85
  # @return [String] guid
89
86
  property :guid
90
87
 
@@ -93,7 +90,7 @@ module DiasporaFederation
93
90
  # +hCard+, which actually has fields for an +KEY+ defined in the +vCard+
94
91
  # specification (will affect older Diaspora* installations).
95
92
  #
96
- # @see HCard#pubkey
93
+ # @see HCard#public_key
97
94
  #
98
95
  # When a user is created on the pod, the pod MUST generate a pgp keypair
99
96
  # for them. This key is used for signing messages. The format is a
@@ -152,7 +149,7 @@ module DiasporaFederation
152
149
  links = data[:links]
153
150
 
154
151
  # TODO: remove! public key is deprecated in webfinger
155
- public_key = parse_link(links, REL_PUBKEY)
152
+ public_key = parse_link(links, REL_PUBKEY)
156
153
 
157
154
  new(
158
155
  acct_uri: data[:subject],
@@ -8,5 +8,23 @@ module DiasporaFederation
8
8
  end
9
9
  end
10
10
 
11
+ require "diaspora_federation/entities/relayable"
11
12
  require "diaspora_federation/entities/profile"
12
13
  require "diaspora_federation/entities/person"
14
+ require "diaspora_federation/entities/location"
15
+ require "diaspora_federation/entities/photo"
16
+ require "diaspora_federation/entities/poll_answer"
17
+ require "diaspora_federation/entities/poll"
18
+ require "diaspora_federation/entities/status_message"
19
+ require "diaspora_federation/entities/request"
20
+ require "diaspora_federation/entities/participation"
21
+ require "diaspora_federation/entities/like"
22
+ require "diaspora_federation/entities/comment"
23
+ require "diaspora_federation/entities/account_deletion"
24
+ require "diaspora_federation/entities/message"
25
+ require "diaspora_federation/entities/conversation"
26
+ require "diaspora_federation/entities/relayable_retraction"
27
+ require "diaspora_federation/entities/reshare"
28
+ require "diaspora_federation/entities/retraction"
29
+ require "diaspora_federation/entities/signed_retraction"
30
+ require "diaspora_federation/entities/poll_participation"
@@ -0,0 +1,14 @@
1
+ module DiasporaFederation
2
+ module Entities
3
+ # this entity is sent when account was deleted on a remote pod
4
+ #
5
+ # @see Validators::AccountDeletionValidator
6
+ class AccountDeletion < Entity
7
+ # @!attribute [r] diaspora_id
8
+ # The diaspora ID of the deleted account
9
+ # @see Person#diaspora_id
10
+ # @return [String] diaspora ID
11
+ property :diaspora_id, xml_name: :diaspora_handle
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,26 @@
1
+ module DiasporaFederation
2
+ module Entities
3
+ # this entity represents a comment to some kind of post (e.g. status message)
4
+ #
5
+ # @see Validators::CommentValidator
6
+ class Comment < Entity
7
+ # @!attribute [r] guid
8
+ # a random string of at least 16 chars.
9
+ # @see Validation::Rule::Guid
10
+ # @return [String] comment guid
11
+ property :guid
12
+
13
+ include Relayable
14
+
15
+ # @!attribute [r] text
16
+ # @return [String] the comment text
17
+ property :text
18
+
19
+ # @!attribute [r] diaspora_id
20
+ # The diaspora ID of the author.
21
+ # @see Person#diaspora_id
22
+ # @return [String] diaspora ID
23
+ property :diaspora_id, xml_name: :diaspora_handle
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,38 @@
1
+ module DiasporaFederation
2
+ module Entities
3
+ # this entity represents a private conversation between users
4
+ #
5
+ # @see Validators::ConversationValidator
6
+ class Conversation < Entity
7
+ # @!attribute [r] guid
8
+ # a random string of at least 16 chars.
9
+ # @see Validation::Rule::Guid
10
+ # @return [String] conversation guid
11
+ property :guid
12
+
13
+ # @!attribute [r] subject
14
+ # @return [String] the conversation subject
15
+ property :subject
16
+
17
+ # @!attribute [r] created_at
18
+ # @return [Time] Conversation creation time
19
+ property :created_at, default: -> { Time.now.utc }
20
+
21
+ # @!attribute [r] messages
22
+ # @return [[Entities::Message]] Messages of this conversation
23
+ entity :messages, [Entities::Message]
24
+
25
+ # @!attribute [r] diaspora_id
26
+ # The diaspora ID of the person initiated the conversation.
27
+ # @see Person#diaspora_id
28
+ # @return [String] diaspora ID
29
+ property :diaspora_id, xml_name: :diaspora_handle
30
+
31
+ # @!attribute [r] participant_ids
32
+ # The diaspora IDs of the persons participating the conversation separated by ";".
33
+ # @see Person#diaspora_id
34
+ # @return [String] participants diaspora IDs
35
+ property :participant_ids, xml_name: :participant_handles
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,35 @@
1
+ module DiasporaFederation
2
+ module Entities
3
+ # this entity represents a like to some kind of post (e.g. status message)
4
+ #
5
+ # @see Validators::LikeValidator
6
+ class Like < Entity
7
+ # @!attribute [r] positive
8
+ # If +true+ set a like, if +false+, set a dislike (dislikes are currently not
9
+ # implemented in the Diaspora frontend).
10
+ # @return [Boolean] is it a like or a dislike
11
+ property :positive
12
+
13
+ # @!attribute [r] guid
14
+ # a random string of at least 16 chars.
15
+ # @see Validation::Rule::Guid
16
+ # @return [String] like guid
17
+ property :guid
18
+
19
+ # @!attribute [r] target_type
20
+ # A string describing the type of the target.
21
+ # Can be "Post" or "Comment" (Comments are currently not implemented in the
22
+ # Diaspora Frontend).
23
+ # @return [String] target type
24
+ property :target_type
25
+
26
+ include Relayable
27
+
28
+ # @!attribute [r] diaspora_id
29
+ # The diaspora ID of the person who posts a like
30
+ # @see Person#diaspora_id
31
+ # @return [String] diaspora ID
32
+ property :diaspora_id, xml_name: :diaspora_handle
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,23 @@
1
+ module DiasporaFederation
2
+ module Entities
3
+ # this entity is used to specify a location data and used embedded in a status message
4
+ #
5
+ # @see Validators::LocationValidator
6
+ class Location < Entity
7
+ # @!attribute [r] address
8
+ # A string describing your location, e.g. a city name, a street name, etc
9
+ # @return [String] address
10
+ property :address
11
+
12
+ # @!attribute [r] lat
13
+ # Geographical latitude of your location
14
+ # @return [String] latitude
15
+ property :lat
16
+
17
+ # @!attribute [r] lng
18
+ # Geographical longitude of your location
19
+ # @return [String] longitude
20
+ property :lng
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,38 @@
1
+ module DiasporaFederation
2
+ module Entities
3
+ # this entity represents a private message exchanged in private conversation
4
+ #
5
+ # @see Validators::MessageValidator
6
+ class Message < Entity
7
+ # @!attribute [r] guid
8
+ # a random string of at least 16 chars.
9
+ # @see Validation::Rule::Guid
10
+ # @return [String] message guid
11
+ property :guid
12
+
13
+ include Relayable
14
+
15
+ # @!attribute [r] text
16
+ # text of the message composed by a user
17
+ # @return [String] text
18
+ property :text
19
+
20
+ # @!attribute [r] created_at
21
+ # message creation time
22
+ # @return [Time] creation time
23
+ property :created_at, default: -> { Time.now.utc }
24
+
25
+ # @!attribute [r] diaspora_id
26
+ # The diaspora ID of the message author.
27
+ # @see Person#diaspora_id
28
+ # @return [String] diaspora ID
29
+ property :diaspora_id, xml_name: :diaspora_handle
30
+
31
+ # @!attribute [r] conversation_guid
32
+ # guid of a conversation this message belongs to
33
+ # @see Conversation#guid
34
+ # @return [String] conversation guid
35
+ property :conversation_guid
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,28 @@
1
+ module DiasporaFederation
2
+ module Entities
3
+ # participation is sent to subscribe a user on updates for some post
4
+ #
5
+ # @see Validators::Participation
6
+ class Participation < Entity
7
+ # @!attribute [r] guid
8
+ # a random string of at least 16 chars.
9
+ # @see Validation::Rule::Guid
10
+ # @return [String] participation guid
11
+ property :guid
12
+
13
+ # @!attribute [r] target_type
14
+ # a string describing a type of the target to subscribe on.
15
+ # currently only "Post" is supported.
16
+ # @return [String] target type
17
+ property :target_type
18
+
19
+ include Relayable
20
+
21
+ # @!attribute [r] diaspora_id
22
+ # The diaspora ID of the person who subscribes on a post
23
+ # @see Person#diaspora_id
24
+ # @return [String] diaspora ID
25
+ property :diaspora_id, xml_name: :diaspora_handle
26
+ end
27
+ end
28
+ end
@@ -5,17 +5,20 @@ module DiasporaFederation
5
5
  # @see Validators::PersonValidator
6
6
  class Person < Entity
7
7
  # @!attribute [r] guid
8
- # @see HCard#guid
8
+ # This is just the guid. When a user creates an account on a pod, the pod
9
+ # MUST assign them a guid - a random string of at least 16 chars.
10
+ # @see Validation::Rule::Guid
9
11
  # @return [String] guid
10
12
  property :guid
11
13
 
12
14
  # @!attribute [r] diaspora_id
13
15
  # The diaspora ID of the person
16
+ # @see Validation::Rule::DiasporaId
14
17
  # @return [String] diaspora ID
15
18
  property :diaspora_id, xml_name: :diaspora_handle
16
19
 
17
20
  # @!attribute [r] url
18
- # @see WebFinger#seed_url
21
+ # @see Discovery::WebFinger#seed_url
19
22
  # @return [String] link to the pod
20
23
  property :url
21
24
 
@@ -25,7 +28,7 @@ module DiasporaFederation
25
28
  entity :profile, Entities::Profile
26
29
 
27
30
  # @!attribute [r] exported_key
28
- # @see HCard#public_key
31
+ # @see Discovery::HCard#public_key
29
32
  # @return [String] public key
30
33
  property :exported_key
31
34
  end
@@ -0,0 +1,59 @@
1
+ module DiasporaFederation
2
+ module Entities
3
+ # this entity represents photo and it is federated as a part of a status message
4
+ #
5
+ # @see Validators::PhotoValidator
6
+ class Photo < Entity
7
+ # @!attribute [r] guid
8
+ # a random string of at least 16 chars.
9
+ # @see Validation::Rule::Guid
10
+ # @return [String] guid
11
+ property :guid
12
+
13
+ # @!attribute [r] diaspora_id
14
+ # The diaspora ID of the person who uploaded the photo
15
+ # @see Person#diaspora_id
16
+ # @return [String] author diaspora ID
17
+ property :diaspora_id, xml_name: :diaspora_handle
18
+
19
+ # @!attribute [r] public
20
+ # Points if the photo is visible to everyone or only to some aspects
21
+ # @return [Boolean] is it public
22
+ property :public, default: false
23
+
24
+ # @!attribute [r] created_at
25
+ # photo entity creation time
26
+ # @return [Time] creation time
27
+ property :created_at, default: -> { Time.now.utc }
28
+
29
+ # @!attribute [r] remote_photo_path
30
+ # an url of the photo on a remote server
31
+ # @return [String] remote photo url
32
+ property :remote_photo_path
33
+
34
+ # @!attribute [r] remote_photo_name
35
+ # @return [String] remote photo name
36
+ property :remote_photo_name
37
+
38
+ # @!attribute [r] text
39
+ # @return [String] text
40
+ property :text, default: nil
41
+
42
+ # @!attribute [r] status_message_guid
43
+ # guid of a status message this message belongs to
44
+ # @see StatusMessage#guid
45
+ # @return [String] guid
46
+ property :status_message_guid
47
+
48
+ # @!attribute [r] height
49
+ # photo height
50
+ # @return [String] height
51
+ property :height
52
+
53
+ # @!attribute [r] width
54
+ # photo width
55
+ # @return [String] width
56
+ property :width
57
+ end
58
+ end
59
+ end