Remove participants limit for conversations

The limit was added in 2012 to prevent spam, but since the participants
need to be a mutual contact with the author nowadays, I don't think it's
a spam problem anymore.

I also added a validation for the minimum count of the participants,
because a conversion without participants doesn't make much sense.
This commit is contained in:
Benjamin Neff 2018-01-18 02:32:36 +01:00
parent 03d779ef39
commit 5e81760f30
No known key found for this signature in database
GPG key ID: 971464C3F1A90194
8 changed files with 148 additions and 108 deletions

View file

@ -6,14 +6,14 @@ This entity represents a private conversation between persons.
## Properties
| Property | Type (Length) | Description |
| -------------- | ----------------------------- | -------------------------------------------------------------------------------------------------------------- |
| `author` | [diaspora\* ID][diaspora-id] | The diaspora\* ID of the author of the conversation. |
| `guid` | [GUID][guid] | The GUID of the conversation. |
| `subject` | [String][string] (255) | The subject of the conversation. |
| `created_at` | [Timestamp][timestamp] | The create timestamp of the conversation. |
| `participants` | [diaspora\* ID][diaspora-id]s | diaspora\* IDs of all participants of this conversation, including the `author`, seperated by `;`, at most 20. |
| `message` | [Message][message] | The first Message in the conversation, needs to be the same `author`. |
| Property | Type (Length) | Description |
| -------------- | ----------------------------- | -------------------------------------------------------------------------------------------------- |
| `author` | [diaspora\* ID][diaspora-id] | The diaspora\* ID of the author of the conversation. |
| `guid` | [GUID][guid] | The GUID of the conversation. |
| `subject` | [String][string] (255) | The subject of the conversation. |
| `created_at` | [Timestamp][timestamp] | The create timestamp of the conversation. |
| `participants` | [diaspora\* ID][diaspora-id]s | diaspora\* IDs of all participants of this conversation, including the `author`, seperated by `;`. |
| `message` | [Message][message] | The first Message in the conversation, needs to be the same `author`. |
## Example

View file

@ -19,7 +19,7 @@ end
require "diaspora_federation/validators/rules/birthday"
require "diaspora_federation/validators/rules/boolean"
require "diaspora_federation/validators/rules/diaspora_id"
require "diaspora_federation/validators/rules/diaspora_id_count"
require "diaspora_federation/validators/rules/diaspora_id_list"
require "diaspora_federation/validators/rules/guid"
require "diaspora_federation/validators/rules/not_nil"
require "diaspora_federation/validators/rules/public_key"

View file

@ -9,7 +9,7 @@ module DiasporaFederation
rule :subject, [:not_empty, length: {maximum: 255}]
rule :participants, diaspora_id_count: {maximum: 20}
rule :participants, diaspora_id_list: {minimum: 2}
rule :messages, :not_nil
end
end

View file

@ -1,37 +0,0 @@
module Validation
module Rule
# Rule for validating the number of diaspora* IDs in a string.
# The evaluated string is split at ";" and the result will be counted.
class DiasporaIdCount
# This rule must have a +maximum+ param.
# @return [Hash] params
attr_reader :params
# Creates a new rule for a maximum diaspora* ID count validation
# @param [Hash] params
# @option params [Integer] :maximum maximum allowed id count
def initialize(params)
unless params.include?(:maximum) && params[:maximum].is_a?(Integer)
raise ArgumentError, "A number has to be specified for :maximum"
end
@params = params
end
# The error key for this rule
# @return [Symbol] error key
def error_key
:diaspora_id_count
end
def valid_value?(value)
ids = value.split(";")
return false unless ids.count <= params[:maximum]
ids.each do |id|
return false if DiasporaId::DIASPORA_ID.match(id).nil?
end
true
end
end
end
end

View file

@ -0,0 +1,41 @@
module Validation
module Rule
# Rule for validating the number of diaspora* IDs in a string.
# The evaluated string is split at ";".
class DiasporaIdList
# This rule can have a +minimum+ or +maximum+ param.
# @return [Hash] params
attr_reader :params
# Creates a new rule for a diaspora* ID list validation
# @param [Hash] params
# @option params [Integer] :minimum minimum allowed id count
# @option params [Integer] :maximum maximum allowed id count
def initialize(params={})
%i[minimum maximum].each do |param|
if params.include?(param) && !params[param].is_a?(Integer)
raise ArgumentError, "The :#{param} needs to be an Integer"
end
end
@params = params
end
# The error key for this rule
# @return [Symbol] error key
def error_key
:diaspora_id_list
end
def valid_value?(value)
ids = value.split(";")
return false if params.include?(:maximum) && ids.count > params[:maximum]
return false if params.include?(:minimum) && ids.count < params[:minimum]
ids.each do |id|
return false if DiasporaId::DIASPORA_ID.match(id).nil?
end
true
end
end
end
end

View file

@ -29,11 +29,15 @@ module DiasporaFederation
end
describe "#participant_ids" do
# must not contain more than 20 participant handles
it_behaves_like "a property with a value validation/restriction" do
let(:property) { :participants }
let(:wrong_values) { [Array.new(21) { Fabricate.sequence(:diaspora_id) }.join(";")] }
let(:correct_values) { [Array.new(20) { Fabricate.sequence(:diaspora_id) }.join(";")] }
let(:wrong_values) { ["", "foo;bar", Fabricate.sequence(:diaspora_id)] }
let(:correct_values) {
[
Array.new(2) { Fabricate.sequence(:diaspora_id) }.join(";"),
Array.new(21) { Fabricate.sequence(:diaspora_id) }.join(";")
]
}
end
end
end

View file

@ -1,58 +0,0 @@
describe Validation::Rule::DiasporaIdCount do
let(:id_str) { Array.new(3) { Fabricate.sequence(:diaspora_id) }.join(";") }
it "requires a parameter" do
validator = Validation::Validator.new({})
expect {
validator.rule(:ids, :diaspora_id_count)
}.to raise_error ArgumentError
end
it "requires a integer as parameter" do
validator = Validation::Validator.new({})
[nil, "", 5.5].each do |val|
expect {
validator.rule(:ids, diaspora_id_count: {maximum: val})
}.to raise_error ArgumentError, "A number has to be specified for :maximum"
end
end
it "has an error key" do
expect(described_class.new(maximum: 5).error_key).to eq(:diaspora_id_count)
end
context "validation" do
it "validates less ids" do
validator = Validation::Validator.new(OpenStruct.new(ids: id_str))
validator.rule(:ids, diaspora_id_count: {maximum: 5})
expect(validator).to be_valid
expect(validator.errors).to be_empty
end
it "fails for less but non ids" do
bad_str = "user@example.com;i am a weird diaspora* ID @@@ ### 12345;shouldnt be reached by a rule"
validator = Validation::Validator.new(OpenStruct.new(ids: bad_str))
validator.rule(:ids, diaspora_id_count: {maximum: 5})
expect(validator).not_to be_valid
expect(validator.errors).to include(:ids)
end
it "validates exactly as many ids" do
validator = Validation::Validator.new(OpenStruct.new(ids: id_str))
validator.rule(:ids, diaspora_id_count: {maximum: 3})
expect(validator).to be_valid
expect(validator.errors).to be_empty
end
it "fails for too many ids" do
validator = Validation::Validator.new(OpenStruct.new(ids: id_str))
validator.rule(:ids, diaspora_id_count: {maximum: 1})
expect(validator).not_to be_valid
expect(validator.errors).to include(:ids)
end
end
end

View file

@ -0,0 +1,90 @@
describe Validation::Rule::DiasporaIdList do
let(:id_str) { Array.new(3) { Fabricate.sequence(:diaspora_id) }.join(";") }
it "does not require a parameter" do
validator = Validation::Validator.new({})
expect {
validator.rule(:ids, :diaspora_id_list)
}.not_to raise_error
end
it "allows a :maximum parameter" do
validator = Validation::Validator.new({})
expect {
validator.rule(:ids, diaspora_id_list: {maximum: 20})
}.not_to raise_error
end
it "requires a integer as :maximum" do
validator = Validation::Validator.new({})
[nil, "", 5.5].each do |val|
expect {
validator.rule(:ids, diaspora_id_list: {maximum: val})
}.to raise_error ArgumentError, "The :maximum needs to be an Integer"
end
end
it "requires a integer as :minimum" do
validator = Validation::Validator.new({})
[nil, "", 5.5].each do |val|
expect {
validator.rule(:ids, diaspora_id_list: {minimum: val})
}.to raise_error ArgumentError, "The :minimum needs to be an Integer"
end
end
it "has an error key" do
expect(described_class.new(maximum: 5).error_key).to eq(:diaspora_id_list)
end
context "validation" do
it "validates less ids" do
validator = Validation::Validator.new(OpenStruct.new(ids: id_str))
validator.rule(:ids, diaspora_id_list: {maximum: 5})
expect(validator).to be_valid
expect(validator.errors).to be_empty
end
it "fails for less but non ids" do
bad_str = "user@example.com;i am a weird diaspora* ID @@@ ### 12345;shouldnt be reached by a rule"
validator = Validation::Validator.new(OpenStruct.new(ids: bad_str))
validator.rule(:ids, diaspora_id_list: {maximum: 5})
expect(validator).not_to be_valid
expect(validator.errors).to include(:ids)
end
it "validates exactly as many ids" do
validator = Validation::Validator.new(OpenStruct.new(ids: id_str))
validator.rule(:ids, diaspora_id_list: {minimum: 3, maximum: 3})
expect(validator).to be_valid
expect(validator.errors).to be_empty
end
it "validates without params" do
validator = Validation::Validator.new(OpenStruct.new(ids: id_str))
validator.rule(:ids, :diaspora_id_list)
expect(validator).to be_valid
expect(validator.errors).to be_empty
end
it "fails for too many ids" do
validator = Validation::Validator.new(OpenStruct.new(ids: id_str))
validator.rule(:ids, diaspora_id_list: {maximum: 2})
expect(validator).not_to be_valid
expect(validator.errors).to include(:ids)
end
it "fails for too less ids" do
validator = Validation::Validator.new(OpenStruct.new(ids: id_str))
validator.rule(:ids, diaspora_id_list: {minimum: 4})
expect(validator).not_to be_valid
expect(validator.errors).to include(:ids)
end
end
end