diff --git a/app/assets/javascripts/admin/templates/group.hbs b/app/assets/javascripts/admin/templates/group.hbs
index 81e2da28de2..d2d2020e8f8 100644
--- a/app/assets/javascripts/admin/templates/group.hbs
+++ b/app/assets/javascripts/admin/templates/group.hbs
@@ -92,6 +92,11 @@
{{combo-box name="grant_trust_level" valueAttribute="value" value=model.grant_trust_level content=trustLevelOptions}}
+
+
+
+ {{text-field name="incoming_email" value=model.incoming_email placeholderKey="admin.groups.incoming_email_placeholder"}}
+
{{/unless}}
diff --git a/app/assets/javascripts/discourse/models/group.js.es6 b/app/assets/javascripts/discourse/models/group.js.es6
index b8979d2b78f..361eb3ba384 100644
--- a/app/assets/javascripts/discourse/models/group.js.es6
+++ b/app/assets/javascripts/discourse/models/group.js.es6
@@ -98,7 +98,8 @@ const Group = Discourse.Model.extend({
automatic_membership_retroactive: !!this.get('automatic_membership_retroactive'),
title: this.get('title'),
primary_group: !!this.get('primary_group'),
- grant_trust_level: this.get('grant_trust_level')
+ grant_trust_level: this.get('grant_trust_level'),
+ incoming_email: this.get("incoming_email"),
};
},
diff --git a/app/controllers/admin/groups_controller.rb b/app/controllers/admin/groups_controller.rb
index f614a15b5f2..62653c427e2 100644
--- a/app/controllers/admin/groups_controller.rb
+++ b/app/controllers/admin/groups_controller.rb
@@ -81,6 +81,8 @@ class Admin::GroupsController < Admin::AdminController
group.primary_group = group.automatic ? false : params["primary_group"] == "true"
+ group.incoming_email = group.automatic ? nil : params[:incoming_email]
+
title = params[:title] if params[:title].present?
group.title = group.automatic ? nil : title
diff --git a/app/models/group.rb b/app/models/group.rb
index 6de579db38b..7684e4f9ec7 100644
--- a/app/models/group.rb
+++ b/app/models/group.rb
@@ -8,6 +8,8 @@ class Group < ActiveRecord::Base
has_many :categories, through: :category_groups
has_many :users, through: :group_users
+ before_save :downcase_incoming_email
+
after_save :destroy_deletions
after_save :automatic_group_membership
after_save :update_primary_group
@@ -23,6 +25,7 @@ class Group < ActiveRecord::Base
validate :name_format_validator
validates_uniqueness_of :name, case_sensitive: false
validate :automatic_membership_email_domains_format_validator
+ validate :incoming_email_validator
AUTO_GROUPS = {
:everyone => 0,
@@ -70,6 +73,17 @@ class Group < ActiveRecord::Base
)", levels: levels, user_id: user && user.id )
}
+ def downcase_incoming_email
+ self.incoming_email = (incoming_email || "").strip.downcase.presence
+ end
+
+ def incoming_email_validator
+ return if self.automatic || self.incoming_email.blank?
+ unless Email.is_valid?(incoming_email)
+ self.errors.add(:base, I18n.t('groups.errors.invalid_incoming_email', incoming_email: incoming_email))
+ end
+ end
+
def posts_for(guardian, before_post_id=nil)
user_ids = group_users.map {|gu| gu.user_id}
result = Post.where(user_id: user_ids).includes(:user, :topic, :topic => :category).references(:posts, :topics, :category)
diff --git a/app/serializers/basic_group_serializer.rb b/app/serializers/basic_group_serializer.rb
index 38644aff4da..cc7ea1a229c 100644
--- a/app/serializers/basic_group_serializer.rb
+++ b/app/serializers/basic_group_serializer.rb
@@ -9,5 +9,10 @@ class BasicGroupSerializer < ApplicationSerializer
:automatic_membership_retroactive,
:primary_group,
:title,
- :grant_trust_level
+ :grant_trust_level,
+ :incoming_email
+
+ def include_incoming_email?
+ scope.is_staff?
+ end
end
diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml
index e66c1f214e4..d2ef04368c0 100644
--- a/config/locales/client.en.yml
+++ b/config/locales/client.en.yml
@@ -1958,6 +1958,8 @@ en:
primary_group: "Automatically set as primary group"
group_owners: Owners
add_owners: Add owners
+ incoming_email: "Custom incoming email address"
+ incoming_email_placeholder: "enter email address"
api:
diff --git a/config/locales/server.en.yml b/config/locales/server.en.yml
index 82fc7339e7f..d035d192fce 100644
--- a/config/locales/server.en.yml
+++ b/config/locales/server.en.yml
@@ -194,6 +194,7 @@ en:
can_not_modify_automatic: "You can not modify an automatic group"
member_already_exist: "'%{username}' is already a member of this group."
invalid_domain: "'%{domain}' is not a valid domain."
+ invalid_incoming_email: "'%{incoming_email}' is not a valid email address."
default_names:
everyone: "everyone"
admins: "admins"
diff --git a/db/migrate/20151201161726_add_incoming_email_to_groups.rb b/db/migrate/20151201161726_add_incoming_email_to_groups.rb
new file mode 100644
index 00000000000..afea28ba220
--- /dev/null
+++ b/db/migrate/20151201161726_add_incoming_email_to_groups.rb
@@ -0,0 +1,6 @@
+class AddIncomingEmailToGroups < ActiveRecord::Migration
+ def change
+ add_column :groups, :incoming_email, :string, null: true
+ add_index :groups, :incoming_email, unique: true
+ end
+end
diff --git a/spec/controllers/admin/groups_controller_spec.rb b/spec/controllers/admin/groups_controller_spec.rb
index a80f7bbf1ed..677bc07890e 100644
--- a/spec/controllers/admin/groups_controller_spec.rb
+++ b/spec/controllers/admin/groups_controller_spec.rb
@@ -30,7 +30,8 @@ describe Admin::GroupsController do
"automatic_membership_retroactive"=>false,
"title"=>nil,
"primary_group"=>false,
- "grant_trust_level"=>nil
+ "grant_trust_level"=>nil,
+ "incoming_email"=>nil
}])
end
diff --git a/spec/models/group_spec.rb b/spec/models/group_spec.rb
index 5c4ce42cd8f..87bd3898bcc 100644
--- a/spec/models/group_spec.rb
+++ b/spec/models/group_spec.rb
@@ -43,6 +43,16 @@ describe Group do
group.automatic_membership_email_domains = "discourse.org|wikipedia.org"
expect(group.valid?).to eq true
end
+
+ it "is invalid for bad incoming email" do
+ group.incoming_email = "foo.bar.org"
+ expect(group.valid?).to eq(false)
+ end
+
+ it "is valid for proper incoming email" do
+ group.incoming_email = "foo@bar.org"
+ expect(group.valid?).to eq(true)
+ end
end
def real_admins