Page Menu
Home
GRNET
Search
Configure Global Search
Log In
Files
F449192
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Subscribers
None
File Metadata
Details
File Info
Storage
Attached
Created
Thu, Apr 24, 4:12 PM
Size
9 KB
Mime Type
text/x-diff
Expires
Sat, Apr 26, 4:12 PM (1 d, 20 h)
Engine
blob
Format
Raw Data
Handle
214867
Attached To
rWEBDNS WebDNS (edet4)
View Options
diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb
index 01aae98..365ef77 100644
--- a/app/controllers/users_controller.rb
+++ b/app/controllers/users_controller.rb
@@ -1,48 +1,55 @@
class UsersController < ApplicationController
before_action :authenticate_user!
- before_action :user, only: [:mute, :unmute, :token, :generate_token]
+ before_action :user, only: [:mute, :unmute, :mute_all, :token, :generate_token]
# GET /users/1/token
def token
end
# POST /users/1/generate_token
def generate_token
@user.token = SecureRandom.hex(10)
@user.save!
redirect_to token_user_path(@user)
end
# PUT /users/1/unsubscribe/2
def mute
domain = show_domain_scope.find(params[:domain_id])
@user.subscriptions.find_or_create_by!(domain: domain)
redirect_to domains_url, notice: "Successfully unsubscribed from #{domain.name} notifications!"
end
# PUT /users/1/subscribe/2
def unmute
domain = show_domain_scope.find(params[:domain_id])
# Drop all opt-outs
@user.subscriptions.where(domain: domain).delete_all
redirect_to domains_url, notice: "Successfully subscribed to #{domain.name} notifications!"
end
+ # PUT /users/1/domains/mute
+ def mute_all
+ @user.mute_all_domains
+
+ redirect_to domains_url, notice: "Successfully unsubscribed from all domain notifications!"
+ end
+
private
def user
@user ||= User.find(params[:user_id] || params[:id])
# Guard access to other user tokens
if current_user.id != @user.id && !admin?
redirect_to(root_path, alert: 'You need admin rights for that!')
end
@user
end
end
diff --git a/app/models/user.rb b/app/models/user.rb
index 51e2f75..66f7508 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -1,32 +1,48 @@
class User < ActiveRecord::Base
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
has_many :memberships
has_many :groups, through: :memberships
has_many :subscriptions, dependent: :delete_all
scope :orphans, -> { includes(:memberships).where(:memberships => { user_id: nil }) }
# Check if the user can change his password
#
# Remote users are not able to change their password
def can_change_password?
!identifier?
end
def to_api
Hash[
:id, id,
:email, email
].with_indifferent_access
end
def self.find_for_database_authentication(conditions)
# Override devise method for database auth
# We only want to auth local user via the database.
find_first_by_auth_conditions(conditions, identifier: '')
end
+
+ def mute_all_domains
+ ActiveRecord::Base.transaction do
+ domain_ids = Domain.where(group: groups).pluck(:id)
+ domain_ids.each { |did|
+
+ sub = self.subscriptions.create(domain_id: did)
+ if !sub.valid?
+ # Allow only domain_id (uniqueness) errors
+ raise x.errors.full_messages.join(', ') if sub.errors.size > 1
+ raise x.errors.full_messages.join(', ') if !sub.errors[:domain_id]
+ end
+
+ }
+ end
+ end
end
diff --git a/app/views/shared/_nav.html.erb b/app/views/shared/_nav.html.erb
index e05d35d..a6281ba 100644
--- a/app/views/shared/_nav.html.erb
+++ b/app/views/shared/_nav.html.erb
@@ -1,57 +1,59 @@
<!-- Fixed navbar -->
<nav class="navbar navbar-inverse navbar-fixed-top">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="/">WebDNS</a>
</div>
<div id="navbar" class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li class="active"><a href="/domains">Domains</a></li>
<form class="navbar-form navbar-left" role="search" action="/records/search" method="get">
<div class="form-group">
<input type="text" name="q" id="q" class="form-control" placeholder="Records" value="<%= params[:q] %>">
</div>
<button type="submit" class="btn btn-default">Search</button>
</form>
</ul>
<ul class="nav navbar-nav navbar-right">
<% if admin? %>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown">
Admin<span class="caret"></span>
</a>
<ul class="dropdown-menu">
<li><a href="/admin/groups/">Groups</a></li>
<li><a href="/admin/jobs/">Jobs</a></li>
<li><a href="/admin/users/orphans/">Orphans</a></li>
</ul>
</li>
<% end %>
<% if user_signed_in? %>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown">
<%= current_user.try(:email) %>
<span class="caret"></span>
</a>
<ul class="dropdown-menu">
<% if current_user.can_change_password? %>
<li><%= link_to('Change Password', edit_user_registration_path) %></li>
<% end %>
+ <li><%= link_to('Mute notifications', mute_user_domains_path(current_user), method: :put,
+ title: 'Mute all domain notifications') %></li>
<li><%= link_to('API Token', token_user_path(current_user)) %></li>
<li><%= link_to('Logout', destroy_user_session_path, method: :delete) %></li>
</ul>
</li>
<% end %>
</ul>
</div><!--/.nav-collapse -->
</div>
</nav>
diff --git a/config/routes.rb b/config/routes.rb
index 6c277dc..3dac3f1 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -1,86 +1,87 @@
Rails.application.routes.draw do
# Override devise user removal
devise_scope :users do
delete :users, to: redirect('/')
end
devise_for :users
get '/auth/saml', to: 'auth#saml'
root to: redirect('/domains')
resources :users, only: [] do
get :token, to: 'users#token', on: :member
post :generate_token, to: 'users#generate_token', on: :member
resources :domains, only: [] do
put :mute, to: 'users#mute'
put :unmute, to: 'users#unmute'
+ put :mute, to: 'users#mute_all', on: :collection
end
end
resources :groups, only: [:show] do
get :search_member,
to: 'groups#search_member', on: :member
post :members,
to: 'groups#create_member', as: :create_member, on: :member
delete 'member/:user_id',
to: 'groups#destroy_member', as: :destroy_member, on: :member
end
resources :domains do
get :edit_dnssec, to: 'domains#edit_dnssec', on: :member
delete :full_destroy, to: 'domains#full_destroy', on: :member
resources :records, except: [:index, :show] do
# Reuse records#update instead of introducing new controller actions
#
# rubocop:disable Style/AlignHash
put :disable, to: 'records#update', on: :member,
defaults: { record: { disabled: true } }
put :enable, to: 'records#update', on: :member,
defaults: { record: { disabled: false } }
put :editable, to: 'records#editable', on: :collection
post :valid, to: 'records#valid', on: :collection
post :bulk, to: 'records#bulk', on: :collection
# rubocop:enable Style/AlignHash
end
end
get '/records/search', to: 'records#search'
# Admin
namespace :admin do
root to: redirect('/admin/groups')
resources :groups, except: [:show]
resources :jobs, only: [:index, :destroy] do
put :done, to: 'jobs#update', on: :member,
defaults: { job: { status: 1 } }
put :pending, to: 'jobs#update', on: :member,
defaults: { job: { status: 0 } }
get '/type/:category', to: 'jobs#index', on: :collection,
constraints: proc { |req| ['completed', 'pending'].include?(req.params[:category]) }
end
resources :users, only: [:destroy] do
get :orphans, to: 'users#orphans', on: :collection
put :update_groups, to: 'users#update_groups', on: :collection
end
end
# API
scope '/api' do
get :ping, to: 'api#ping'
get :whoami, to: 'api#whoami'
get '/domain/:domain/list', to: 'api#list', constraints: { domain: /[^\/]+/}
post '/domain/:domain/bulk', to: 'api#bulk', constraints: { domain: /[^\/]+/}
get :domains, to: 'api#domains'
end if WebDNS.settings[:api]
# Private
put 'private/replace_ds', to: 'private#replace_ds'
put 'private/trigger_event', to: 'private#trigger_event'
get 'private/zones', to: 'private#zones'
get 'help/api', to: 'help#api'
end
diff --git a/test/models/subscription_test.rb b/test/models/subscription_test.rb
index b3f9a84..74018eb 100644
--- a/test/models/subscription_test.rb
+++ b/test/models/subscription_test.rb
@@ -1,17 +1,35 @@
require 'test_helper'
class SubscriptionTest < ActiveSupport::TestCase
test 'single subscription for a domain' do
domain = create(:domain_with_subscriptions)
assert_equal 1, domain.opt_outs.count
subscription = domain.opt_outs.first
assert_equal true, subscription.disabled
user = subscription.user
user.reload
assert_equal domain, user.subscriptions.first.domain
end
+
+ test 'mute all domains for a user' do
+ d1 = create(:domain_with_subscriptions)
+ d2 = create(:domain_with_subscriptions)
+ user = create(:user)
+
+ # Add user to the groups
+ d1.group.users << user
+ d2.group.users << user
+
+ # Opt out from notifications
+ user.mute_all_domains
+ # Ensure this is re-entrant
+ user.mute_all_domains
+
+ # Assert 2 opt-out domains
+ assert_equal 2, user.subscriptions.count
+ end
end
Event Timeline
Log In to Comment