fedipub-moderation 0.5.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 +7 -0
- data/README.md +98 -0
- data/Rakefile +8 -0
- data/app/models/fedipub/moderation/domain_block.rb +12 -0
- data/app/models/fedipub/moderation/report.rb +32 -0
- data/app/services/fedipub/moderation/application_service.rb +7 -0
- data/app/services/fedipub/moderation/report_creation_service.rb +40 -0
- data/app/validators/fedipub/moderation/domain_name_validator.rb +9 -0
- data/config/initializers/extensions.rb +9 -0
- data/config/initializers/handlers.rb +5 -0
- data/config/routes.rb +2 -0
- data/db/migrate/20241127105043_create_federails_moderation_reports.rb +13 -0
- data/db/migrate/20241128115659_create_federails_moderation_domain_blocks.rb +8 -0
- data/db/migrate/20260729204941_rename_federails_moderation_to_fedipub_moderation.rb +8 -0
- data/lib/fedipub/moderation/configuration.rb +11 -0
- data/lib/fedipub/moderation/engine.rb +9 -0
- data/lib/fedipub/moderation/filtered_inbox.rb +18 -0
- data/lib/fedipub/moderation/filtered_notifier.rb +16 -0
- data/lib/fedipub/moderation/railtie.rb +6 -0
- data/lib/fedipub/moderation/version.rb +5 -0
- data/lib/fedipub/moderation.rb +18 -0
- data/lib/tasks/fedipub/moderation_tasks.rake +4 -0
- metadata +130 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 1ce4eb580ac4093a39a006480b07f863e6b2f4ae8bb1d077a42ecc10799c7f55
|
|
4
|
+
data.tar.gz: d94937b13d7a3a1f730ed89a790b2647a03b4dcc8e7aed060d4231b0fd529361
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 3cd1c951cf24d4c47c914440f014703f416058fc8cce885b284256b9f0e05b04891758a61779eb6cd55a2d75ce5c405e1cfadd3c07d0b36fd7220fdce2c11ff5
|
|
7
|
+
data.tar.gz: 6dc30a28a28d2b27e6ab15de37e52204cb2b2e9f7e220ea7dde7b87965db16cb7d2e17260ab1ad4fde375892a1a167fca57c7d4a5dbfa0058361d9beb84dbd88
|
data/README.md
ADDED
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
# Fedipub::Moderation
|
|
2
|
+
|
|
3
|
+

|
|
4
|
+

|
|
5
|
+
|
|
6
|
+

|
|
7
|
+

|
|
8
|
+

|
|
9
|
+
|
|
10
|
+
A gem that provides moderation capabilities for [Fedipub](https://gitlab.com/fedipub/fedipub). It adds the following features:
|
|
11
|
+
|
|
12
|
+
* Handle incoming `Flag` activities, normally used for reporting content to moderators
|
|
13
|
+
* Block federation with particular servers
|
|
14
|
+
|
|
15
|
+
[!note]
|
|
16
|
+
This gem was previously called `federails-moderation`, but has changed name in line with the rename of Federails to Fedipub.
|
|
17
|
+
|
|
18
|
+
## Requirements
|
|
19
|
+
|
|
20
|
+
* [Fedipub](https://gitlab.com/fedipub/fedipub) >= 0.8
|
|
21
|
+
* Ruby >= 3.0
|
|
22
|
+
|
|
23
|
+
## Installation
|
|
24
|
+
Add the gem to your Rails application:
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
> bundle add "fedipub-moderation"
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Then install the database migrations:
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
> bin/rails fedipub_moderation:install:migrations
|
|
34
|
+
> bin/rails db:migrate
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Usage
|
|
38
|
+
|
|
39
|
+
### Reports
|
|
40
|
+
|
|
41
|
+
When your application receives a `Flag` activitypub message, it will create a `Fedipub::Moderation::Report` record with the details.
|
|
42
|
+
|
|
43
|
+
```ruby
|
|
44
|
+
# Find all unresolved reports
|
|
45
|
+
reports = Fedipub::Moderation::Report.where(resolution: nil)
|
|
46
|
+
r = reports.first
|
|
47
|
+
|
|
48
|
+
# Reports can have a comment that was sent with them:
|
|
49
|
+
puts r.content
|
|
50
|
+
# "This message is spam"
|
|
51
|
+
|
|
52
|
+
# It will be associated with the actor that sent it:
|
|
53
|
+
puts r.actor.at_address
|
|
54
|
+
# "@floppy@mastodon.me.uk"
|
|
55
|
+
|
|
56
|
+
# Deal with the report in your app, then either:
|
|
57
|
+
r.resolve!
|
|
58
|
+
# or, you can ignore it
|
|
59
|
+
r.ignore!
|
|
60
|
+
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
You can receive a callback in your application when a new report is received, by providing a proc which will be called:
|
|
64
|
+
|
|
65
|
+
```
|
|
66
|
+
Fedipub::Moderation.configure do |conf|
|
|
67
|
+
conf.after_report_created = ->(report) { MyApp::MyReportHandler.call(report) }
|
|
68
|
+
end
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### Domain Blocks
|
|
72
|
+
|
|
73
|
+
You can block domains that are abusive like so:
|
|
74
|
+
|
|
75
|
+
```
|
|
76
|
+
Fedipub::Moderation::DomainBlock.create(domain: "spammer.com")
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
Once the block is created, incoming messages from that domain, or from any actor on that domain, will be ignored. Also, outgoing messages to that domain will be dropped before being delivered.
|
|
80
|
+
|
|
81
|
+
Actors from the blocked domain aren't currently auto-removed; this may be added in the future, but for now that's left up to your application.
|
|
82
|
+
|
|
83
|
+
## Contributing
|
|
84
|
+
|
|
85
|
+
Bug reports and pull requests are welcome on GitLab at https://gitlab.com/fedipub/fedipub-moderation. This project is intended to be a safe, welcoming space for collaboration; everyone interacting in the project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://gitlab.com/fedipub/fedipub-moderation/-/blob/main/CODE_OF_CONDUCT.md).
|
|
86
|
+
|
|
87
|
+
## Support & Community
|
|
88
|
+
|
|
89
|
+
For help, join the main [Fedipub matrix chat room](https://matrix.to/#/#fedipub:matrix.org).
|
|
90
|
+
|
|
91
|
+
## Acknowledgements
|
|
92
|
+
|
|
93
|
+
This gem builds on top of [Fedipub](https://gitlab.com/fedipub/fedipub), by [Manuel Tancoigne](https://gitlab.com/mtancoigne).
|
|
94
|
+
|
|
95
|
+
This gem was initially created as part of [Manyfold](https://manyfold.app), with funding from [NGI0 Entrust](https://nlnet.nl/entrust), a fund established by [NLnet](https://nlnet.nl) with financial support from the European Commission's [Next Generation Internet](https://ngi.eu) program.
|
|
96
|
+
|
|
97
|
+
[<img src="https://nlnet.nl/logo/banner.png" alt="NLnet foundation logo" width="20%" />](https://nlnet.nl)
|
|
98
|
+
[<img src="https://nlnet.nl/image/logos/NGI0_tag.svg" alt="NGI Zero Logo" width="20%" />](https://nlnet.nl/entrust)
|
data/Rakefile
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
module Fedipub::Moderation
|
|
2
|
+
class DomainBlock < ApplicationRecord
|
|
3
|
+
validates :domain, presence: true, uniqueness: true, "fedipub/moderation/domain_name": true
|
|
4
|
+
|
|
5
|
+
def self.blocked?(query)
|
|
6
|
+
self.exists?(domain: [ query, PublicSuffix.parse(query).domain ])
|
|
7
|
+
rescue PublicSuffix::Error
|
|
8
|
+
# Allow things that we don't understand
|
|
9
|
+
false
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
class Fedipub::Moderation::Report < ApplicationRecord
|
|
2
|
+
belongs_to :fedipub_actor, class_name: "Fedipub::Actor", optional: true
|
|
3
|
+
belongs_to :object, polymorphic: true, optional: true
|
|
4
|
+
|
|
5
|
+
after_create :execute_create_callback
|
|
6
|
+
|
|
7
|
+
def resolve!
|
|
8
|
+
update!(resolved_at: DateTime.now, resolution: "resolved")
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def ignore!
|
|
12
|
+
update!(resolved_at: DateTime.now, resolution: "ignored")
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def reporter_address
|
|
16
|
+
if fedipub_actor
|
|
17
|
+
fedipub_actor.at_address
|
|
18
|
+
else
|
|
19
|
+
URI.parse(federated_url).host
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def local?
|
|
24
|
+
fedipub_actor&.local?
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
private
|
|
28
|
+
|
|
29
|
+
def execute_create_callback
|
|
30
|
+
Fedipub::Moderation::Configuration.after_report_created&.call self
|
|
31
|
+
end
|
|
32
|
+
end
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
module Fedipub::Moderation
|
|
2
|
+
class ReportCreationService < ApplicationService
|
|
3
|
+
def initialize(activity)
|
|
4
|
+
@activity = activity
|
|
5
|
+
Rails.logger.info "Report recieved: #{@activity.inspect}"
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def call
|
|
9
|
+
Report.create!(
|
|
10
|
+
fedipub_actor: find_reporter,
|
|
11
|
+
object: find_objects.first,
|
|
12
|
+
federated_url: @activity["id"],
|
|
13
|
+
content: @activity["content"]
|
|
14
|
+
)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
private
|
|
18
|
+
|
|
19
|
+
def find_reporter
|
|
20
|
+
Fedipub::Actor.find_or_create_by_federation_url(@activity["actor"])
|
|
21
|
+
rescue ActiveRecord::RecordInvalid, URI::InvalidURIError
|
|
22
|
+
# Anonymous reports will try to create invalid actors, so we end up here
|
|
23
|
+
nil
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def find_objects
|
|
27
|
+
objects = Array(@activity["object"]).map { |url|
|
|
28
|
+
begin
|
|
29
|
+
# Find reported actors
|
|
30
|
+
Fedipub::Actor.find_by_federation_url(url)
|
|
31
|
+
# Other objects could be here too, but they will come later
|
|
32
|
+
rescue ActiveRecord::RecordNotFound
|
|
33
|
+
nil
|
|
34
|
+
end
|
|
35
|
+
}.compact
|
|
36
|
+
Rails.logger.warn "Fedipub::Moderation cannot currently handle multiple objects in a single report, only the first has been logged" if objects.length > 1
|
|
37
|
+
objects
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
require "public_suffix"
|
|
2
|
+
|
|
3
|
+
module Fedipub::Moderation
|
|
4
|
+
class DomainNameValidator < ActiveModel::EachValidator
|
|
5
|
+
def validate_each(record, attribute, value)
|
|
6
|
+
record.errors.add attribute, :invalid unless PublicSuffix.valid?(value, default_rule: nil)
|
|
7
|
+
end
|
|
8
|
+
end
|
|
9
|
+
end
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
require "fediverse/inbox"
|
|
2
|
+
require "fedipub/moderation/filtered_inbox"
|
|
3
|
+
|
|
4
|
+
Fediverse::Inbox.send(:include, Fedipub::Moderation::FilteredInbox)
|
|
5
|
+
|
|
6
|
+
require "fediverse/notifier"
|
|
7
|
+
require "fedipub/moderation/filtered_notifier"
|
|
8
|
+
|
|
9
|
+
Fediverse::Notifier.send(:include, Fedipub::Moderation::FilteredNotifier)
|
data/config/routes.rb
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
class CreateFederailsModerationReports < ActiveRecord::Migration[7.0]
|
|
2
|
+
def change
|
|
3
|
+
create_table :federails_moderation_reports do |t|
|
|
4
|
+
t.string :federated_url
|
|
5
|
+
t.references :federails_actor, foreign_key: true
|
|
6
|
+
t.string :content
|
|
7
|
+
t.references :object, polymorphic: true
|
|
8
|
+
t.datetime :resolved_at
|
|
9
|
+
t.string :resolution
|
|
10
|
+
t.timestamps
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
class RenameFederailsModerationToFedipubModeration < ActiveRecord::Migration[7.2]
|
|
2
|
+
def change
|
|
3
|
+
rename_column :federails_moderation_reports, :federails_actor_id, :fedipub_actor_id
|
|
4
|
+
rename_index :federails_moderation_reports, "index_federails_moderation_reports_on_object", "index_fedipub_moderation_reports_on_object"
|
|
5
|
+
rename_table :federails_moderation_reports, :fedipub_moderation_reports
|
|
6
|
+
rename_table :federails_moderation_domain_blocks, :fedipub_moderation_domain_blocks
|
|
7
|
+
end
|
|
8
|
+
end
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
module Fedipub::Moderation
|
|
2
|
+
# rubocop:disable Style/ClassVars
|
|
3
|
+
|
|
4
|
+
# Stores the Fedipub::Moderation configuration in a _singleton_.
|
|
5
|
+
module Configuration
|
|
6
|
+
# A proc that is called any time new report is created
|
|
7
|
+
# Useful for sending notifications
|
|
8
|
+
mattr_accessor :after_report_created
|
|
9
|
+
end
|
|
10
|
+
# rubocop:enable Style/ClassVars
|
|
11
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
module Fedipub::Moderation
|
|
2
|
+
module FilteredInbox
|
|
3
|
+
extend ActiveSupport::Concern
|
|
4
|
+
|
|
5
|
+
included do
|
|
6
|
+
class <<self
|
|
7
|
+
def filter_request(payload)
|
|
8
|
+
filtered_dispatch_request(payload) unless
|
|
9
|
+
(payload["id"] && DomainBlock.blocked?(URI.parse(payload["id"]).host)) ||
|
|
10
|
+
(payload["actor"] && DomainBlock.blocked?(URI.parse(payload["actor"]).host))
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
alias_method :filtered_dispatch_request, :dispatch_request
|
|
14
|
+
alias_method :dispatch_request, :filter_request
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
module Fedipub::Moderation
|
|
2
|
+
module FilteredNotifier
|
|
3
|
+
extend ActiveSupport::Concern
|
|
4
|
+
|
|
5
|
+
included do
|
|
6
|
+
class <<self
|
|
7
|
+
def filter_post_to_inbox(inbox_url:, message:, from: nil)
|
|
8
|
+
filtered_post_to_inbox(inbox_url: inbox_url, message: message, from: from) unless DomainBlock.blocked?(URI.parse(inbox_url).hostname)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
alias_method :filtered_post_to_inbox, :post_to_inbox
|
|
12
|
+
alias_method :post_to_inbox, :filter_post_to_inbox
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
require "fedipub/moderation/version"
|
|
2
|
+
require "fedipub/moderation/engine"
|
|
3
|
+
require "fedipub/moderation/configuration"
|
|
4
|
+
|
|
5
|
+
module Fedipub
|
|
6
|
+
module Moderation
|
|
7
|
+
mattr_reader :configuration
|
|
8
|
+
@@configuration = Configuration
|
|
9
|
+
|
|
10
|
+
def self.configure
|
|
11
|
+
yield @@configuration
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def self.table_name_prefix
|
|
15
|
+
"fedipub_moderation_"
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: fedipub-moderation
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.5.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- James Smith
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2026-08-06 00:00:00.000000000 Z
|
|
12
|
+
dependencies:
|
|
13
|
+
- !ruby/object:Gem::Dependency
|
|
14
|
+
name: rails
|
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
|
16
|
+
requirements:
|
|
17
|
+
- - ">="
|
|
18
|
+
- !ruby/object:Gem::Version
|
|
19
|
+
version: 7.2.2
|
|
20
|
+
type: :runtime
|
|
21
|
+
prerelease: false
|
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
+
requirements:
|
|
24
|
+
- - ">="
|
|
25
|
+
- !ruby/object:Gem::Version
|
|
26
|
+
version: 7.2.2
|
|
27
|
+
- !ruby/object:Gem::Dependency
|
|
28
|
+
name: fedipub
|
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
|
30
|
+
requirements:
|
|
31
|
+
- - "~>"
|
|
32
|
+
- !ruby/object:Gem::Version
|
|
33
|
+
version: '0.9'
|
|
34
|
+
type: :runtime
|
|
35
|
+
prerelease: false
|
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
37
|
+
requirements:
|
|
38
|
+
- - "~>"
|
|
39
|
+
- !ruby/object:Gem::Version
|
|
40
|
+
version: '0.9'
|
|
41
|
+
- !ruby/object:Gem::Dependency
|
|
42
|
+
name: public_suffix
|
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
|
44
|
+
requirements:
|
|
45
|
+
- - ">="
|
|
46
|
+
- !ruby/object:Gem::Version
|
|
47
|
+
version: '6'
|
|
48
|
+
- - "<"
|
|
49
|
+
- !ruby/object:Gem::Version
|
|
50
|
+
version: '8'
|
|
51
|
+
type: :runtime
|
|
52
|
+
prerelease: false
|
|
53
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
54
|
+
requirements:
|
|
55
|
+
- - ">="
|
|
56
|
+
- !ruby/object:Gem::Version
|
|
57
|
+
version: '6'
|
|
58
|
+
- - "<"
|
|
59
|
+
- !ruby/object:Gem::Version
|
|
60
|
+
version: '8'
|
|
61
|
+
- !ruby/object:Gem::Dependency
|
|
62
|
+
name: simplecov
|
|
63
|
+
requirement: !ruby/object:Gem::Requirement
|
|
64
|
+
requirements:
|
|
65
|
+
- - "~>"
|
|
66
|
+
- !ruby/object:Gem::Version
|
|
67
|
+
version: '0.22'
|
|
68
|
+
type: :development
|
|
69
|
+
prerelease: false
|
|
70
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
71
|
+
requirements:
|
|
72
|
+
- - "~>"
|
|
73
|
+
- !ruby/object:Gem::Version
|
|
74
|
+
version: '0.22'
|
|
75
|
+
description: Moderation additions for Fedipub; reporting, limit/suspend, server blocking,
|
|
76
|
+
etc
|
|
77
|
+
email:
|
|
78
|
+
- james@floppy.org.uk
|
|
79
|
+
executables: []
|
|
80
|
+
extensions: []
|
|
81
|
+
extra_rdoc_files: []
|
|
82
|
+
files:
|
|
83
|
+
- README.md
|
|
84
|
+
- Rakefile
|
|
85
|
+
- app/models/fedipub/moderation/domain_block.rb
|
|
86
|
+
- app/models/fedipub/moderation/report.rb
|
|
87
|
+
- app/services/fedipub/moderation/application_service.rb
|
|
88
|
+
- app/services/fedipub/moderation/report_creation_service.rb
|
|
89
|
+
- app/validators/fedipub/moderation/domain_name_validator.rb
|
|
90
|
+
- config/initializers/extensions.rb
|
|
91
|
+
- config/initializers/handlers.rb
|
|
92
|
+
- config/routes.rb
|
|
93
|
+
- db/migrate/20241127105043_create_federails_moderation_reports.rb
|
|
94
|
+
- db/migrate/20241128115659_create_federails_moderation_domain_blocks.rb
|
|
95
|
+
- db/migrate/20260729204941_rename_federails_moderation_to_fedipub_moderation.rb
|
|
96
|
+
- lib/fedipub/moderation.rb
|
|
97
|
+
- lib/fedipub/moderation/configuration.rb
|
|
98
|
+
- lib/fedipub/moderation/engine.rb
|
|
99
|
+
- lib/fedipub/moderation/filtered_inbox.rb
|
|
100
|
+
- lib/fedipub/moderation/filtered_notifier.rb
|
|
101
|
+
- lib/fedipub/moderation/railtie.rb
|
|
102
|
+
- lib/fedipub/moderation/version.rb
|
|
103
|
+
- lib/tasks/fedipub/moderation_tasks.rake
|
|
104
|
+
homepage: https://gitlab.com/fedipub/fedipub-moderation
|
|
105
|
+
licenses:
|
|
106
|
+
- MIT
|
|
107
|
+
metadata:
|
|
108
|
+
homepage_uri: https://gitlab.com/fedipub/fedipub-moderation
|
|
109
|
+
source_code_uri: https://gitlab.com/fedipub/fedipub-moderation
|
|
110
|
+
changelog_uri: https://gitlab.com/fedipub/fedipub-moderation/releases
|
|
111
|
+
post_install_message:
|
|
112
|
+
rdoc_options: []
|
|
113
|
+
require_paths:
|
|
114
|
+
- lib
|
|
115
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
116
|
+
requirements:
|
|
117
|
+
- - ">="
|
|
118
|
+
- !ruby/object:Gem::Version
|
|
119
|
+
version: '3.3'
|
|
120
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
121
|
+
requirements:
|
|
122
|
+
- - ">="
|
|
123
|
+
- !ruby/object:Gem::Version
|
|
124
|
+
version: '0'
|
|
125
|
+
requirements: []
|
|
126
|
+
rubygems_version: 3.5.22
|
|
127
|
+
signing_key:
|
|
128
|
+
specification_version: 4
|
|
129
|
+
summary: Moderation additions for Fedipub.
|
|
130
|
+
test_files: []
|