decidim-core 0.0.1.alpha7 → 0.0.1.alpha8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (84) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.txt +619 -0
  3. data/README.md +1 -1
  4. data/app/assets/javascripts/decidim.js.es6 +13 -0
  5. data/app/assets/stylesheets/decidim/_variables.scss +23 -0
  6. data/app/assets/stylesheets/decidim/application.sass +2 -0
  7. data/app/assets/stylesheets/decidim/extras/_turbolinks.scss +3 -0
  8. data/app/assets/stylesheets/decidim/modules/_cards.scss +0 -5
  9. data/app/assets/stylesheets/decidim/utils/_settings.scss +5 -11
  10. data/app/commands/decidim/authorize_user.rb +37 -0
  11. data/app/controllers/concerns/decidim/needs_authorization.rb +36 -0
  12. data/app/controllers/decidim/account_controller.rb +26 -0
  13. data/app/controllers/decidim/application_controller.rb +5 -0
  14. data/app/controllers/decidim/authorizations_controller.rb +76 -0
  15. data/app/controllers/decidim/devise/registrations_controller.rb +1 -1
  16. data/app/controllers/decidim/devise/sessions_controller.rb +8 -0
  17. data/app/controllers/decidim/locales_controller.rb +2 -0
  18. data/app/controllers/decidim/pages_controller.rb +10 -0
  19. data/app/controllers/decidim/participatory_processes_controller.rb +32 -0
  20. data/app/helpers/decidim/authorization_form_helper.rb +25 -0
  21. data/app/helpers/decidim/humanize_booleans_helper.rb +14 -0
  22. data/app/mailers/decidim/application_mailer.rb +1 -1
  23. data/app/models/decidim/abilities/everyone.rb +16 -0
  24. data/app/models/decidim/ability.rb +32 -0
  25. data/app/models/decidim/authorization.rb +25 -0
  26. data/app/models/decidim/participatory_process.rb +25 -0
  27. data/app/models/decidim/participatory_process_step.rb +38 -0
  28. data/app/models/decidim/user.rb +19 -0
  29. data/app/services/decidim/authorization_handler.rb +94 -0
  30. data/app/uploaders/decidim/application_uploader.rb +0 -2
  31. data/app/views/decidim/account/_authorizations.html.erb +52 -0
  32. data/app/views/decidim/account/show.html.erb +32 -0
  33. data/app/views/decidim/authorizations/index.html.erb +22 -0
  34. data/app/views/decidim/authorizations/new.html.erb +29 -0
  35. data/app/views/decidim/devise/confirmations/new.html.erb +27 -11
  36. data/app/views/decidim/devise/invitations/edit.html.erb +25 -10
  37. data/app/views/decidim/devise/passwords/edit.html.erb +30 -15
  38. data/app/views/decidim/devise/passwords/new.html.erb +25 -11
  39. data/app/views/decidim/devise/registrations/new.html.erb +48 -20
  40. data/app/views/decidim/devise/sessions/new.html.erb +40 -21
  41. data/app/views/decidim/devise/shared/_links.html.erb +18 -6
  42. data/app/views/decidim/participatory_processes/_no_processes_yet.html.erb +3 -0
  43. data/app/views/decidim/participatory_processes/_order_by_processes.html.erb +3 -0
  44. data/app/views/decidim/participatory_processes/_participatory_process.html.erb +26 -0
  45. data/app/views/decidim/participatory_processes/_process_header_home.html.erb +18 -0
  46. data/app/views/decidim/participatory_processes/_promoted_process.html.erb +32 -0
  47. data/app/views/decidim/participatory_processes/index.html.erb +15 -0
  48. data/app/views/decidim/participatory_processes/show.html.erb +15 -0
  49. data/app/views/devise/mailer/organization_admin_invitation_instructions.html.erb +1 -1
  50. data/app/views/devise/mailer/organization_admin_invitation_instructions.text.erb +1 -1
  51. data/app/views/layouts/decidim/_footer.html.erb +3 -3
  52. data/app/views/layouts/decidim/_header.html.erb +5 -2
  53. data/app/views/pages/404.html.erb +13 -0
  54. data/app/views/pages/500.html.erb +10 -0
  55. data/app/views/{decidim/home/show.html.erb → pages/home.html.erb} +0 -0
  56. data/app/views/pages/terms.ca.html.erb +4 -0
  57. data/app/views/pages/terms.en.html.erb +4 -0
  58. data/app/views/pages/terms.es.html.erb +4 -0
  59. data/config/i18n-tasks.yml +3 -0
  60. data/config/initializers/devise.rb +1 -1
  61. data/config/locales/ca.yml +84 -10
  62. data/config/locales/en.yml +84 -10
  63. data/config/locales/es.yml +84 -10
  64. data/config/routes.rb +14 -1
  65. data/db/migrate/20161013134732_add_promoted_flag_to_processes.rb +5 -0
  66. data/db/migrate/20161017085822_add_participatory_process_steps.rb +16 -0
  67. data/db/migrate/20161018091013_create_decidim_authorizations.rb +13 -0
  68. data/db/migrate/20161019072016_add_active_flag_to_step.rb +7 -0
  69. data/db/migrate/20161020080756_add_position_to_steps.rb +7 -0
  70. data/db/migrate/20161025125300_add_published_at_to_processes.rb +5 -0
  71. data/db/seeds.rb +81 -27
  72. data/lib/decidim/authorization_form_builder.rb +70 -0
  73. data/lib/decidim/core.rb +23 -5
  74. data/lib/decidim/core/engine.rb +21 -0
  75. data/lib/decidim/core/version.rb +1 -1
  76. data/lib/decidim/faker/localized.rb +162 -0
  77. data/lib/decidim/form_builder.rb +1 -1
  78. data/lib/tasks/decidim_tasks.rake +1 -1
  79. metadata +121 -15
  80. data/MIT-LICENSE +0 -20
  81. data/app/assets/javascripts/decidim.js +0 -23
  82. data/app/assets/stylesheets/decidim.scss +0 -16
  83. data/app/assets/stylesheets/decidim/utils/_variables.scss +0 -25
  84. data/app/controllers/decidim/home_controller.rb +0 -7
data/README.md CHANGED
@@ -25,4 +25,4 @@ $ gem install decidim
25
25
  Contribution directions go here.
26
26
 
27
27
  ## License
28
- The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
28
+ The gem is available as open source under the terms of the [AGPLv3 License](https://opensource.org/licenses/AGPL-3.0).
@@ -0,0 +1,13 @@
1
+ //= require foundation
2
+ //= require modernizr
3
+ //= require owl.carousel.min
4
+ //= require svg4everybody.min
5
+ //= require appendAround
6
+
7
+ /* globals svg4everybody */
8
+
9
+ $(document).on('turbolinks:load', () => {
10
+ $(document).foundation();
11
+ $('.js-append').appendAround();
12
+ svg4everybody();
13
+ });
@@ -0,0 +1,23 @@
1
+ // Variables
2
+ $body-font-color: #3D393C;
3
+
4
+ $primary: #ef604d !default;
5
+ $secondary: #599aa6 !default;
6
+ $success: #3adb76 !default;
7
+ $warning: #ffae00 !default;
8
+ $alert: #ec5840 !default;
9
+
10
+ $light-gray: #fafafa !default;
11
+ $light-gray-dark: darken($light-gray, 2.5) !default;
12
+ $medium-gray: #e8e8e8 !default;
13
+ $dark-gray: #2c2930 !default;
14
+ $black: #1a181d !default;
15
+ $white: #fff !default;
16
+
17
+ $twitter: #55acee !default;
18
+ $facebook: #3b5998 !default;
19
+ $google: #dd4b39 !default;
20
+
21
+ $muted: lighten($body-font-color, 30) !default;
22
+
23
+ $border: 1px solid $medium-gray !default;
@@ -1,3 +1,4 @@
1
+ @import "variables"
1
2
  @import "utils/*"
2
3
 
3
4
  @import foundation
@@ -5,3 +6,4 @@
5
6
 
6
7
  @import "modules/*"
7
8
  @import "layouts/*"
9
+ @import "extras/*"
@@ -0,0 +1,3 @@
1
+ .turbolinks-progress-bar{
2
+ background-color: $primary;
3
+ }
@@ -12,11 +12,6 @@ $card-margin-bottom: map-get($grid-column-gutter, medium);
12
12
 
13
13
  $card-footer-bg: $light-gray-dark;
14
14
 
15
- $card-proposal: $proposals;
16
- $card-action: $actions;
17
- $card-debate: $debates;
18
- $card-meeting: $meetings;
19
-
20
15
  $datetime-bg: $primary;
21
16
 
22
17
 
@@ -49,19 +49,13 @@ $global-font-size: 100%;
49
49
  $global-width: rem-calc(1200);
50
50
  $global-lineheight: 1.5;
51
51
  $foundation-palette: (
52
- primary: #ef604d,
53
- secondary: #599aa6,
54
- success: #57d685,
55
- warning: #ffae00,
56
- alert: #ec5840,
52
+ primary: $primary,
53
+ secondary: $secondary,
54
+ success: $success,
55
+ warning: $warning,
56
+ alert: $alert,
57
57
  );
58
- $light-gray: #fafafa;
59
- $medium-gray: #e8e8e8;
60
- $dark-gray: #2c2930;
61
- $black: #1a181d;
62
- $white: #fff;
63
58
  $body-background: $light-gray;
64
- $body-font-color: #3D393C;
65
59
  $body-font-family: 'Source Sans Pro', Helvetica, Roboto, Arial, sans-serif;
66
60
  $body-antialiased: true;
67
61
  $global-margin: 1rem;
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+ module Decidim
3
+ # A command to authorize a user with an authorization handler.
4
+ class AuthorizeUser < Rectify::Command
5
+ # Public: Initializes the command.
6
+ #
7
+ # handler - An AuthorizationHandler object.
8
+ def initialize(handler)
9
+ @handler = handler
10
+ end
11
+
12
+ # Executes the command. Braodcasts these events:
13
+ #
14
+ # - :ok when everything is valid.
15
+ # - :invalid if the handler wasn't valid and we couldn't proceed.
16
+ #
17
+ # Returns nothing.
18
+ def call
19
+ return broadcast(:invalid) unless handler.valid?
20
+
21
+ create_authorization
22
+ broadcast(:ok)
23
+ end
24
+
25
+ private
26
+
27
+ attr_reader :handler
28
+
29
+ def create_authorization
30
+ Authorization.create!(
31
+ user: handler.user,
32
+ name: handler.handler_name,
33
+ metadata: handler.metadata
34
+ )
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/concern"
4
+
5
+ module Decidim
6
+ # Shared behaviour for controllers that need authorization to work.
7
+ module NeedsAuthorization
8
+ extend ActiveSupport::Concern
9
+
10
+ included do
11
+ check_authorization
12
+
13
+ rescue_from CanCan::AccessDenied, with: :user_not_authorized
14
+
15
+ private
16
+
17
+ # Overwrites `cancancan`'s method to point to the correct ability class,
18
+ # since the gem expects the ability class to be in the root namespace.
19
+ def current_ability
20
+ @current_ability ||= Decidim::Ability.new(current_user)
21
+ end
22
+
23
+ # Handles the case when a user visits a path that is not allowed to them.
24
+ # Redirects the user to the root path and shows a flash message telling
25
+ # them they are not authorized.
26
+ def user_not_authorized
27
+ flash[:alert] = t("actions.unauthorized", scope: "decidim.core")
28
+ redirect_to(request.referrer || user_not_authorized_path)
29
+ end
30
+
31
+ def user_not_authorized_path
32
+ raise NotImplementedError
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+ require_dependency "decidim/application_controller"
3
+
4
+ module Decidim
5
+ # The controller to handle the user's account page.
6
+ class AccountController < ApplicationController
7
+ helper_method :authorizations, :handlers
8
+ authorize_resource :user_account, class: false
9
+
10
+ private
11
+
12
+ def handlers
13
+ @handlers ||= Decidim.authorization_handlers.reject do |handler|
14
+ authorized_handlers.include?(handler.handler_name)
15
+ end
16
+ end
17
+
18
+ def authorizations
19
+ @authorizations ||= current_user.authorizations
20
+ end
21
+
22
+ def authorized_handlers
23
+ authorizations.map(&:name)
24
+ end
25
+ end
26
+ end
@@ -4,8 +4,13 @@ module Decidim
4
4
  class ApplicationController < ActionController::Base
5
5
  include Decidim::NeedsOrganization
6
6
  include Decidim::LocaleSwitcher
7
+ include NeedsAuthorization
7
8
  protect_from_forgery with: :exception, prepend: true
8
9
 
9
10
  layout "application"
11
+
12
+ def user_not_authorized_path
13
+ decidim.root_path
14
+ end
10
15
  end
11
16
  end
@@ -0,0 +1,76 @@
1
+ # frozen_string_literal: true
2
+ require_dependency "decidim/application_controller"
3
+
4
+ module Decidim
5
+ # This controller allows users to create and destroy their authorizations. It
6
+ # shouldn't be necessary to expand it to add new authorization schemes.
7
+ class AuthorizationsController < ApplicationController
8
+ helper_method :handler, :handlers
9
+ before_action :valid_handler, only: [:new, :create]
10
+ before_action :only_one_handler?, only: [:index]
11
+
12
+ def new
13
+ authorize! current_user, Authorization
14
+ end
15
+
16
+ def index
17
+ authorize! current_user, Authorization
18
+ end
19
+
20
+ def create
21
+ authorize! current_user, Authorization
22
+
23
+ AuthorizeUser.call(handler) do
24
+ on(:ok) do
25
+ flash[:notice] = t("authorizations.create.success", scope: "decidim")
26
+ redirect_to account_path
27
+ end
28
+
29
+ on(:invalid) do
30
+ flash[:alert] = t("authorizations.create.error", scope: "decidim")
31
+ render action: :new
32
+ end
33
+ end
34
+ end
35
+
36
+ def destroy
37
+ @authorization = current_user.authorizations.find(params[:id])
38
+ authorize! current_user, @authorization
39
+
40
+ @authorization.destroy
41
+ flash[:notice] = t("authorizations.destroy.success", scope: "decidim")
42
+ redirect_to account_path
43
+ end
44
+
45
+ def handler
46
+ @handler ||= AuthorizationHandler.handler_for(handler_name, handler_params)
47
+ end
48
+
49
+ def handlers
50
+ @handlers ||= Decidim.authorization_handlers
51
+ end
52
+
53
+ protected
54
+
55
+ def handler_params
56
+ (params[:authorization_handler] || {}).merge(user: current_user)
57
+ end
58
+
59
+ def handler_name
60
+ params[:handler] || params[:authorization_handler][:handler_name]
61
+ end
62
+
63
+ def valid_handler
64
+ return true if handler
65
+
66
+ logger.warn "Invalid authorization handler given: #{handler_name} doesn't"\
67
+ "exist or you haven't added it to `Decidim.authorization_handlers`"
68
+
69
+ redirect_to(account_path) && (return false)
70
+ end
71
+
72
+ def only_one_handler?
73
+ redirect_to(action: :new, handler: handlers.first.handler_name) && return if handlers.length == 1
74
+ end
75
+ end
76
+ end
@@ -12,7 +12,7 @@ module Decidim
12
12
  protected
13
13
 
14
14
  def configure_permitted_parameters
15
- devise_parameter_sanitizer.permit(:sign_up, keys: [:name])
15
+ devise_parameter_sanitizer.permit(:sign_up, keys: [:name, :tos_agreement])
16
16
  end
17
17
 
18
18
  # Called before resource.save
@@ -6,6 +6,14 @@ module Decidim
6
6
  include Decidim::NeedsOrganization
7
7
  include Decidim::LocaleSwitcher
8
8
  layout "application"
9
+
10
+ def after_sign_in_path_for(user)
11
+ if user.is_a?(User) && user.sign_in_count == 1 && Decidim.authorization_handlers.any?
12
+ authorizations_path
13
+ else
14
+ super
15
+ end
16
+ end
9
17
  end
10
18
  end
11
19
  end
@@ -4,6 +4,8 @@ require_dependency "decidim/application_controller"
4
4
  module Decidim
5
5
  # A controller to allow users switching their locale.
6
6
  class LocalesController < ApplicationController
7
+ authorize_resource :locales, class: false
8
+
7
9
  def create
8
10
  if current_user && params["locale"] && available_locales.include?(params["locale"])
9
11
  current_user.update_attribute(:locale, params["locale"])
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+ require_dependency "decidim/application_controller"
3
+
4
+ module Decidim
5
+ # This controller serves static pages using HighVoltage.
6
+ class PagesController < ApplicationController
7
+ include HighVoltage::StaticPage
8
+ authorize_resource :public_pages, class: false
9
+ end
10
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+ require_dependency "decidim/application_controller"
3
+
4
+ module Decidim
5
+ # A controller that holds the logic to show ParticipatoryProcesses in a
6
+ # public layout.
7
+ class ParticipatoryProcessesController < ApplicationController
8
+ helper_method :participatory_processes, :participatory_process, :promoted_processes
9
+
10
+ def index
11
+ authorize! :read, ParticipatoryProcess
12
+ end
13
+
14
+ def show
15
+ authorize! :read, participatory_process
16
+ end
17
+
18
+ private
19
+
20
+ def participatory_process
21
+ @participatory_process ||= ParticipatoryProcess.find(params[:id])
22
+ end
23
+
24
+ def participatory_processes
25
+ @participatory_processes ||= current_organization.participatory_processes.includes(:active_step).published
26
+ end
27
+
28
+ def promoted_processes
29
+ @promoted_processes ||= participatory_processes.promoted
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+ module Decidim
3
+ # A heper to expose an easy way to add authorization forms in a view.
4
+ module AuthorizationFormHelper
5
+ # Creates a ew authorization form in a view, accepts the same arguments as
6
+ # `form_for`.
7
+ #
8
+ # record - The record to use in the form, it shoulde be a descendant of
9
+ # AuthorizationHandler.
10
+ # options - An optional hash with options to pass wo the form builder.
11
+ # block - A block with the content of the form.
12
+ #
13
+ # Returns a String.
14
+ def authorization_form_for(record, options = {}, &block)
15
+ default_options = {
16
+ builder: AuthorizationFormBuilder,
17
+ as: "authorization_handler",
18
+ url: authorizations_path
19
+ }
20
+
21
+ options = default_options.merge(options)
22
+ form_for(record, options, &block)
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+ module Decidim
3
+ # Helper to print booleans in a human way.
4
+ module HumanizeBooleansHelper
5
+ # Displays booleans in a human way (yes/no, supporting i18n). Supports
6
+ # `nil` values as `false`.
7
+ #
8
+ # boolean - a Boolean that will be displayed in a human way.
9
+ def humanize_boolean(boolean)
10
+ value = boolean ? "true" : "false"
11
+ I18n.t(value, scope: "booleans")
12
+ end
13
+ end
14
+ end
@@ -5,7 +5,7 @@ module Decidim
5
5
  class ApplicationMailer < ActionMailer::Base
6
6
  include Roadie::Rails::Automatic
7
7
 
8
- default from: "from@example.com"
8
+ default from: Decidim.config.mailer_sender
9
9
  layout "mailer"
10
10
  end
11
11
  end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+ module Decidim
3
+ module Abilities
4
+ # Defines the base abilities for any user. Guest users will use these too.
5
+ # Intended to be used with `cancancan`.
6
+ class Everyone
7
+ include CanCan::Ability
8
+
9
+ def initialize(_user)
10
+ can :read, ParticipatoryProcess, &:published?
11
+ can :read, :public_pages
12
+ can :manage, :locales
13
+ end
14
+ end
15
+ end
16
+ end