-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Hadrien Froger
committed
Sep 21, 2024
1 parent
d97c7be
commit 55e51d5
Showing
3 changed files
with
33 additions
and
250 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,277 +1,60 @@ | ||
<h1 align="center"> | ||
<img | ||
src="https://github.com/octree-gva/meta/blob/main/decidim/static/header.png?raw=true" | ||
alt="Decidim - Octree Participatory democracy on a robust and open source solution" /> | ||
</h1> | ||
<h1 align="center"><img src="https://github.com/octree-gva/meta/blob/main/decidim/static/header.png?raw=true" alt="Decidim - Octree Participatory democracy on a robust and open source solution" /></h1> | ||
<h4 align="center"> | ||
<a href="https://git.octree.ch/decidim/vocacity/decidim-modules/decidim-module-spam_signal/issues">Issues</a> | | ||
<a href="https://decidim-ice.github.io/decidim-anti-spam/">Documentation</a> <br/><br /> | ||
<a href="https://crowdin.com/project/decidim-spam-module"><img src="https://badges.crowdin.net/decidim-spam-module/localized.svg" /></a><br /><br /> | ||
<a href="https://www.octree.ch">Octree</a> | | ||
<a href="https://octree.ch/en/contact-us/">Contact Us</a> | | ||
<a href="https://blog.octree.ch">Our Blog (FR)</a><br/><br/> | ||
<a href="https://octree.ch/en/contact-us/">Contact Us</a><br/><br/> | ||
<a href="https://decidim.org">Decidim</a> | | ||
<a href="https://docs.decidim.org/en/">Decidim Docs</a> | | ||
<a href="https://meta.decidim.org">Participatory Governance (META DECIDIM)</a><br/><br/> | ||
<a href="https://matrix.to/#/+decidim:matrix.org">Decidim Community (Matrix+Element.io)</a> | ||
</h4> | ||
<p align="center"> | ||
<a href="https://participer.lausanne.ch"> | ||
<img | ||
src="https://github.com/octree-gva/meta/blob/main/decidim/static/participer_lausanne/chip.png?raw=true" | ||
alt="Lausanne Participe — Une plateforme de participation pour imaginer et réaliser ensemble" /> | ||
</a> | ||
<a href="https://participer.ge.ch"> | ||
<img | ||
src="https://github.com/octree-gva/meta/blob/main/decidim/static/participerge/chip.png?raw=true" | ||
alt="Participer Genève — The public platform for citizen participation in Geneva and it's region" /> | ||
</a> | ||
<a href="https://opencollective.com/voca"> | ||
<img | ||
src="https://github.com/octree-gva/meta/blob/main/decidim/static/opencollective_chip.png?raw=true" | ||
alt="Voca – Open-Source SaaS platform for Decidim" /> | ||
</a> | ||
</p> | ||
<br /><br /> | ||
|
||
# Anti-Spam for decidim | ||
|
||
Flexible detection and reaction on spam for Decidim, sponsored by: | ||
|
||
* [Participer Lausanne](https://participer.lausanne.ch) | ||
* [Genève Participe](https://participer.ge.ch) | ||
|
||
## Available Detection | ||
This anti-spam gem comes with three core detection for spam: | ||
|
||
* Allowed TLDs: A list of all extensions (like `.com`) that are allowed. If an extension not present in the list is detected, a `Not Allowed Tlds Found` is raised | ||
* Forbidden TLDs: A list of all extensions (like `.finance`) that are forbidden. If an extension not present in the list is detected, a `Forbidden Tlds Found` is raised | ||
* Words: A dictionnary of forbidden word. If a forbidden word is found, a `Word Found` is raised. | ||
|
||
## Rules | ||
A rule is a link between the detection and what you do with the user (the agent). | ||
We work on two sets of rules: SPAM and SUSPICIOUS. You can this way define two kinds of actions and have a more fine-grained spam policy. For example, you could: | ||
|
||
* When a `.xxx` domain is found, Lock the user | ||
* When a domain that is not `.com, .ch, .eu, .io`, Signalize the user to the admins. | ||
|
||
## Agent | ||
An agent is activated by a rule with a detected content. We have for now two agent: | ||
|
||
1. Lock: Use the `Devise::Lockable` strategy to lock the user, and send unlock instructions by email | ||
2. Sinalize: Do nothing, but sinalize the user to the admins | ||
|
||
## Installation | ||
|
||
Add this line to your application's Gemfile: | ||
|
||
```ruby | ||
gem 'decidim-spam_signal', '~> 0.3.1' | ||
``` | ||
or | ||
|
||
```ruby | ||
gem install decidim-spam_signal | ||
``` | ||
|
||
Then execute: | ||
|
||
```bash | ||
bundle | ||
bundle exec rails decidim_spam_signal:install:migrations | ||
bundle exec rails db:migrate | ||
``` | ||
|
||
## Local development | ||
For decidim version 0.27, use Gemfile.0.27. For version 0.26, use Gemfile.0.26 | ||
``` | ||
cp Gemfile.0.27 Gemfile | ||
``` | ||
|
||
First, you need to run an empty database with a decidim dev container which runs nothing. | ||
``` | ||
docker-compose down -v --remove-orphans | ||
docker-compose up -d | ||
``` | ||
|
||
Once created, you access the decidim container | ||
``` | ||
# Get the id of the decidim dev container | ||
docker ps --format {{.ID}} --filter=label=org.label-schema.name=decidim | ||
# 841ae977c7da | ||
docker exec -it 841ae977c7da bash | ||
``` | ||
You are now in bash, run manually. This will check your environment and do migrations if needed | ||
``` | ||
bundle exec rake decidim_spam_signal_admin:install:migrations | ||
docker-entrypoint | ||
``` | ||
|
||
You are now ready to use your container in the way you want for development: | ||
<a href="https://meta.decidim.org">Participatory Governance (meta decidim)</a><br/><br/> | ||
<a href="https://matrix.to/#/+decidim:matrix.org">Decidim Community (Matrix+Element.io)</a><br /><br /> | ||
</h4><br /> | ||
|
||
* Run a rails seed: `bundle exec rails db:seed` | ||
* Have live-reload on your assets: `bin/webpack-dev-server` | ||
* Execute tasks, like `bundle exec rails g migration AddSomeColumn` | ||
* Run the rails server: `bundle exec rails s -b 0.0.0.0` | ||
* etc. | ||
|
||
To stop everything, uses: | ||
- `docker-compose down` to stop the containers | ||
- `docker-compose down -v` to stop the containers and remove all previously saved data. | ||
|
||
### Debugging | ||
To debug something on the container: | ||
1. Ensure `decidim-app` is running | ||
```bash | ||
docker ps --all | ||
# CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES | ||
# 841ae977c7da decidim-module-spam_signal-decidim-app "sleep infinity" 32 minutes ago Up 29 minutes 0.0.0.0:3000->3000/tcp, :::3000->3000/tcp, 0.0.0.0:3035->3035/tcp, :::3035->3035/tcp decidim-spam_signal-app <-------- THIS ONE | ||
# b56adf6404d8 decidim-geo-development-app "bin/webpack-dev-ser…" 54 seconds ago Up 46 seconds 0.0.0.0:3035->3035/tcp decidim-webpacker decidim-installer | ||
# bc1e912c3d8a postgis/postgis:14-3.3-alpine "docker-entrypoint.s…" 13 hours ago Up 13 hours 0.0.0.0:5432->5432/tcp decidim-spam-signal-pg-1 | ||
``` | ||
# Anti-spam For Decidim | ||
This module integrates a newadministration tab to manage and configure a Decidim anti-spam. | ||
|
||
2. In another terminal, run `docker exec -it 841ae977c7da bash` | ||
3. Run | ||
- `tail -f $ROOT/log/development.log` to **access logs** | ||
- `bundle exec rails restart` to **restart rails server AND keeps webpacker running** | ||
- `cd $ROOT` to access the `development_app` | ||
- `cd $ROOT/../decidim_module_geo` to access the module directory | ||
**Avoid Sapmmy Comment Creation**<br /> | ||
This module will avoid spam or comercial content before a comment is even saved. | ||
|
||
## Environment Variable | ||
**Mass-reporting**<br /> | ||
This module can report automatically user, and send report to a single email (and not all the admins) | ||
|
||
```bash | ||
export USER_BOT_EMAIL='[email protected]' # user-bot used for signaling the spammers | ||
``` | ||
**Detect bad User's profile**<br /> | ||
With this module, you will be able to detect url of strange domains, and commercial content in the profile description (about section). This allow to stop spammer earlier. | ||
|
||
## Scripting | ||
We don't have UI for this (and probably won't), so here some useful script: | ||
To know more about features and configurations, visit [decidim-anti-spam documentation website](https://decidim-ice.github.io/decidim-anti-spam/) | ||
|
||
Who is locked for more than a month and didn't unlock their account (CSV)? | ||
```ruby | ||
require "csv" | ||
headers=["id", "nickname", "email", "vérouillé le"] | ||
CSV.open("locked-users.csv", "w") do |csv| | ||
csv << headers | ||
Decidim::User.where("locked_at < ?", 31.days.ago).pluck(:id, :nickname, :email, :locked_at).each {|usr| csv << usr } | ||
end | ||
``` | ||
--- | ||
|
||
The philosophy of this module is to adapt rules to each situation, and has been greatly influenced by [the Pol.is moderation good practices guide](https://compdemocracy.org/Moderation/). | ||
|
||
Apply your spam strategy to existing data? | ||
```ruby | ||
Decidim::User.all.each {|user| user.valid? } | ||
Decidim::Comments::Comment.all.each {|comment| comment.valid? } | ||
``` | ||
|
||
## Contributing | ||
You are welcome to fill issues in this repo, and help if you have time. | ||
|
||
## Documentation | ||
You can consult our documentation on the [decidim-anti-spam documentation website](https://decidim-ice.github.io/decidim-anti-spam/) | ||
|
||
# Add your own detection | ||
An agent have two classes: A command class, and a form class (for settings). | ||
## Contributions | ||
This module is maintained by [Octree](https://octree.ch), we plan work and release in our self-hosted gitlab. | ||
|
||
For `Command`, here some restrictions: | ||
|
||
* You need to define a form to a `Decidim::Form` class, with absolute `::<name>` namespace. You will have trouble with memory allocation if you don't | ||
* You need to suffix your command with `ScanCommand` name. That's a convention we use to avoid configurations. | ||
* call must broadcast :ok or one of the `output_symbols` defined | ||
|
||
```ruby | ||
class CustomScanCommand < Decidim::SpamSignal::Scans::ScanHandler | ||
def self.form | ||
::CustomSettingsForm | ||
end | ||
def self.output_symbols | ||
[:foo] | ||
end | ||
def call | ||
return broadcast(:foo) if config["foo_enabled"] | ||
broadcast(:ok) | ||
end | ||
end | ||
``` | ||
|
||
|
||
For Settings: | ||
|
||
* You need to include the module `Decidim::SpamSignal::SettingsForm` to make the whole thing work | ||
* We have special naming rules on how you name your attributes: | ||
* if its start with `is_` or end with `_enabled`, you will have a checkbox | ||
* if its ends with `_csv` you will have a textarea | ||
* the rest is like default decidim's form builder. | ||
|
||
```ruby | ||
class CustomSettingsForm < Decidim::Form | ||
include Decidim::SpamSignal::SettingsForm | ||
attribute :foo_enabled, Boolean, default: false | ||
# You can add validation here ;) | ||
end | ||
``` | ||
|
||
And now, you can register your command in an initializer: | ||
```ruby | ||
Decidim::SpamSignal::Scans::ScansRepository.instance.register(:custom, ::CustomScanCommand) | ||
``` | ||
|
||
And set the i18n fields: | ||
* `decidim.spam_signal.scans.custom.name` | ||
* `decidim.spam_signal.scans.custom.description` | ||
* `decidim.spam_signal.forms.custom.custom_settings_form.foo_enabled` | ||
|
||
|
||
# Add your own agent | ||
We won't advise you create your own agent, as it seems the Lock agent as the strongest agent is already a good compromise for spam control. If you really want it, that's simple, it's almost like detection: | ||
|
||
* Use `CopCommand` to suffix your command | ||
* Add a `self.form` to your settings (it can returns `nil`) | ||
* Use these different attributes: | ||
* `suspicious_user` the user that have done something wrong | ||
* `admin_reporter` an admin user only used to report spam | ||
* `errors` an ActiveRecord error, to forbid saving (@see [Working With Validation Errors in Rails Guides](https://guides.rubyonrails.org/active_record_validations.html#working-with-validation-errors)) | ||
|
||
```ruby | ||
class CustomCopCommand < Decidim::SpamSignal::Cops::CopHandler | ||
def self.form | ||
::CustomSettingsForm | ||
end | ||
|
||
def call | ||
suspicious_user.lock_access! # or do whatever with the admin | ||
end | ||
end | ||
``` | ||
|
||
Settings are exactly the same logic, and i18n fields: | ||
* `decidim.spam_signal.cops.custom.name` | ||
* `decidim.spam_signal.cops.custom.description` | ||
* `decidim.spam_signal.forms.custom.custom_settings_form.foo_enabled` | ||
|
||
To register it in an initializer: | ||
```ruby | ||
Decidim::SpamSignal::Cops::CopsRepository.instance.register(:custom, ::CustomCopCommand) | ||
``` | ||
|
||
|
||
**N.B** You will find in the code the term `cop` to refer an agent. | ||
This is provocative on purpose: participation must be as inclusive as possible, restricting participation is _BAD_. You are warned, be your own cop. | ||
**New ideas**<br /> | ||
New ideas are welcome on our [feedback page](https://feedback.voca.city/?tags=decidim-anti-spam). We manage there co-financing and release planning. | ||
For technical aspects (contributions, code, issues), take a look at our [gitlab](https://git.octree.ch/decidim/vocacity/decidim-modules/decidim-module-spam_signal). | ||
|
||
|
||
## License | ||
|
||
This engine is distributed under the [GNU AFFERO GENERAL PUBLIC LICENSE](LICENSE.md). | ||
This engine is distributed under the [GNU AFFERO GENERAL PUBLIC LICENSE](LICENSE.md) | ||
|
||
<br /><br /> | ||
|
||
<p align="center"> | ||
<img | ||
src="https://github.com/octree-gva/meta/blob/main/decidim/static/spam-signal/spam-signal-1.png?raw=true" | ||
alt="Anti Spam for Decidim, screenshot" /> | ||
</p> | ||
<p align="center"> | ||
<img | ||
src="https://github.com/octree-gva/meta/blob/main/decidim/static/spam-signal/spam-signal-2.png?raw=true" | ||
alt="Anti Spam for Decidim, screenshot" /> | ||
</p> | ||
|
||
<br /><br /> | ||
|
||
<h3 align="center">With the support of</h3> | ||
<p align="center"> | ||
<img src="https://raw.githubusercontent.com/octree-gva/meta/main/decidim/static/octree_and_decidim.png" height="90" alt="Decidim Installation by Octree" /> | ||
<img | ||
src="https://git.octree.ch/decidim/vocacity/decidim-modules/decidim-module-spam_signal/-/raw/main/partners.png?raw=true" | ||
alt="Lausanne Participe — Une plateforme de participation pour imaginer et réaliser ensemble" /> | ||
</p> | ||
|
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters