Permalink
Browse files

Improve channel, user and api_key models with basic scopes, correct r…

…eferences and protect attributes.

Simplify channels & user controllers and models, moving code to the models.
Remove catch-all route and ensure all actions are specified, fixing url paths.
Change clone to dup in feed_controller as using clone seems to affect the cloned object (problem only in ruby 1.9.3?)
  • Loading branch information...
1 parent bfd5b29 commit 4f0354303f933c708b22581f004c2fcb718b49cd @abradburne abradburne committed Feb 9, 2012
@@ -1,23 +1,22 @@
class ApiKeysController < ApplicationController
+ include KeyUtilities
+
before_filter :require_user, :set_channels_menu
def index
- get_channel_data
- @read_keys = ApiKey.find(:all, :conditions => { :channel_id => @channel.id, :user_id => current_user.id, :write_flag => 0 })
+ @channel = current_user.channels.find(params[:channel_id])
+ @write_key = @channel.api_keys.write_keys.first
+ @read_keys = @channel.api_keys.read_keys
end
def destroy
- @api_key = ApiKey.find_by_api_key(params[:api_key])
- @api_key.delete if @api_key.user_id == current_user.id
+ current_user.api_keys.find_by_api_key(params[:id]).try(:destroy)
redirect_to :back
end
def create
- @channel = Channel.find(params[:channel_id])
- # make sure channel belongs to current user
- check_permissions(@channel)
-
- @api_key = ApiKey.find(:first, :conditions => { :channel_id => @channel.id, :user_id => current_user.id, :write_flag => 1 } )
+ @channel = current_user.channels.find(params[:channel_id])
+ @api_key = @channel.api_keys.write_keys.first
# if no api key found or read api key
if (@api_key.nil? or params[:write] == '0')
@@ -32,14 +31,12 @@ def create
@api_key.save
# redirect
- redirect_to channel_api_keys_path(@channel.id) and return
+ redirect_to channel_api_keys_path(@channel)
end
def update
- @api_key = ApiKey.find_by_api_key(params[:api_key][:api_key])
-
- @api_key.note = params[:api_key][:note]
- @api_key.save if current_user.id == @api_key.user_id
- redirect_to channel_api_keys_path(@api_key.channel)
+ @api_key = current_user.api_keys.find_by_api_key(params[:id])
+ @api_key.update_attributes(params[:api_key])
+ redirect_to :back
end
end
@@ -85,24 +85,19 @@ def get_userkey
# get specified header value
def get_header_value(name)
- value = nil
- for header in request.env
- value = header[1] if (header[0].upcase.index(name.upcase))
- end
- return value
- end
-
- # gets the same data for showing or editing
- def get_channel_data
- @channel = Channel.find(params[:channel_id]) if params[:channel_id]
- @channel = Channel.find(params[:id]) if @channel.nil? and params[:id]
- @key = ''
- # make sure channel belongs to current user
- check_permissions(@channel)
-
- @api_key = ApiKey.find(:first, :conditions => { :channel_id => @channel.id, :user_id => current_user.id, :write_flag => 1 } )
- @key = @api_key.api_key if @api_key
- end
+ value = nil
+ for header in request.env
+ value = header[1] if (header[0].upcase.index(name.upcase))
+ end
+ return value
+ end
+
+ # gets the same data for showing or editing
+ def get_channel_data
+ @channel = current_user.channels.find(params[:channel_id]) if params[:channel_id]
+ @channel = current_user.channels.find(params[:id]) if @channel.nil? and params[:id]
+ @key = @channel.api_keys.write_keys.first.try(:api_key) || ""
+ end
def check_permissions(channel)
render :text => t(:channel_permission) and return if (current_user.nil? || (channel.user_id != current_user.id))
@@ -131,18 +126,6 @@ def bad_feed_xml
return feed_unauthorized.to_xml(:only => :entry_id)
end
- # generates a database unique api key
- def generate_api_key(size = 16)
- alphanumerics = ('0'..'9').to_a + ('A'..'Z').to_a
- k = (0..size).map {alphanumerics[Kernel.rand(36)]}.join
-
- # if key exists in database, regenerate key
- k = generate_api_key if ApiKey.find_by_api_key(k)
-
- # output the key
- return k
- end
-
# options: days = how many days ago, start = start date, end = end date, offset = timezone offset
def get_date_range(params)
# set timezone correctly
@@ -21,72 +21,33 @@ def edit
end
def update
- @channel = Channel.find(params[:id])
- # make sure channel belongs to current user
- check_permissions(@channel)
- # protect against bots
- render :text => '' and return if params[:userlogin].length > 0
-
+ @channel = current_user.channels.find(params[:id])
@channel.update_attributes(params[:channel])
- @channel.name = "#{t(:channel_default_name)} #{@channel.id}" if params[:channel][:name].empty?
- @channel.save
- redirect_to channel_path(@channel.id) and return
+ redirect_to channel_path(@channel.id)
end
- def create
- # protect against bots
- render :text => '' and return if params[:userlogin].length > 0
-
- # get default name for field
- @d = t(:channel_default_field)
-
- # add channel with defaults
- @channel = Channel.new(:field1 => "#{@d}1")
- @channel.user_id = current_user.id
- @channel.save
-
- # now that the channel is saved, we can create the default name
- @channel.name = "#{t(:channel_default_name)} #{@channel.id}"
- @channel.save
-
- # create an api key for this channel
- @api_key = ApiKey.new
- @api_key.channel_id = @channel.id
- @api_key.user_id = current_user.id
- @api_key.write_flag = 1
- @api_key.api_key = generate_api_key
- @api_key.save
-
- # redirect to edit the newly created channel
- redirect_to edit_channel_path(@channel.id)
- end
-
- # clear all data from a channel
- def clear
- channel = Channel.find(params[:id])
- # make sure channel belongs to current user
- check_permissions(channel)
-
- # do the delete
- channel.feeds.each do |f|
- f.delete
- end
-
- # set the channel's last_entry_id to nil
- channel.last_entry_id = nil
- channel.save
-
- redirect_to channels_path
+ def create
+ channel = current_user.channels.create(:field1 => "#{t(:channel_default_field)} 1")
+ channel.add_write_api_key
+
+ # redirect to edit the newly created channel
+ redirect_to edit_channel_path(channel)
+ end
+
+ # clear all data from a channel
+ def clear
+ channel = current_user.channels.find(params[:id])
+ channel.feeds.delete_all
+ channel.update_attribute(:last_entry_id, nil)
+
+ redirect_to channels_path
end
def destroy
- @channel = Channel.find(params[:id])
- # make sure channel belongs to current user
- check_permissions(@channel)
-
- # do the delete
- @channel.delete
+ channel = current_user.channels.find(params[:id])
+ channel.destroy
+
redirect_to channels_path
end
@@ -255,6 +216,9 @@ def upload
redirect_to channel_path(channel.id)
end
+
+private
+
# determine if the date can be parsed
def date_parsable?(date)
return !is_a_number?(date)
@@ -556,7 +556,7 @@ def object_sum(object, comma_flag=false, round=nil)
# creates an empty clone of an object
def create_empty_clone(object)
- empty_clone = object.clone
+ empty_clone = object.dup
empty_clone.attribute_names.each { |attr| empty_clone[attr] = nil }
return empty_clone
end
@@ -1,23 +1,20 @@
class MailerController < ApplicationController
def resetpassword
- # protect against bots
- render :text => '' and return if params[:userlogin].length > 0
-
@user = User.find_by_login_or_email(params[:user][:login])
+
if @user.nil?
- sleep 2
session[:mail_message] = t(:account_not_found)
else
begin
@user.reset_perishable_token!
- #Mailer.password_reset(@user, "https://www.thingspeak.com/users/reset_password/#{@user.id}?token=#{@user.perishable_token}").deliver
+ # Mailer.password_reset(@user, "https://www.thingspeak.com/users/#{@user.id}/reset_password?token=#{@user.perishable_token}").deliver
session[:mail_message] = t(:password_reset_mailed)
rescue
session[:mail_message] = t(:password_reset_error)
end
end
- redirect_to :controller => 'user_session', :action => 'new'
+ redirect_to login_path
end
end
@@ -8,15 +8,12 @@ def new
end
def create
- # protect against bots
- render :text => '' and return if params[:userlogin].length > 0
-
@user = User.new(params[:user])
# save user
if @user.valid?
if @user.save
- redirect_back_or_default account_path and return
+ redirect_back_or_default account_path
end
else
render :action => :new
@@ -26,25 +23,24 @@ def create
def show
@menu = 'account'
- @user = @current_user
+ @user = current_user
end
def edit
@menu = 'account'
- @user = @current_user
+ @user = current_user
end
# displays forgot password page
def forgot_password
- @user = User.new
end
# this action is called from an email link when a password reset is requested
def reset_password
# if user has been logged in (due to previous form submission)
if !current_user.nil?
@user = current_user
- @user.errors.add_to_base(t(:password_problem))
+ @user.errors.add(t(:password_problem))
@valid_link = true
else
@user = User.find_by_id(params[:id])
@@ -76,13 +72,13 @@ def change_password
def update
@menu = 'account'
- @user = @current_user # makes our views "cleaner" and more consistent
+ @user = current_user # makes our views "cleaner" and more consistent
# check current password and update
if @user.valid_password?(params[:password_current]) && @user.update_attributes(params[:user])
redirect_to account_path
else
- @user.errors.add_to_base(t(:password_incorrect))
- render :action => :edit
+ @user.errors.add :base, t(:password_incorrect)
+ render :edit
end
end
View
@@ -1,7 +1,22 @@
class ApiKey < ActiveRecord::Base
- belongs_to :channel
+ belongs_to :channel
+ belongs_to :user
- validates_uniqueness_of :api_key
+ validates_uniqueness_of :api_key
+
+ scope :write_keys, :conditions => { :write_flag => true }
+ scope :read_keys, :conditions => { :write_flag => false }
+
+ attr_readonly :created_at
+ attr_accessible :note
+
+ def to_s
+ api_key
+ end
+
+ def to_param
+ api_key
+ end
end
View
@@ -1,7 +1,40 @@
class Channel < ActiveRecord::Base
- belongs_to :user
+ include KeyUtilities
+
+ belongs_to :user
has_many :feeds
has_many :api_keys
+
+ attr_readonly :created_at
+ attr_protected :user_id, :last_entry_id
+
+ after_create :set_initial_default_name
+ before_validation :set_default_name
+
+ validates :name, :presence => true, :on => :update
+
+ def add_write_api_key
+ write_key = self.api_keys.new
+ write_key.user = self.user
+ write_key.write_flag = true
+ write_key.api_key = generate_api_key
+ write_key.save
+ end
+
+ def field_label(field_number)
+ self["field#{field_number}"]
+ end
+
+private
+
+ def set_default_name
+ self.name = "#{I18n.t(:channel_default_name)} #{self.id}" if self.name.blank?
+ end
+
+ def set_initial_default_name
+ update_attribute(:name, "#{I18n.t(:channel_default_name)} #{self.id}")
+ end
+
end
View
@@ -1,7 +1,10 @@
class Feed < ActiveRecord::Base
belongs_to :channel
- self.include_root_in_json = false
+ self.include_root_in_json = false
+
+ attr_readonly :created_at
+ attr_protected :channel_id
end
Oops, something went wrong.

0 comments on commit 4f03543

Please sign in to comment.