diff --git a/app/controllers/moderator/invitations_controller.rb b/app/controllers/moderator/invitations_controller.rb
index 296041b32..82a725cfc 100644
--- a/app/controllers/moderator/invitations_controller.rb
+++ b/app/controllers/moderator/invitations_controller.rb
@@ -1,9 +1,17 @@
module Moderator
class InvitationsController < ApplicationController
+ before_filter :moderator_only
+
def new
end
def create
+ User.find(params[:invitation][:user_id]).invite!(params[:invitation][:level])
+ redirect_to moderator_invitations_path
+ end
+
+ def index
+ @users = User.where("inviter_id = ?", CurrentUser.id).paginate(params[:page])
end
end
end
diff --git a/app/controllers/moderator/ip_addrs_controller.rb b/app/controllers/moderator/ip_addrs_controller.rb
index de497b4d0..94c38a9c7 100644
--- a/app/controllers/moderator/ip_addrs_controller.rb
+++ b/app/controllers/moderator/ip_addrs_controller.rb
@@ -1,5 +1,7 @@
module Moderator
class IpAddrsController < ApplicationController
+ before_filter :janitor_only
+
def index
@search = IpAddrSearch.new(params[:search])
end
diff --git a/app/helpers/moderator/invitations_helper.rb b/app/helpers/moderator/invitations_helper.rb
new file mode 100644
index 000000000..4d6a58cff
--- /dev/null
+++ b/app/helpers/moderator/invitations_helper.rb
@@ -0,0 +1,10 @@
+module Moderator
+ module InvitationsHelper
+ def level_select
+ choices = []
+ choices << ["Privileged", User::Levels::PRIVILEGED]
+ choices << ["Contributor", User::Levels::CONTRIBUTOR]
+ select(:invitation, :level, choices)
+ end
+ end
+end
diff --git a/app/models/user.rb b/app/models/user.rb
index 34bab9cdc..6d114b7ea 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -52,6 +52,16 @@ class User < ActiveRecord::Base
end
end
+ module InvitationMethods
+ def invite!(level)
+ if level.to_i <= Levels::CONTRIBUTOR
+ self.level = level
+ self.inviter_id = CurrentUser.id
+ save
+ end
+ end
+ end
+
module NameMethods
extend ActiveSupport::Concern
@@ -304,6 +314,7 @@ class User < ActiveRecord::Base
include BlacklistMethods
include ForumMethods
include LimitMethods
+ include InvitationMethods
def initialize_default_image_size
self.default_image_size = "Medium"
diff --git a/app/views/moderator/invitations/index.html.erb b/app/views/moderator/invitations/index.html.erb
new file mode 100644
index 000000000..f710a98e2
--- /dev/null
+++ b/app/views/moderator/invitations/index.html.erb
@@ -0,0 +1,13 @@
+
+
+
Invitations
+
+
+ <% @users.each do |user| %>
+
<%= link_to user.name, user_path(user) %>
+ <% end %>
+
+
+ <%= numbered_paginator(@users) %>
+
+
diff --git a/app/views/moderator/invitations/new.html.erb b/app/views/moderator/invitations/new.html.erb
new file mode 100644
index 000000000..3b64f79e5
--- /dev/null
+++ b/app/views/moderator/invitations/new.html.erb
@@ -0,0 +1,19 @@
+
+
+
New Invitation
+
+ <%= form_tag(moderator_invitations_path) do %>
+
+
+ <%= text_field :invitation, :user_name %>
+
+
+
+
+ <%= level_select %>
+
+
+ <%= submit_tag %>
+ <% end %>
+
+
diff --git a/config/routes.rb b/config/routes.rb
index 00ece4f46..dda1785a8 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -9,6 +9,7 @@ Danbooru::Application.routes.draw do
get :search
end
end
+ resources :invitations, :only => [:new, :create, :index]
resource :tag
namespace :post do
resource :dashboard, :only => [:show]
diff --git a/test/factories/user.rb b/test/factories/user.rb
index 9bfdf7856..491a15bf3 100644
--- a/test/factories/user.rb
+++ b/test/factories/user.rb
@@ -5,6 +5,7 @@ Factory.define(:user) do |f|
f.email {Faker::Internet.email}
f.default_image_size "medium"
f.base_upload_limit 10
+ f.level 20
end
Factory.define(:banned_user, :parent => :user) do |f|
diff --git a/test/functional/moderator/invitations_controller_test.rb b/test/functional/moderator/invitations_controller_test.rb
new file mode 100644
index 000000000..08dce7ec2
--- /dev/null
+++ b/test/functional/moderator/invitations_controller_test.rb
@@ -0,0 +1,34 @@
+require 'test_helper'
+
+module Moderator
+ class InvitationsControllerTest < ActionController::TestCase
+ context "The invitations controller" do
+ setup do
+ @mod = Factory.create(:moderator_user)
+ CurrentUser.user = @mod
+ CurrentUser.ip_addr = "127.0.0.1"
+ MEMCACHE.flush_all
+
+ @user_1 = Factory.create(:user)
+ @user_2 = Factory.create(:user, :inviter_id => @mod.id)
+ end
+
+ should "render the new page" do
+ get :new, {}, {:user_id => @mod.id}
+ assert_response :success
+ end
+
+ should "create a new invite" do
+ post :create, {:invitation => {:user_id => @user_1.id, :level => User::Levels::CONTRIBUTOR}}, {:user_id => @mod.id}
+ assert_redirected_to(moderator_invitations_path)
+ @user_1.reload
+ assert_equal(User::Levels::CONTRIBUTOR, @user_1.level)
+ end
+
+ should "list invites" do
+ get :index
+ assert_response :success
+ end
+ end
+ end
+end
diff --git a/test/unit/user_test.rb b/test/unit/user_test.rb
index 6ecedd073..924ee2816 100644
--- a/test/unit/user_test.rb
+++ b/test/unit/user_test.rb
@@ -13,6 +13,24 @@ class UserTest < ActiveSupport::TestCase
CurrentUser.user = nil
CurrentUser.ip_addr = nil
end
+
+ context "that has been invited by a mod" do
+ setup do
+ @mod = Factory.create(:moderator_user)
+ end
+
+ should "work" do
+ @user.invite!(User::Levels::CONTRIBUTOR)
+ @user.reload
+ assert_equal(User::Levels::CONTRIBUTOR, @user.level)
+ end
+
+ should "not allow invites up to janitor level or beyond" do
+ @user.invite!(User::Levels::JANITOR)
+ @user.reload
+ assert_equal(User::Levels::MEMBER, @user.level)
+ end
+ end
should "not validate if the originating ip address is banned" do
Factory.create(:ip_ban)