decidim-bulletin_board 0.1.0 → 0.2.0
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.
- checksums.yaml +4 -4
- data/Gemfile.lock +8 -1
- data/decidim-bulletin_board.gemspec +3 -0
- data/lib/decidim/bulletin_board.rb +3 -0
- data/lib/decidim/bulletin_board/client.rb +12 -0
- data/lib/decidim/bulletin_board/version.rb +1 -1
- data/lib/decidim/bulletin_board/voter.rb +4 -0
- data/lib/decidim/bulletin_board/voter/cast_vote.rb +60 -0
- data/lib/decidim/bulletin_board/voter/vote_form.rb +63 -0
- metadata +53 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a3d1e27c207aed87322d6be72c10f4cdec8abcad317b1b0f500911d1a1a2db6e
|
4
|
+
data.tar.gz: d60a4887bb883c3f4da0f0100cf1b8e19e37bf14c26326288c5d4b63ff417f1e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c69fc5b2a6a410969c72936d030bf8d87184b1a52d2145da348d4b5288cabf51df7edd877317f42555781481b0fe7107da3df89033ef53915dc4ec38db9f2977
|
7
|
+
data.tar.gz: 83383e33224e36288e9d25d645a71624375274104a80e59eb1b082ad7cfcd679c283fadcb8d4ab0e6f973821a161006d837c92f73817bf0ab900fa90cef1744d
|
data/Gemfile.lock
CHANGED
@@ -1,15 +1,19 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
decidim-bulletin_board (0.
|
4
|
+
decidim-bulletin_board (0.2.0)
|
5
|
+
activemodel (~> 5.0, >= 5.0.0.1)
|
5
6
|
activesupport (~> 5.0, >= 5.0.0.1)
|
6
7
|
byebug (~> 11.0)
|
7
8
|
graphlient (~> 0.4.0)
|
8
9
|
jwt
|
10
|
+
wisper (~> 2.0.0)
|
9
11
|
|
10
12
|
GEM
|
11
13
|
remote: https://rubygems.org/
|
12
14
|
specs:
|
15
|
+
activemodel (5.2.4.4)
|
16
|
+
activesupport (= 5.2.4.4)
|
13
17
|
activesupport (5.2.4.4)
|
14
18
|
concurrent-ruby (~> 1.0, >= 1.0.2)
|
15
19
|
i18n (>= 0.7, < 2)
|
@@ -91,6 +95,8 @@ GEM
|
|
91
95
|
addressable (>= 2.3.6)
|
92
96
|
crack (>= 0.3.2)
|
93
97
|
hashdiff (>= 0.4.0, < 2.0.0)
|
98
|
+
wisper (2.0.1)
|
99
|
+
wisper-rspec (1.1.0)
|
94
100
|
|
95
101
|
PLATFORMS
|
96
102
|
ruby
|
@@ -103,6 +109,7 @@ DEPENDENCIES
|
|
103
109
|
rubocop-faker
|
104
110
|
rubocop-rspec (~> 1.21)
|
105
111
|
webmock (~> 3.6)
|
112
|
+
wisper-rspec (~> 1.1.0)
|
106
113
|
|
107
114
|
BUNDLED WITH
|
108
115
|
2.1.4
|
@@ -23,12 +23,15 @@ Gem::Specification.new do |s|
|
|
23
23
|
s.executables = s.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
24
24
|
s.require_paths = ["lib"]
|
25
25
|
|
26
|
+
s.add_dependency "activemodel", "~> 5.0", ">= 5.0.0.1"
|
26
27
|
s.add_dependency "activesupport", "~> 5.0", ">= 5.0.0.1"
|
27
28
|
s.add_dependency "byebug", "~> 11.0"
|
28
29
|
s.add_dependency "graphlient", "~> 0.4.0"
|
29
30
|
s.add_dependency "jwt"
|
31
|
+
s.add_dependency "wisper", "~> 2.0.0"
|
30
32
|
|
31
33
|
s.add_development_dependency "rake", "~> 13.0"
|
32
34
|
s.add_development_dependency "rspec", "~> 3.7"
|
33
35
|
s.add_development_dependency "webmock", "~> 3.6"
|
36
|
+
s.add_development_dependency "wisper-rspec", "~> 1.1.0"
|
34
37
|
end
|
@@ -2,10 +2,13 @@
|
|
2
2
|
|
3
3
|
require "decidim/bulletin_board/version"
|
4
4
|
require "graphlient"
|
5
|
+
require "wisper"
|
6
|
+
require "active_model"
|
5
7
|
require "decidim/bulletin_board/jwk_utils"
|
6
8
|
require "decidim/bulletin_board/client"
|
7
9
|
require "decidim/bulletin_board/graphql/client"
|
8
10
|
require "decidim/bulletin_board/create_election"
|
11
|
+
require "decidim/bulletin_board/voter"
|
9
12
|
require "active_support/configurable"
|
10
13
|
require "jwt"
|
11
14
|
|
@@ -34,11 +34,23 @@ module Decidim
|
|
34
34
|
private_key && server && api_key
|
35
35
|
end
|
36
36
|
|
37
|
+
def sign_data(data)
|
38
|
+
JWT.encode(data, identification_private_key.keypair, "RS256")
|
39
|
+
end
|
40
|
+
|
37
41
|
def setup_election(election_data)
|
38
42
|
message_id = "#{election_data[:election_id]}.create_election+a.#{authority_slug}"
|
39
43
|
Decidim::BulletinBoard::CreateElection.call(election_data, message_id)
|
40
44
|
end
|
41
45
|
|
46
|
+
def cast_vote(election_data, voter_data, encrypted_vote)
|
47
|
+
form = Decidim::BulletinBoard::Voter::VoteForm.new(self, election_data, voter_data, encrypted_vote)
|
48
|
+
cast_vote = Decidim::BulletinBoard::Voter::CastVote.new(form)
|
49
|
+
cast_vote.on(:ok) { |pending_message| return pending_message }
|
50
|
+
cast_vote.on(:error) { |error_message| raise StandardError, error_message }
|
51
|
+
cast_vote.call
|
52
|
+
end
|
53
|
+
|
42
54
|
private
|
43
55
|
|
44
56
|
attr_reader :identification_private_key, :private_key
|
@@ -0,0 +1,60 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module BulletinBoard
|
5
|
+
module Voter
|
6
|
+
# This command uses the GraphQL client to cast the vote.
|
7
|
+
class CastVote
|
8
|
+
include Wisper::Publisher
|
9
|
+
# Public: Initializes the command.
|
10
|
+
#
|
11
|
+
# form - A form object with the params.
|
12
|
+
def initialize(form)
|
13
|
+
@form = form
|
14
|
+
end
|
15
|
+
|
16
|
+
# Executes the command. Broadcasts these events:
|
17
|
+
#
|
18
|
+
# - :ok when everything is valid and the mutation operation is successful.
|
19
|
+
# - :error if the form wasn't valid or the mutation operation was not successful.
|
20
|
+
#
|
21
|
+
# Returns nothing.
|
22
|
+
def call
|
23
|
+
return broadcast(:error, form.errors.full_messages.join(". ")) unless form.valid?
|
24
|
+
|
25
|
+
args = {
|
26
|
+
message_id: form.message_id,
|
27
|
+
signed_data: form.signed_data
|
28
|
+
}
|
29
|
+
|
30
|
+
begin
|
31
|
+
response = client.query do
|
32
|
+
mutation do
|
33
|
+
vote(messageId: args[:message_id], signedData: args[:signed_data]) do
|
34
|
+
pendingMessage do
|
35
|
+
status
|
36
|
+
end
|
37
|
+
error
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
return broadcast(:error, response.data.vote.error) if response.data.vote.error.present?
|
43
|
+
|
44
|
+
broadcast(:ok, response.data.vote.pending_message)
|
45
|
+
rescue Graphlient::Errors::FaradayServerError
|
46
|
+
broadcast(:error, "something went wrong")
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
private
|
51
|
+
|
52
|
+
attr_reader :form
|
53
|
+
|
54
|
+
def client
|
55
|
+
@client ||= BulletinBoard::Graphql::Client.client
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module BulletinBoard
|
5
|
+
module Voter
|
6
|
+
# A form object to handle some data transformation and validation to cast a vote.
|
7
|
+
class VoteForm
|
8
|
+
include ActiveModel::Validations
|
9
|
+
|
10
|
+
validates :election_data, :voter_data, :encrypted_vote, presence: true
|
11
|
+
validate :election_id_present
|
12
|
+
validate :voter_id_present
|
13
|
+
|
14
|
+
# Public: initialize the form
|
15
|
+
#
|
16
|
+
# bulletin_board_data - An instance of the bulletin board client
|
17
|
+
# election_data - A Hash including the necessary data from the election.
|
18
|
+
# voter_data - A Hash including the necessary data from the voter.
|
19
|
+
# encrypted_vote - A Hash including the encrypted vote to cast
|
20
|
+
def initialize(bulletin_board_client, election_data, voter_data, encrypted_vote)
|
21
|
+
@bulletin_board_client = bulletin_board_client
|
22
|
+
@election_data = election_data
|
23
|
+
@voter_data = voter_data
|
24
|
+
@encrypted_vote = encrypted_vote
|
25
|
+
end
|
26
|
+
|
27
|
+
# Public: returns a message identifier for the cast vote operation.
|
28
|
+
def message_id
|
29
|
+
@message_id ||= "#{election_id}.vote.cast+v.#{voter_id}"
|
30
|
+
end
|
31
|
+
|
32
|
+
# Public: uses the bulletin board client to sign the encrypted vote merged with the `message_id`.
|
33
|
+
def signed_data
|
34
|
+
@signed_data ||= bulletin_board_client.sign_data(encrypted_vote.merge(message_id: message_id))
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
attr_reader :bulletin_board_client, :election_data, :voter_data, :encrypted_vote
|
40
|
+
|
41
|
+
def election_id_present
|
42
|
+
errors.add(:election_data, "doesn't include the election id") unless election_id.present?
|
43
|
+
end
|
44
|
+
|
45
|
+
def election_id
|
46
|
+
return if election_data.blank?
|
47
|
+
|
48
|
+
election_data[:election_id]
|
49
|
+
end
|
50
|
+
|
51
|
+
def voter_id_present
|
52
|
+
errors.add(:voter_data, "doesn't include the voter id") unless voter_id.present?
|
53
|
+
end
|
54
|
+
|
55
|
+
def voter_id
|
56
|
+
return if voter_data.blank?
|
57
|
+
|
58
|
+
voter_data[:voter_id]
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: decidim-bulletin_board
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- David Morcillo
|
@@ -9,8 +9,28 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: exe
|
11
11
|
cert_chain: []
|
12
|
-
date: 2020-12-
|
12
|
+
date: 2020-12-08 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: activemodel
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
requirements:
|
18
|
+
- - "~>"
|
19
|
+
- !ruby/object:Gem::Version
|
20
|
+
version: '5.0'
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 5.0.0.1
|
24
|
+
type: :runtime
|
25
|
+
prerelease: false
|
26
|
+
version_requirements: !ruby/object:Gem::Requirement
|
27
|
+
requirements:
|
28
|
+
- - "~>"
|
29
|
+
- !ruby/object:Gem::Version
|
30
|
+
version: '5.0'
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 5.0.0.1
|
14
34
|
- !ruby/object:Gem::Dependency
|
15
35
|
name: activesupport
|
16
36
|
requirement: !ruby/object:Gem::Requirement
|
@@ -73,6 +93,20 @@ dependencies:
|
|
73
93
|
- - ">="
|
74
94
|
- !ruby/object:Gem::Version
|
75
95
|
version: '0'
|
96
|
+
- !ruby/object:Gem::Dependency
|
97
|
+
name: wisper
|
98
|
+
requirement: !ruby/object:Gem::Requirement
|
99
|
+
requirements:
|
100
|
+
- - "~>"
|
101
|
+
- !ruby/object:Gem::Version
|
102
|
+
version: 2.0.0
|
103
|
+
type: :runtime
|
104
|
+
prerelease: false
|
105
|
+
version_requirements: !ruby/object:Gem::Requirement
|
106
|
+
requirements:
|
107
|
+
- - "~>"
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: 2.0.0
|
76
110
|
- !ruby/object:Gem::Dependency
|
77
111
|
name: rake
|
78
112
|
requirement: !ruby/object:Gem::Requirement
|
@@ -115,6 +149,20 @@ dependencies:
|
|
115
149
|
- - "~>"
|
116
150
|
- !ruby/object:Gem::Version
|
117
151
|
version: '3.6'
|
152
|
+
- !ruby/object:Gem::Dependency
|
153
|
+
name: wisper-rspec
|
154
|
+
requirement: !ruby/object:Gem::Requirement
|
155
|
+
requirements:
|
156
|
+
- - "~>"
|
157
|
+
- !ruby/object:Gem::Version
|
158
|
+
version: 1.1.0
|
159
|
+
type: :development
|
160
|
+
prerelease: false
|
161
|
+
version_requirements: !ruby/object:Gem::Requirement
|
162
|
+
requirements:
|
163
|
+
- - "~>"
|
164
|
+
- !ruby/object:Gem::Version
|
165
|
+
version: 1.1.0
|
118
166
|
description: ''
|
119
167
|
email:
|
120
168
|
- david@codegram.com
|
@@ -142,6 +190,9 @@ files:
|
|
142
190
|
- lib/decidim/bulletin_board/graphql/client.rb
|
143
191
|
- lib/decidim/bulletin_board/jwk_utils.rb
|
144
192
|
- lib/decidim/bulletin_board/version.rb
|
193
|
+
- lib/decidim/bulletin_board/voter.rb
|
194
|
+
- lib/decidim/bulletin_board/voter/cast_vote.rb
|
195
|
+
- lib/decidim/bulletin_board/voter/vote_form.rb
|
145
196
|
homepage: https://github.com
|
146
197
|
licenses:
|
147
198
|
- AGPL-3.0
|