Giter Club home page Giter Club logo

gdpr_rails's Introduction

GDPR RAILS

Rails Engine for the GDPR compliance

RB

The world needs some privacy, please

Build Status Maintainability Coverage Status

About this project

PolicyManager (Aka GDPR Rails) was created with flexibility in mind to comply with the requirements of the GDPR (General Data Protection Regulation). It's currently being developed at preyproject and will be battle-tested on preyproject.com from May 25th.

Main Features:

Policy Rules

  • Configurable policy rules, supports activerecord validations for new or existing users
  • Supports session-less consent policies which will become persistent once the user signs in or signs up
  • Versioning system for new policies
  • JSON endpoints to handle pending policies and portability logic in order to be implemented in client only interfaces, ie: frontend apps like React, Vue, Backbone, you name it.

Portability

Portability module lets you define export options, that will generate a navigable static HTML site with all the data you've defined in the portability rules with json support too.

  • Seamless data export with configurable templates
  • Configurable Mailer templates for progress & download completion
  • Downloads images to the local filesystem in order to comply with GDPR requirements on data accessibility.
  • Zips all the information and delivers it with a expirable download link
  • ActiveJob to handle the process
  • Behind the scenes uses Rails's ActiveStorage (with an optional Paperclip support) in which you can set up storages, like S3, Google

Scripts & Cookies

Configurable scripts which will bind cookie names in order to handle the script rendering and the cookie clean up.

Forgetability

  • TBD, for now we simply delete all the data when a user closes the account. This could be handled in the future with encryption like in emails or other kind of sensible fields on a database.

Admin Panel

Admin panel

Installation

Add this line to your application's Gemfile:

as gem 'gdpr_rails'

Then in your application.rb require the policy_manager lib with

require "policy_manager"

Install & run the migrations

rake policy_manager:install:migrations

Rails ActiveStorage

By default The engine will use the app's active_storage setup for file handling

Rails Paperclip

If you don't use activeStorage in your application, run this migration to use paperclip

class PaperclipFieldsToPortability < ActiveRecord::Migration[5.2]
  def change
    add_column :policy_manager_portability_requests, :attachment, :string
    add_column :policy_manager_portability_requests , :attachment_file_name, :string
    add_column :policy_manager_portability_requests , :attachment_file_size, :string
    add_column :policy_manager_portability_requests , :attachment_file_content_type, :string
    add_column :policy_manager_portability_requests, :attachment_content_type, :string
  end
end

and in your Gdpr config add paperclip option to enable it

PolicyManager::Config.setup do |config|
  config.paperclip = true
  #....
end

Usage examples

Basic config

config = PolicyManager::Config.setup do |c|
  c.logout_url = "logout"
  c.from_email = "[email protected]"
  c.admin_email_inbox = "[email protected]"

  c.user_resource = User # defaults to User
  c.admin_user_resource = AdminUser # defaults to User
  # is_admin method in order for engine to know
  # how to authorize admin only areas
  c.is_admin_method = ->(o){
    o.is_god? || o.is_admin? || o.is_me? || o.watheva
  }

end

In order for this engine to work you must supply some rules according to your needs, in order to be in comply with the GDPR you will need 3 rules at least. A cookie consent, a Privacy& TOS and an Age confirmation (+16). So, let's start by doing that:

Term rules

In your app router add the following:

  mount PolicyManager::Engine => "/policies"

Then add the concern to your User model:

class User < ApplicationRecord
  include PolicyManager::Concerns::UserBehavior
end

Then add an initializer, config/initializers/gdpr.rb and inside it set your policy rules.

PolicyManager::Config.setup do |c|
  c.add_rule({name: "cookie", sessionless: true }  )
  c.add_rule({name: "age", validates_on: [:create, :update], blocking: true })
  c.add_rule({name: "privacy_terms", validates_on: [:create, :update], blocking: true })
end

# If you are using devise, you must extend engines's controller with devise helpers in order to get current_user
PolicyManager::UserTermsController.send(:include, Devise::Controllers::Helpers)

Note that you will need to go to the policy panel and add the policy content for each term at http://localhost:3000/policies/categories otherwise you will see errors like no term for #{rule} policy

ActiveRecord Methods

When the policies are configured will generate some helper methods on User model. For example, with the example above you will get the following methods for free:

  • @user.has_consented_cookie?
  • @user.has_consented_age?
  • @user.has_consented_privacy_terms?

also you get:

  • @user.pending_policies
  • @user.pending_blocking_policies
  • @user.confirm_all_policies!
  • @user.reject_all_policies!
  • @user.needs_policy_confirmation_for?(rule)
  • @user.policy_term_on(rule)
  • @user.policy_user_term_on(term)
  • @user.handle_policy_for(term)
  • @user.can_request_portability?

Policy rules:

  • sessionless: will allow rules to be available for non logged users, if accepted a cookie cookies["policy_rule_cookie"] will be generated. If then the user sign in or signs up you could get this cookie it will persist in database.

Use this in your controller:

@user.accept_policy_from("your_cookie") if cookies["policy_rule_your_cookie"] == "accepted"
  • validates_on: will require users validation, will automagically create virtual attributes for the policy you set, so, if you set age in your config you must supply in your forms a policy_rule_age checkbox in your form, if you don't supply those then the user validation will return errors on policy_rule_age . Don't forget to add the fields in your strong params in the controller which handles the request.
  • if: you can add conditions as a Proc in order skip validations:
  c.add_rule({name: "age", validates_on: [:create, :update],
              if: ->(o){ o.enabled_for_validation } })
  • on_reject: Proc which will be triggered when user rejects a policy (has an argument that contains the controller context)
  • on_accept: Proc which will be triggered when user accepts a policy (has an argument that contains the controller context)

Example

This is an example for a cookie rule. The expected behavior would be when the user rejects cookies iterate over our scripts and delete cookies:

  c.add_rule({name: "cookie", sessionless: true, on_reject: ->(context){
      PolicyManager::Script.cookies
      .select{|o| !o.permanent }
      .each{|o|
        o.cookies.each{|c|
          context.send(:cookies).delete(c, domain: o.domain)
        }
      }
    }
  })

Policy handling:

There are some endpoints that will handle json in order to interact with client applications, like react interfaces, $.ajax etc. you can also use the html web panel directly from the engine. So, if the Engine was mounted on /policies then your routes will be:

pending_user_terms          GET    /user_terms/pending(.:format)                     policy_manager/user_terms#pending
accept_multiples_user_terms PUT    /user_terms/accept_multiples(.:format)            policy_manager/user_terms#accept_multiples
blocking_terms_user_terms   GET    /user_terms/blocking_terms(.:format)              policy_manager/user_terms#blocking_terms
accept_user_term            PUT    /user_terms/:id/accept(.:format)                  policy_manager/user_terms#accept
reject_user_term            PUT    /user_terms/:id/reject(.:format)                  policy_manager/user_terms#reject
user_terms                  GET    /user_terms(.:format)                             policy_manager/user_terms#index
user_term                   GET    /user_terms/:id(.:format)                         policy_manager/user_terms#show

Scripts & Cookies

This is supposed to in mix with your declared cookie term. So, this configuration let's you declare your external scripts that are related with tracking, ie: Google Analytics, Kissmetrics, Google Tag manager, etc... This configuration expects that you declare scripts that will be rendered over certain contexts (environments) and have the names (and domains) of the cookies that those scripts generates.

example:

  c.add_script(
    name: "google analytics",
    script: 'shared/analytics/universal',
    environments: [:production],
    description: ->{I18n.t("cookies.list.google_analytics")},
    cookies: ["_ga", "_gid", "_gat_XXX-XXX"],
    domain: ".panel.preyproject.com"
  )

Importance of declaring the cookie domain: When you clean up the cookies (like in the example above for on_reject) is important to set the domain that this cookies belongs. In some cases this external scripts could add the cookie on your subdomain or your base domain. In out case we found that some cookies are generated on panel.preyproject.com or .panel.preyproject or just preyproject.com. Try to get that information on chrome console -> application -> cookies.

Example in your layout:

This is an example on how you would render your scripts only if the user has accepted the cookie

    <% if current_user.has_consented_cookie? %>
     <!--  # this cames from portability/helpers/scripts_helpers -->
      <%= render_scripts %>
    <% end %>

render_scripts will iterate over your configured scripts and render the templates defined on PolicyManager::Script

Portability Rules

Export option & Portability rules will allow you to set up how and which data you will give to a requester user.

Exporter:

  • path: where the folder will be generated, usually can be set on /tmp, this will need a pathname, like Rails.root.join("tmp/export")
  • resource: which model , ie: User
  • index_template: The first page. defaults to a simple ul li list of links tied to your rules, this expects a Pathname or a String with your template
  • layout: A layout template this expects a layout name which has to be available on your app.
  • after_zip: a callback to handle the zip file on the resource, something like:
after_zip: ->(zip_path, resource){
  puts "THIS IS GREAT #{zip_path} was zipped, now what ??"
}
  • mail_helpers: If you have some helpers you want to add to the mailers, then you can pass an Array of helpers, [MailHelper, OtherMailHelper],
  • attachment_path: Paperclip upload path , defaults to "portability/:id/build.zip",
  • attachment_storage: Paperclip storage, defaults to filesystem , you can set s3 or google or whatever paperclip supports
  • expiration_link: integer, defaults to 60 (1 minute),

Portability Rules:

Portability rules collection render. This will call a @user.articles and will auto paginate records

PolicyManager::Config.setup do |c|

  # minimal exporter setup
  c.exporter = {
    path: Rails.root + "tmp/export",
    resource: 'User'
  }

  # portability rules, collection render. This will call a @user.articles
  # and will auto paginate records
  # template expects a string or path
  c.add_portability_rule({
    name: "exportable_data",
    collection: :articles,
    template: "hello, a collection will be rendered here use @collection.to_json",
    json_template: "collection.json.jbuilder", # or Rails.root.join("app/views/collection.json.jbuilder")

    per: 10
  })

  # portability rules, member render. This will call a @user.account_data
  # template expects a string or path
  c.add_portability_rule({
    name: "my_account",
    member: :account_data,
    template: "hellow , here a resource will be rendered <%= @member.to_json %> "
  })

end

Important:

If the content that will be delivered has images use the image_tag in your template. This helper was reimplemented in order for the remote image to be downloaded automatically. And will be served locally in order to comply with the Portability data requirements.

Web Endpoints and methods for user:

user_portability_requests   GET    /user_portability_requests(.:format)              policy_manager/user_portability_requests#index
                            POST   /user_portability_requests(.:format)              policy_manager/user_portability_requests#create
user_portability_request    DELETE /user_portability_requests/:id(.:format)          policy_manager/user_portability_requests#destroy

Web Endpoints and methods for admin :

this routes are accessible from engine's admin panel


confirm_portability_request GET    /portability_requests/:id/confirm(.:format)       policy_manager/portability_requests#confirm
portability_requests        GET    /portability_requests(.:format)                   policy_manager/portability_requests#index
portability_request         DELETE /portability_requests/:id(.:format)               policy_manager/portability_requests#destroy

TO DO

  • anonimyzer

Acknowledgments

Main maintainers

Contributing

  • Just fork the repo and send us a Pull Request, with some tests please :)
  • FYI: The CI pipeline on travis will require gemlocks for each or the Rails versions we test against.
    • Run bundle exec appraisal install and commit the generated files in the ./gemfile/ directory
    • Check out Appraisal for more context.

License

The gem is available as open source under the terms of the MIT License.

gdpr_rails's People

Contributors

ben-gy avatar etiennedepaulis avatar kasparsj avatar masonhensley avatar michelson avatar ohbarye avatar oscartzgz avatar patriciojofre avatar piotaixr avatar sapientpants avatar tpei avatar viamin avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

gdpr_rails's Issues

Chartkick security vulnerability

The chartkick dependency in this repo is fixed to 2.3.4. Due to a security vulnerability in chartkick, it should be updated to support >= 3.2.0.

Rails version too restrictive for Rails 6 patch releases.

Fetching gem metadata from https://rubygems.org/.........
Fetching gem metadata from https://rubygems.org/.
Resolving dependencies.....
Bundler could not find compatible versions for gem "rails":
  In Gemfile:
    rails (= 6.0.1)

    gdpr_rails was resolved to 0.5.1, which depends on
      rails (>= 5.1.4, <= 6)

[readme?] Problem when user class has different name than User

Version: 0.3.4

My user class is sth like BlahUser.
Configuration:

PolicyManager::Config.setup do |c|
  c.user_resource = BlahUser # defaults to User
  c.admin_user_resource = BlahUser # defaults to User
  [...]
end

When i visit /policies/user_portability_requests, i have an error saying that PortabilityRequests does not have a field blah_user_id. I had to change the migration CreatePolicyManagerPortabilityRequests by hand (rename user_id to blah_user_id).

Is it the expected behavior or am I missing sth? (or the Readme?)

Rails 7 support?

Hi,

Greate tool, but are you planning to roll out Rails 7 support? Currently gemspec restrict it to install in Rails 7 env... is it intentional?

Ability to accept/reject specific cookie

Hi,

Awesome engine! thanks for the work.

A question: Following what is recommended by French authorities, we'd like to allow users to pick which service (GA, optimizely, whateva...) they want to accept.
You have an example here of how it would work (https://www.cnil.fr/=> click on the top page banner on "personnaliser" to open the modal).

Is it possible already on gdpr_rails to have
@user.has_consented_cookie? applied to specific cookies ? Let me give you an example, which is basically how the above website cnil.fr handles it:

A (not logged-in) user sees two lines

  • google analytics + 2 buttons accept/reject
  • optimizely + 2 buttons accept/reject
  • and so on...
    And based on the user choice for EACH service, this is stored in the gdpr_rails cookie consent.

Is that how it works today ? is it possible to set up this behavior using gdpr_rails or is it really only "accept all cookies or reject all cookies" for the moment?

Could not figure it out based on the documentation. Thanks

M.

Rails 5.2 Compatibility

Hey there, was curious to know if you were able to get this working with Rails 5.2. I'm getting the following error:

Bundler could not find compatible versions for gem "rails":
  In snapshot (Gemfile.lock):
    rails (= 5.2.0)

  In Gemfile:
    rails (= 5.2.0)

    gdpr_rails was resolved to 0.2.1, which depends on
      rails (~> 5.1.4)

Running `bundle update` will rebuild your snapshot from scratch, using only
the gems in your Gemfile, which may resolve the conflict.

Accessing and rendering terms

Hi, all info related to terms seems to be on a User object @userโ€ฆ.
Is there a way to easily render out the terms posted and saved in policy_manager_terms?

The reason why I see this as useful and needed is that you can write your policies in the policy manager, and then show it on your privacy page. Say:

<%= policy_rule_age_content %>

from there it fetches the last and most updated one that is published and shows that.

Issue with paperclip

Hi there,

I have followed the instructions as per README and got gdpr_rails working with active_admin. However when I tried to look at the User model inside activeAdmin I get the following error:

Bootsnap::LoadPathCache::FallbackScan at /admin/users

and trace back to an issue with paperclip. Weird thing is, I am using activestorage so I skipped the paperclip instructions.

gdpr_rails (0.5.0) app/models/policy_manager/concerns/active_storage_behavior.rb

# -*- encoding : utf-8 -*-

require "paperclip"

module PolicyManager::Concerns::ActiveStorageBehavior

  extend ActiveSupport::Concern

  included do

I dont think paperclip is required in active_storage_behavior.rb` otherwise I have no idea on how to fix it.
Thanks in advance!!!

here is my initializer gdrp.rb

PolicyManager::Config.setup do |c|
  c.admin_user_resource = AdminUser # Active Admin default
  c.logout_url = "/admin/logout"
  c.from_email = "[email protected]" # Active Admin default
  c.admin_email_inbox = "[email protected]"
  c.paperclip = false
  # Cookie consent
  c.add_rule({name: "cookie", sessionless: true }  )
  # Age confirmation
  c.add_rule({name: "age", validates_on: [:create, :update], blocking: true })
  # Privacy & TOC
  c.add_rule({name: "privacy_terms", validates_on: [:create, :update], blocking: true })

PolicyManager::UserTermsController.send(:include, Devise::Controllers::Helpers)
end

and gemfile.lock

GEM
  remote: https://rubygems.org/
  specs:
    aasm (5.0.6)
      concurrent-ruby (~> 1.0)
    actioncable (5.2.3)
      actionpack (= 5.2.3)
      nio4r (~> 2.0)
      websocket-driver (>= 0.6.1)
    actionmailer (5.2.3)
      actionpack (= 5.2.3)
      actionview (= 5.2.3)
      activejob (= 5.2.3)
      mail (~> 2.5, >= 2.5.4)
      rails-dom-testing (~> 2.0)
    actionpack (5.2.3)
      actionview (= 5.2.3)
      activesupport (= 5.2.3)
      rack (~> 2.0)
      rack-test (>= 0.6.3)
      rails-dom-testing (~> 2.0)
      rails-html-sanitizer (~> 1.0, >= 1.0.2)
    actionview (5.2.3)
      activesupport (= 5.2.3)
      builder (~> 3.1)
      erubi (~> 1.4)
      rails-dom-testing (~> 2.0)
      rails-html-sanitizer (~> 1.0, >= 1.0.3)
    activeadmin (2.3.1)
      arbre (~> 1.2, >= 1.2.1)
      formtastic (~> 3.1)
      formtastic_i18n (~> 0.4)
      inherited_resources (~> 1.7)
      jquery-rails (~> 4.2)
      kaminari (~> 1.0, >= 1.0.1)
      railties (>= 5.0, < 6.1)
      ransack (~> 2.1, >= 2.1.1)
      sassc-rails (~> 2.1)
      sprockets (>= 3.0, < 4.1)
      sprockets-es6 (~> 0.9, >= 0.9.2)
    activejob (5.2.3)
      activesupport (= 5.2.3)
      globalid (>= 0.3.6)
    activemodel (5.2.3)
      activesupport (= 5.2.3)
    activerecord (5.2.3)
      activemodel (= 5.2.3)
      activesupport (= 5.2.3)
      arel (>= 9.0)
    activestorage (5.2.3)
      actionpack (= 5.2.3)
      activerecord (= 5.2.3)
      marcel (~> 0.3.1)
    activesupport (5.2.3)
      concurrent-ruby (~> 1.0, >= 1.0.2)
      i18n (>= 0.7, < 2)
      minitest (~> 5.1)
      tzinfo (~> 1.1)
    addressable (2.7.0)
      public_suffix (>= 2.0.2, < 5.0)
    arbre (1.2.1)
      activesupport (>= 3.0.0)
    archive-zip (0.12.0)
      io-like (~> 0.3.0)
    arel (9.0.0)
    babel-source (5.8.35)
    babel-transpiler (0.7.0)
      babel-source (>= 4.0, < 6)
      execjs (~> 2.0)
    bcrypt (3.1.13)
    better_errors (2.5.1)
      coderay (>= 1.0.0)
      erubi (>= 1.0.0)
      rack (>= 0.9.0)
    bindex (0.8.1)
    binding_of_caller (0.8.0)
      debug_inspector (>= 0.0.1)
    bootsnap (1.4.5)
      msgpack (~> 1.0)
    builder (3.2.3)
    byebug (11.0.1)
    capybara (3.29.0)
      addressable
      mini_mime (>= 0.1.3)
      nokogiri (~> 1.8)
      rack (>= 1.6.0)
      rack-test (>= 0.6.3)
      regexp_parser (~> 1.5)
      xpath (~> 3.2)
    chartkick (3.2.1)
    childprocess (2.0.0)
      rake (< 13.0)
    chromedriver-helper (2.1.1)
      archive-zip (~> 0.10)
      nokogiri (~> 1.8)
    coderay (1.1.2)
    coffee-rails (4.2.2)
      coffee-script (>= 2.2.0)
      railties (>= 4.0.0)
    coffee-script (2.4.1)
      coffee-script-source
      execjs
    coffee-script-source (1.12.2)
    concurrent-ruby (1.1.5)
    crass (1.0.4)
    debug_inspector (0.0.3)
    devise (4.7.1)
      bcrypt (~> 3.0)
      orm_adapter (~> 0.1)
      railties (>= 4.1.0)
      responders
      warden (~> 1.2.3)
    erubi (1.8.0)
    execjs (2.7.0)
    ffi (1.11.1)
    formtastic (3.1.5)
      actionpack (>= 3.2.13)
    formtastic_i18n (0.6.0)
    gdpr_rails (0.5.0)
      aasm
      chartkick (>= 3.2.0)
      groupdate (= 4.0.0)
      rails (>= 5.1.4, <= 6)
      redcarpet
      rubyzip (>= 1.0.0)
      will_paginate
    globalid (0.4.2)
      activesupport (>= 4.2.0)
    groupdate (4.0.0)
      activesupport (>= 4.2)
    has_scope (0.7.2)
      actionpack (>= 4.1)
      activesupport (>= 4.1)
    i18n (1.6.0)
      concurrent-ruby (~> 1.0)
    inherited_resources (1.11.0)
      actionpack (>= 5.0, < 6.1)
      has_scope (~> 0.6)
      railties (>= 5.0, < 6.1)
      responders (>= 2, < 4)
    io-like (0.3.0)
    jbuilder (2.9.1)
      activesupport (>= 4.2.0)
    jquery-rails (4.3.5)
      rails-dom-testing (>= 1, < 3)
      railties (>= 4.2.0)
      thor (>= 0.14, < 2.0)
    kaminari (1.1.1)
      activesupport (>= 4.1.0)
      kaminari-actionview (= 1.1.1)
      kaminari-activerecord (= 1.1.1)
      kaminari-core (= 1.1.1)
    kaminari-actionview (1.1.1)
      actionview
      kaminari-core (= 1.1.1)
    kaminari-activerecord (1.1.1)
      activerecord
      kaminari-core (= 1.1.1)
    kaminari-core (1.1.1)
    listen (3.1.5)
      rb-fsevent (~> 0.9, >= 0.9.4)
      rb-inotify (~> 0.9, >= 0.9.7)
      ruby_dep (~> 1.2)
    loofah (2.2.3)
      crass (~> 1.0.2)
      nokogiri (>= 1.5.9)
    mail (2.7.1)
      mini_mime (>= 0.1.1)
    marcel (0.3.3)
      mimemagic (~> 0.3.2)
    method_source (0.9.2)
    mimemagic (0.3.3)
    mini_mime (1.0.2)
    mini_portile2 (2.4.0)
    minitest (5.11.3)
    msgpack (1.3.1)
    nio4r (2.5.1)
    nokogiri (1.10.4)
      mini_portile2 (~> 2.4.0)
    orm_adapter (0.5.0)
    polyamorous (2.3.0)
      activerecord (>= 5.0)
    public_suffix (4.0.1)
    puma (3.12.1)
    rack (2.0.7)
    rack-test (1.1.0)
      rack (>= 1.0, < 3)
    rails (5.2.3)
      actioncable (= 5.2.3)
      actionmailer (= 5.2.3)
      actionpack (= 5.2.3)
      actionview (= 5.2.3)
      activejob (= 5.2.3)
      activemodel (= 5.2.3)
      activerecord (= 5.2.3)
      activestorage (= 5.2.3)
      activesupport (= 5.2.3)
      bundler (>= 1.3.0)
      railties (= 5.2.3)
      sprockets-rails (>= 2.0.0)
    rails-dom-testing (2.0.3)
      activesupport (>= 4.2.0)
      nokogiri (>= 1.6)
    rails-html-sanitizer (1.2.0)
      loofah (~> 2.2, >= 2.2.2)
    railties (5.2.3)
      actionpack (= 5.2.3)
      activesupport (= 5.2.3)
      method_source
      rake (>= 0.8.7)
      thor (>= 0.19.0, < 2.0)
    rake (12.3.3)
    ransack (2.3.0)
      actionpack (>= 5.0)
      activerecord (>= 5.0)
      activesupport (>= 5.0)
      i18n
      polyamorous (= 2.3.0)
    rb-fsevent (0.10.3)
    rb-inotify (0.10.0)
      ffi (~> 1.0)
    redcarpet (3.5.0)
    regexp_parser (1.6.0)
    responders (3.0.0)
      actionpack (>= 5.0)
      railties (>= 5.0)
    ruby_dep (1.5.0)
    rubyzip (1.2.4)
    sass (3.7.4)
      sass-listen (~> 4.0.0)
    sass-listen (4.0.0)
      rb-fsevent (~> 0.9, >= 0.9.4)
      rb-inotify (~> 0.9, >= 0.9.7)
    sass-rails (5.1.0)
      railties (>= 5.2.0)
      sass (~> 3.1)
      sprockets (>= 2.8, < 4.0)
      sprockets-rails (>= 2.0, < 4.0)
      tilt (>= 1.1, < 3)
    sassc (2.2.0)
      ffi (~> 1.9)
    sassc-rails (2.1.2)
      railties (>= 4.0.0)
      sassc (>= 2.0)
      sprockets (> 3.0)
      sprockets-rails
      tilt
    selenium-webdriver (3.142.4)
      childprocess (>= 0.5, < 3.0)
      rubyzip (~> 1.2, >= 1.2.2)
    spring (2.1.0)
    spring-watcher-listen (2.0.1)
      listen (>= 2.7, < 4.0)
      spring (>= 1.2, < 3.0)
    sprockets (3.7.2)
      concurrent-ruby (~> 1.0)
      rack (> 1, < 3)
    sprockets-es6 (0.9.2)
      babel-source (>= 5.8.11)
      babel-transpiler
      sprockets (>= 3.0.0)
    sprockets-rails (3.2.1)
      actionpack (>= 4.0)
      activesupport (>= 4.0)
      sprockets (>= 3.0.0)
    sqlite3 (1.4.1)
    thor (0.20.3)
    thread_safe (0.3.6)
    tilt (2.0.9)
    turbolinks (5.2.0)
      turbolinks-source (~> 5.2)
    turbolinks-source (5.2.0)
    tzinfo (1.2.5)
      thread_safe (~> 0.1)
    uglifier (4.1.20)
      execjs (>= 0.3.0, < 3)
    warden (1.2.8)
      rack (>= 2.0.6)
    web-console (3.7.0)
      actionview (>= 5.0)
      activemodel (>= 5.0)
      bindex (>= 0.4.0)
      railties (>= 5.0)
    websocket-driver (0.7.1)
      websocket-extensions (>= 0.1.0)
    websocket-extensions (0.1.4)
    will_paginate (3.1.8)
    xpath (3.2.0)
      nokogiri (~> 1.8)

PLATFORMS
  ruby

DEPENDENCIES
  activeadmin
  better_errors
  binding_of_caller
  bootsnap (>= 1.1.0)
  byebug
  capybara (>= 2.15)
  chromedriver-helper
  coffee-rails (~> 4.2)
  devise
  gdpr_rails
  jbuilder (~> 2.5)
  listen (>= 3.0.5, < 3.2)
  puma (~> 3.11)
  rails (~> 5.2.3)
  sass-rails (~> 5.0)
  selenium-webdriver
  spring
  spring-watcher-listen (~> 2.0.0)
  sqlite3
  turbolinks (~> 5)
  uglifier (>= 1.3.0)
  web-console (>= 3.3.0)

RUBY VERSION
   ruby 2.6.3p62

BUNDLED WITH
   1.17.2

current_user when not using Devise

Any thoughts as to how current_user should be made available when Devise (and hence its helper that generates current_user) isn't being used?

I'm happy to work on this, but wanted to ask if anyone has an idea for how this should be done.

undefined local variable or method `acts_as_messageable'

The error arises when User model is configured with Mailboxer gem and it say's acts_as_messageable is undefined.
I tried to add acts_as_messageable method inside module PolicyManager::Concerns::UserBehavior
but still error shows up.
In model user.rb:

class User < ApplicationRecord
 
  # Include default devise modules.
  devise :database_authenticatable, :registerable,
          :recoverable, :rememberable, :trackable, :validatable,
          :confirmable   #, :omniauthable  #,:token_authenticatable
  include DeviseTokenAuth::Concerns::User
  
  include PolicyManager::Concerns::UserBehavior  #policy management
  
  acts_as_messageable
end

In gem PolicyManager::Concerns::UserBehavior

module PolicyManager::Concerns::UserBehavior
  extend ActiveSupport::Concern
  module ActiveRecordExtension
    def acts_as_messageable
   #code
    end
  end

How to store cookie consent ?

The method explaine in the readme does not seem to work (or even exist):

@user.store_policy_cookie if cookies["policy_rule_cookie"] == "accepted"

I had to do something like this to make it work:

class ApplicationController < ActionController::Base

  protected

  def after_sign_in_path_for(user)
    handle_cookie_policy_for(user) if cookies["cookieconsent_status"] == "dismiss"

    super(user)
  end

  def handle_cookie_policy_for(user)
    rule_name = "cookie"

    return if !user.needs_policy_confirmation_for?(rule_name)

    term = user.policy_term_on(rule_name)
    user.handle_policy_for(term).accept!
  end
end

Should the Readme be updated or is it me not using correctly this method ?
Thanks for your help

No such file to load -- paperclip.rb

Upgrading to 0.5+ keeps the app from running with the following error:

5: from /home/ubuntu/app/shared/bundle/ruby/2.6.0/gems/gdpr_rails-0.5.1/app/models/policy_manager/concerns/paperclip_behavior.rb:2:in `<main>'
4: from /home/ubuntu/app/shared/bundle/ruby/2.6.0/gems/activesupport-6.0.0/lib/active_support/dependencies.rb:325:in `require'
3: from /home/ubuntu/app/shared/bundle/ruby/2.6.0/gems/activesupport-6.0.0/lib/active_support/dependencies.rb:291:in `load_dependency'
2: from /home/ubuntu/app/shared/bundle/ruby/2.6.0/gems/activesupport-6.0.0/lib/active_support/dependencies.rb:325:in `block in require'
1: from /home/ubuntu/app/shared/bundle/ruby/2.6.0/gems/skylight-core-4.1.2/lib/skylight/core/probes.rb:118:in `require'
/home/ubuntu/app/shared/bundle/ruby/2.6.0/gems/bootsnap-1.4.5/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:33:in `require': No such file to load -- paperclip.rb (LoadError)

Any ideas on how to debug this?

I tried setting paperclip to false in the config, but that didn't seem to help. I use ActiveStorage.

Checkboxes with blocking validation not working as expected

I swear I had this working. It could very well be something on my end. It seems that even though I am passing in the following to the Devise registration controller:
"policy_rule_privacy"=>"0", "policy_rule_terms_of_service"=>"0"

The registration goes through with these policy configurations:

  c.add_rule(
    name: 'privacy',
    validates_on: [:create, :update],
    blocking: true,
    if: ->(o){ !o.prevalidation && !ENV['SKIP_POLICY'] }
  )
  c.add_rule(
    name: 'terms_of_service',
    validates_on: [:create, :update],
    blocking: true,
    if: ->(o){ !o.prevalidation && !ENV['SKIP_POLICY'] }
  )

It works as intended if I check the checkboxes, but if I leave them unchecked the validation still passes.

    <label>
      <%= f.check_box :policy_rule_privacy %>
      You have read and agree to the terms outlined in our <a href="#">Privacy Policy</a>
    </label>
    <label>
      <%= f.check_box :policy_rule_terms_of_service %>
      You have read and agree to the terms outlined in our <a href="#">Terms of Service</a>
    </label>

Any ideas what may be causing this?

Rails 6 + Require Paperclip Error?

Came across an error where the gem attempts to require paperclip in a rails 6 environment despite it being set to false.

Question - should require paperclip in gdpr_rails-f8f4e72e3042/app/models/policy_manager/concerns/paperclip_behavior.rb be handled differently for rails 6? Should zeitworks be added as a dep to the package per this post? https://medium.com/cedarcode/understanding-zeitwerk-in-rails-6-f168a9f09a1f

#config/initializers/gdpr_policy_manager.rb
PolicyManager::Config.setup do |config|
  # config.paperclip = false
  # ...

Offending Code Blocks

# ...gems/ruby-2.6.4/bundler/gems/gdpr_rails-f8f4e72e3042/app/models/policy_manager/portability_request.rb
require "aasm"

module PolicyManager
  class PortabilityRequest < ApplicationRecord

    belongs_to :user, class_name: Config.user_resource.to_s, foreign_key:  :user_id

    if PolicyManager::Config.paperclip
      include PolicyManager::Concerns::PaperclipBehavior 
    else
      include PolicyManager::Concerns::ActiveStorageBehavior
    end
# ...
# ... gems/ruby-2.6.4/bundler/gems/gdpr_rails-f8f4e72e3042/app/models/policy_manager/concerns/paperclip_behavior.rb

# -*- encoding : utf-8 -*-
require "paperclip"

module PolicyManager::Concerns::PaperclipBehavior
  extend ActiveSupport::Concern
  include Paperclip::Glue

  included do
# ...

Log Line of Significance

from /usr/local/bundle/ruby/2.6.0/bundler/gems/gdpr_rails-f8f4e72e3042/app/models/policy_manager/concerns/paperclip_behavior.rb:2:in `<main>'

Full Logs

, [2020-01-28T21:16:14.127792 #1]  INFO -- sentry: ** [Raven] Raven 2.13.0 ready to catch errors
=> Booting Puma
=> Rails 6.0.2.1 application starting in production 
=> Run `rails server --help` for more startup options
I, [2020-01-28T21:16:15.650386 #1]  INFO -- : Raven 2.13.0 ready to catch errors
Exiting
/usr/local/bundle/ruby/2.6.0/gems/bootsnap-1.4.5/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:33:in `require': cannot load such file -- paperclip (LoadError)
	from /usr/local/bundle/ruby/2.6.0/gems/zeitwerk-2.2.2/lib/zeitwerk/kernel.rb:23:in `require'
	from /usr/local/bundle/ruby/2.6.0/bundler/gems/gdpr_rails-f8f4e72e3042/app/models/policy_manager/concerns/paperclip_behavior.rb:2:in `<main>'
	from /usr/local/bundle/ruby/2.6.0/gems/bootsnap-1.4.5/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:22:in `require'
	from /usr/local/bundle/ruby/2.6.0/gems/bootsnap-1.4.5/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:22:in `block in require_with_bootsnap_lfi'
	from /usr/local/bundle/ruby/2.6.0/gems/bootsnap-1.4.5/lib/bootsnap/load_path_cache/loaded_features_index.rb:92:in `register'
	from /usr/local/bundle/ruby/2.6.0/gems/bootsnap-1.4.5/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:21:in `require_with_bootsnap_lfi'
	from /usr/local/bundle/ruby/2.6.0/gems/bootsnap-1.4.5/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:30:in `require'
	from /usr/local/bundle/ruby/2.6.0/gems/zeitwerk-2.2.2/lib/zeitwerk/kernel.rb:16:in `require'
	from /usr/local/bundle/ruby/2.6.0/gems/zeitwerk-2.2.2/lib/zeitwerk/loader.rb:351:in `const_get'
	from /usr/local/bundle/ruby/2.6.0/gems/zeitwerk-2.2.2/lib/zeitwerk/loader.rb:351:in `block (2 levels) in eager_load'
	from /usr/local/bundle/ruby/2.6.0/gems/zeitwerk-2.2.2/lib/zeitwerk/loader.rb:685:in `block in ls'
	from /usr/local/bundle/ruby/2.6.0/gems/zeitwerk-2.2.2/lib/zeitwerk/loader.rb:682:in `foreach'
	from /usr/local/bundle/ruby/2.6.0/gems/zeitwerk-2.2.2/lib/zeitwerk/loader.rb:682:in `ls'
	from /usr/local/bundle/ruby/2.6.0/gems/zeitwerk-2.2.2/lib/zeitwerk/loader.rb:346:in `block in eager_load'
	from /usr/local/bundle/ruby/2.6.0/gems/zeitwerk-2.2.2/lib/zeitwerk/loader.rb:338:in `synchronize'
	from /usr/local/bundle/ruby/2.6.0/gems/zeitwerk-2.2.2/lib/zeitwerk/loader.rb:338:in `eager_load'
	from /usr/local/bundle/ruby/2.6.0/gems/zeitwerk-2.2.2/lib/zeitwerk/loader.rb:449:in `each'
	from /usr/local/bundle/ruby/2.6.0/gems/zeitwerk-2.2.2/lib/zeitwerk/loader.rb:449:in `eager_load_all'
	from /usr/local/bundle/ruby/2.6.0/gems/railties-6.0.2.1/lib/rails/application/finisher.rb:122:in `block in <module:Finisher>'
	from /usr/local/bundle/ruby/2.6.0/gems/railties-6.0.2.1/lib/rails/initializable.rb:32:in `instance_exec'
	from /usr/local/bundle/ruby/2.6.0/gems/railties-6.0.2.1/lib/rails/initializable.rb:32:in `run'
	from /usr/local/bundle/ruby/2.6.0/gems/railties-6.0.2.1/lib/rails/initializable.rb:61:in `block in run_initializers'
	from /usr/local/lib/ruby/2.6.0/tsort.rb:228:in `block in tsort_each'
	from /usr/local/lib/ruby/2.6.0/tsort.rb:350:in `block (2 levels) in each_strongly_connected_component'
	from /usr/local/lib/ruby/2.6.0/tsort.rb:431:in `each_strongly_connected_component_from'
	from /usr/local/lib/ruby/2.6.0/tsort.rb:349:in `block in each_strongly_connected_component'
	from /usr/local/lib/ruby/2.6.0/tsort.rb:347:in `each'
	from /usr/local/lib/ruby/2.6.0/tsort.rb:347:in `call'
	from /usr/local/lib/ruby/2.6.0/tsort.rb:347:in `each_strongly_connected_component'
	from /usr/local/lib/ruby/2.6.0/tsort.rb:226:in `tsort_each'
	from /usr/local/lib/ruby/2.6.0/tsort.rb:205:in `tsort_each'
	from /usr/local/bundle/ruby/2.6.0/gems/railties-6.0.2.1/lib/rails/initializable.rb:60:in `run_initializers'
	from /usr/local/bundle/ruby/2.6.0/gems/railties-6.0.2.1/lib/rails/application.rb:363:in `initialize!'
	from /app/config/environment.rb:5:in `<main>'
	from /usr/local/bundle/ruby/2.6.0/gems/bootsnap-1.4.5/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:22:in `require'
	from /usr/local/bundle/ruby/2.6.0/gems/bootsnap-1.4.5/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:22:in `block in require_with_bootsnap_lfi'
	from /usr/local/bundle/ruby/2.6.0/gems/bootsnap-1.4.5/lib/bootsnap/load_path_cache/loaded_features_index.rb:92:in `register'
	from /usr/local/bundle/ruby/2.6.0/gems/bootsnap-1.4.5/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:21:in `require_with_bootsnap_lfi'
	from /usr/local/bundle/ruby/2.6.0/gems/bootsnap-1.4.5/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:30:in `require'
	from /usr/local/bundle/ruby/2.6.0/gems/zeitwerk-2.2.2/lib/zeitwerk/kernel.rb:23:in `require'
	from /usr/local/bundle/ruby/2.6.0/gems/activesupport-6.0.2.1/lib/active_support/dependencies.rb:325:in `block in require'
	from /usr/local/bundle/ruby/2.6.0/gems/activesupport-6.0.2.1/lib/active_support/dependencies.rb:291:in `load_dependency'
	from /usr/local/bundle/ruby/2.6.0/gems/activesupport-6.0.2.1/lib/active_support/dependencies.rb:325:in `require'
	from /usr/local/bundle/ruby/2.6.0/gems/bootsnap-1.4.5/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:48:in `require_relative'
	from config.ru:3:in `block in <main>'
	from /usr/local/bundle/ruby/2.6.0/gems/rack-2.1.1/lib/rack/builder.rb:71:in `instance_eval'
	from /usr/local/bundle/ruby/2.6.0/gems/rack-2.1.1/lib/rack/builder.rb:71:in `initialize'
	from config.ru:in `new'
	from config.ru:in `<main>'
	from /usr/local/bundle/ruby/2.6.0/gems/rack-2.1.1/lib/rack/builder.rb:65:in `eval'
	from /usr/local/bundle/ruby/2.6.0/gems/rack-2.1.1/lib/rack/builder.rb:65:in `new_from_string'
	from /usr/local/bundle/ruby/2.6.0/gems/rack-2.1.1/lib/rack/builder.rb:59:in `load_file'
	from /usr/local/bundle/ruby/2.6.0/gems/rack-2.1.1/lib/rack/builder.rb:40:in `parse_file'
	from /usr/local/bundle/ruby/2.6.0/gems/rack-2.1.1/lib/rack/server.rb:351:in `build_app_and_options_from_config'
	from /usr/local/bundle/ruby/2.6.0/gems/rack-2.1.1/lib/rack/server.rb:251:in `app'
	from /usr/local/bundle/ruby/2.6.0/gems/rack-2.1.1/lib/rack/server.rb:424:in `wrapped_app'
	from /usr/local/bundle/ruby/2.6.0/gems/rack-2.1.1/lib/rack/server.rb:314:in `block in start'
	from /usr/local/bundle/ruby/2.6.0/gems/rack-2.1.1/lib/rack/server.rb:381:in `handle_profiling'
	from /usr/local/bundle/ruby/2.6.0/gems/rack-2.1.1/lib/rack/server.rb:313:in `start'
	from /usr/local/bundle/ruby/2.6.0/gems/railties-6.0.2.1/lib/rails/commands/server/server_command.rb:39:in `start'
	from /usr/local/bundle/ruby/2.6.0/gems/railties-6.0.2.1/lib/rails/commands/server/server_command.rb:147:in `block in perform'
	from /usr/local/bundle/ruby/2.6.0/gems/railties-6.0.2.1/lib/rails/commands/server/server_command.rb:138:in `tap'
	from /usr/local/bundle/ruby/2.6.0/gems/railties-6.0.2.1/lib/rails/commands/server/server_command.rb:138:in `perform'
	from /usr/local/bundle/ruby/2.6.0/gems/thor-1.0.1/lib/thor/command.rb:27:in `run'
	from /usr/local/bundle/ruby/2.6.0/gems/thor-1.0.1/lib/thor/invocation.rb:127:in `invoke_command'
	from /usr/local/bundle/ruby/2.6.0/gems/thor-1.0.1/lib/thor.rb:392:in `dispatch'
	from /usr/local/bundle/ruby/2.6.0/gems/railties-6.0.2.1/lib/rails/command/base.rb:69:in `perform'
	from /usr/local/bundle/ruby/2.6.0/gems/railties-6.0.2.1/lib/rails/command.rb:46:in `invoke'
	from /usr/local/bundle/ruby/2.6.0/gems/railties-6.0.2.1/lib/rails/commands.rb:18:in `<main>'
	from /usr/local/bundle/ruby/2.6.0/gems/bootsnap-1.4.5/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:22:in `require'
	from /usr/local/bundle/ruby/2.6.0/gems/bootsnap-1.4.5/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:22:in `block in require_with_bootsnap_lfi'
	from /usr/local/bundle/ruby/2.6.0/gems/bootsnap-1.4.5/lib/bootsnap/load_path_cache/loaded_features_index.rb:92:in `register'
	from /usr/local/bundle/ruby/2.6.0/gems/bootsnap-1.4.5/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:21:in `require_with_bootsnap_lfi'
	from /usr/local/bundle/ruby/2.6.0/gems/bootsnap-1.4.5/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:30:in `require'
	from /usr/local/bundle/ruby/2.6.0/gems/activesupport-6.0.2.1/lib/active_support/dependencies.rb:325:in `block in require'
	from /usr/local/bundle/ruby/2.6.0/gems/activesupport-6.0.2.1/lib/active_support/dependencies.rb:291:in `load_dependency'
	from /usr/local/bundle/ruby/2.6.0/gems/activesupport-6.0.2.1/lib/active_support/dependencies.rb:325:in `require'
	from bin/rails:4:in `<main>'

Undefined method 'per' error when used with ActiveAdmin

If you try and use GDPR_Rails with ActiveAdmin... the minute you select any model it will throw up an "Undefined method 'per'" error.

In addition to this... the "has_one_attached" error for the User models containing an "avatar" using Active Storage is still very much present.

Uninstalling GDPR_Rails and removing all references resolved the "Undefined method per" error. It is suspected that GDPR_Rails uses either Kaminari or WillPaginate.

Dependency tree not resolved with Rails 6.1.4

When looking at the branches, it seems that some effort were made to bring it to rails 6.

While trying to installing along rails 6.1.4 I get the following error:

Bundler could not find compatible versions for gem "rails":
  In snapshot (Gemfile.lock):
    rails (= 6.1.4)

  In Gemfile:
    rails (~> 6.1.4) x86_64-linux

    gdpr_rails x86_64-linux was resolved to 0.2.1, which depends on
      rails (~> 5.1.4)

Running `bundle update` will rebuild your snapshot from scratch, using only
the gems in your Gemfile, which may resolve the conflict.

However it seems that the last gem available in the directory is 0.5.1.
Trying to load 0.5.2 from this repo won't help much:

Bundler could not find compatible versions for gem "rubyzip":
  In snapshot (Gemfile.lock):
    rubyzip (= 2.3.2)

  In Gemfile:
    gdpr_rails (~> 0.5.2) x86_64-linux was resolved to 0.5.2, which depends on
      rubyzip (>= 1.0.0, < 2)

    selenium-webdriver x86_64-linux was resolved to 3.142.7, which depends on
      rubyzip (>= 1.2.2) x86_64-linux

    webdrivers x86_64-linux was resolved to 4.6.0, which depends on
      rubyzip (>= 1.3.0) x86_64-linux

Running `bundle update` will rebuild your snapshot from scratch, using only
the gems in your Gemfile, which may resolve the conflict.

Do you have any plan to bring it to rails 6.1?
Thanks for your shared work.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.