class ApiBandsController < ApiController before_filter :api_signed_in_user, :except => [:index, :show, :follower_index] before_filter :auth_band_member, :only => [:update, :recording_create, :recording_update, :recording_destroy, :invitation_index, :invitation_show, :invitation_create, :invitation_destroy, :update_photo, :delete_photo, :generate_filepicker_policy] before_filter :auth_band_admin, :only => [:delete] respond_to :json def index @bands = Band.paginate(page: params[:page]) end def show @band = Band.find(params[:id]) respond_with_model(@band) end def delete @band.try(:destroy) respond_with @band, responder => ApiResponder end def create @band = Band.save(current_user, params) respond_with_model(@band, new: true, location: lambda { return api_band_detail_url(@band.id) }) end def update @band = Band.save(current_user, params) respond_with_model(@band) end def validate @band = Band.build_band(current_user, params) @band.valid? respond_with_model(@band) end def musician_index if !params[:pending].blank? @musicians = Band.pending_musicians(params[:id]) else unless params[:id].blank? @musicians = Band.musician_index(params[:id]) else render :json => { :message => "Band ID is required." }, :status => 400 end end end def musician_create end def musician_destroy unless params[:id].blank? || params[:user_id].blank? BandMusician.delete_all "(band_id = '#{params[:id]}' AND user_id = '#{params[:user_id]}' AND admin = 'f')" end render :json => {}, :status => 202 end ###################### FOLLOWERS ######################## def liker_index # NOTE: liker_index.rabl template references the likers property @band = Band.find(params[:id]) end ###################### FOLLOWERS ######################## def follower_index # NOTE: follower_index.rabl template references the followers property @band = Band.find(params[:id]) end ###################### RECORDINGS ####################### def recording_index @recordings = Band.recording_index(current_user, params[:id]) respond_with @recordings, responder: ApiResponder, :status => 200 end def recording_show hide_private = false band = Band.find(params[:id]) # hide private Recordings from anyone who's not in the Band unless band.users.exists? current_user hide_private = true end @recording = Recording.find(params[:recording_id]) if !@recording.public && hide_private render :json => { :message => "You are not allowed to access this recording." }, :status => 403 #respond_with "You are not allowed to view this recording.", responder: ApiResponder, :status => 403 else respond_with @recording, responder: ApiResponder, :status => 200 end end def recording_create @recording = Recording.save(params[:recording_id], params[:public], params[:description], params[:genres], current_user.id, params[:id], true) respond_with @recording, responder: ApiResponder, :status => 201, :location => api_band_recording_detail_url(@band, @recording) end def recording_update @recording = Recording.save(params[:recording_id], params[:public], params[:description], params[:genres], current_user.id, params[:id], false) respond_with @recording, responder: ApiResponder, :status => 200 end def recording_destroy @recording = Recording.find(params[:recording_id]) unless @recording.nil? @recording.delete respond_with responder: ApiResponder, :status => 204 end # no recording was found with this ID render :json => { :message => ValidationMessages::RECORDING_NOT_FOUND }, :status => 404 end ###################### INVITATIONS ###################### def invitation_index @invitations = @band.invitations respond_with @invitations, responder: ApiResponder, :status => 200 end def invitation_show begin @invitation = BandInvitation.find(params[:invitation_id]) respond_with @invitation, responder: ApiResponder, :status => 200 rescue ActiveRecord::RecordNotFound render :json => { :message => ValidationMessages::BAND_INVITATION_NOT_FOUND }, :status => 404 end end def invitation_create unless Band.is_member?(params[:id], params[:user_id]) @invitation = BandInvitation.save(nil, params[:id], params[:user_id], current_user.id, params[:accepted]) end respond_with @invitation, responder: ApiResponder, :status => 201 # respond_with @invitation, responder: ApiResponder, :status => 201, :location => api_band_invitation_detail_url(@band, @invitation) end def invitation_update if params[:resend] @invitation = BandInvitation.save(params[:invitation_id], nil, nil, nil, false, true) else @invitation = BandInvitation.save(params[:invitation_id], nil, nil, nil, params[:accepted]) end end def invitation_destroy begin @invitation = BandInvitation.find(params[:invitation_id]) @invitation.delete respond_with responder: ApiResponder, :status => 204 rescue ActiveRecord::RecordNotFound render :json => { :message => ValidationMessages::BAND_INVITATION_NOT_FOUND }, :status => 404 end end def update_photo original_fpfile = params[:original_fpfile] cropped_fpfile = params[:cropped_fpfile] cropped_large_fpfile = params[:cropped_large_fpfile] crop_selection = params[:crop_selection] # public bucket to allow images to be available to public @band.update_photo(original_fpfile, cropped_fpfile, cropped_large_fpfile, crop_selection, Rails.application.config.aws_bucket_public) if @band.errors.any? render :json => { :message => "Unexpected error updating photo."}, :status => :unprocessable_entity else render :json => {}, :status => :ok end end def delete_photo @band.delete_photo(Rails.application.config.aws_bucket_public) if @band.errors.any? render :json => { :message => "Unexpected error deleting photo."}, :status => :unprocessable_entity else render :json => {}, :status => :ok end end def generate_filepicker_policy # generates a soon-expiring filepicker policy so that a band can only upload to their own folder in their bucket handle = params[:handle] call = 'pick,convert,store' policy = { :expiry => (DateTime.now + 5.minutes).to_i(), :call => call #:path => 'avatars/' + @band.id + '/.*jpg' } # if the caller specifies a handle, add it to the hash unless handle.nil? start = handle.rindex('/') + 1 policy[:handle] = handle[start..-1] end policy = Base64.urlsafe_encode64( policy.to_json ) digest = OpenSSL::Digest.new('sha256') signature = OpenSSL::HMAC.hexdigest(digest, Rails.application.config.fp_secret, policy) render :json => { :signature => signature, :policy => policy }, :status => :ok end ############################################################################# protected # ensures user is a member of the band def auth_band_member @band = Band.find(params[:id]) unless @band.users.exists? current_user Rails.logger.info("Could not find #{current_user} in #{@band.users.inspect}") raise JamPermissionError, ValidationMessages::PERMISSION_VALIDATION_ERROR end end def auth_band_admin uid = current_user.id @band = Band.find(params[:id]) unless @band.band_musicians.detect { |bm| bm.user_id == uid && bm.admin? } Rails.logger.info("Could not find #{current_user} in #{@band.band_musicians.inspect}") raise JamPermissionError, ValidationMessages::PERMISSION_VALIDATION_ERROR end end end