canvas-lms/app/controllers/notification_preferences_co...

120 lines
4.8 KiB
Ruby

#
# Copyright (C) 2013 Instructure, Inc.
#
# This file is part of Canvas.
#
# Canvas is free software: you can redistribute it and/or modify it under
# the terms of the GNU Affero General Public License as published by the Free
# Software Foundation, version 3 of the License.
#
# Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
# details.
#
# You should have received a copy of the GNU Affero General Public License along
# with this program. If not, see <http://www.gnu.org/licenses/>.
#
# @API Notification Preferences
#
# API for managing notification preferences
#
# @model NotificationPreference
# {
# "id": "NotificationPreference",
# "description": "",
# "properties": {
# "href": {
# "example": "https://canvas.instructure.com/users/1/communication_channels/email/student@example.edu/notification_preferences/new_announcement",
# "type": "string"
# },
# "notification": {
# "description": "The notification this preference belongs to",
# "example": "new_announcement",
# "type": "string"
# },
# "category": {
# "description": "The category of that notification",
# "example": "announcement",
# "type": "string"
# },
# "frequency": {
# "description": "How often to send notifications to this communication channel for the given notification. Possible values are 'immediately', 'daily', 'weekly', and 'never'",
# "example": "daily",
# "type": "string",
# "allowableValues": {
# "values": [
# "immediately",
# "daily",
# "weekly",
# "never"
# ]
# }
# }
# }
# }
#
class NotificationPreferencesController < ApplicationController
before_filter :require_user, :get_cc
include Api::V1::NotificationPolicy
# @API List preferences
# Fetch all preferences for the given communication channel
# @returns [NotificationPreference]
def index
policies = NotificationPolicy.find_all_for(@cc)
render json: { notification_preferences: policies.map { |p| notification_policy_json(p, @current_user, session) } }
end
# @API Get a preference
# Fetch the preference for the given notification for the given communicaiton channel
# @returns NotificationPreference
def show
render json: { notification_preferences: [notification_policy_json(NotificationPolicy.find_or_update_for(@cc, params[:notification]), @current_user, session)] }
end
# @API Update a preference
# Change the preference for a single notification for a single communication channel
# @argument notification_preferences[frequency] [Required] The desired frequency for this notification
def update
return render_unauthorized_action unless @user == @current_user
# support both JSON API style (notification preferences is an array) and Canvas API style (it's a hash)
preference = params[:notification_preferences].is_a?(Array) ? params[:notification_preferences].first : params[:notification_preferences]
render json: { notification_preferences: [notification_policy_json(NotificationPolicy.find_or_update_for(@cc, params[:notification], preference[:frequency]), @current_user, session)] }
end
# @API Update multiple preferences
# Change the preferences for multiple notifications for a single communication channel at once
# @argument notification_preferences[<X>][frequency] [Required] The desired frequency for <X> notification
def update_all
return render_unauthorized_action unless @user == @current_user
policies = []
preferences = convert_hash_to_jsonapi_array(params[:notification_preferences], :notification)
preferences.each do |preference|
policies << NotificationPolicy.find_or_update_for(@cc, preference[:notification], preference[:frequency])
end
render json: { notification_preferences: policies.map{ |p| notification_policy_json(p, @current_user, session) } }
end
private
def convert_hash_to_jsonapi_array(hash, key = :id)
return hash if hash.is_a?(Array)
hash.map { |k, v| { key => k }.reverse_merge!(v).with_indifferent_access }
end
def get_cc
params[:user_id] ||= 'self'
@user = api_find(User, params[:user_id])
if params[:communication_channel_id]
@cc = @user.communication_channels.unretired.find(params[:communication_channel_id])
else
@cc = @user.communication_channels.unretired.of_type(params[:type]).by_path(params[:address]).first
raise ActiveRecord::RecordNotFound unless @cc
end
return unless @user == @current_user || authorized_action(@user, @current_user, :view_statistics)
@cc.user = @user
end
end