diff --git a/admin/app/admin/ars.rb b/admin/app/admin/ars.rb index e150e4401..0b8c4def0 100644 --- a/admin/app/admin/ars.rb +++ b/admin/app/admin/ars.rb @@ -2,4 +2,29 @@ ActiveAdmin.register JamRuby::Ars, :as => 'Ars' do menu :label => 'NAS', :parent => 'Operations' + + form do |f| + f.inputs 'Controls' do + f.input :active + f.input :beta + end + f.inputs 'Meta' do + f.input :name + f.input :provider + f.input :id_int + f.input :ip + f.input :username + f.input :password, as: :string + f.input :port + f.input :continent + f.input :country, as: :string + f.input :city + f.input :subdivision + f.input :latitude + f.input :longitude + end + f.actions + end + + end diff --git a/admin/app/admin/dashboard.rb b/admin/app/admin/dashboard.rb index e4c5ff6db..d5d4af4a9 100644 --- a/admin/app/admin/dashboard.rb +++ b/admin/app/admin/dashboard.rb @@ -8,11 +8,9 @@ ActiveAdmin.register_page "Dashboard" do span "JamKazam Administration Portal" small ul do li link_to "Users", admin_users_path + li link_to "K12 Users", admin_users_path("q[import_source_equals]": "K12") li link_to "Teachers", admin_teachers_path - li link_to "Onboarding Management", admin_onboarder_managements_path - li link_to "Onboarding Settings", admin_onboarders_path - li link_to "Lesson Sessions", admin_lesson_sessions_path - li link_to "Slow Lesson Responses", admin_slow_responses_path + li link_to "Upload School Users", admin_schooluseruploads_path end end diff --git a/admin/app/admin/jam_ruby_users.rb b/admin/app/admin/jam_ruby_users.rb index 38c61b7da..a71f1f13e 100644 --- a/admin/app/admin/jam_ruby_users.rb +++ b/admin/app/admin/jam_ruby_users.rb @@ -11,6 +11,7 @@ ActiveAdmin.register JamRuby::User, :as => 'Users' do filter :jamuser_full_name_or_email_cont, label: 'Name Or Email', as: :string filter :created_at filter :updated_at + filter :import_source includes :purchased_jam_tracks, :jam_track_rights => :jam_track, :taken_lessons => :music_session, :taught_lessons => :music_session @@ -22,6 +23,19 @@ ActiveAdmin.register JamRuby::User, :as => 'Users' do end + member_action :quick_reset, :method => :get do + resetting_to = 'jellyandjam123' + resource.change_password(resetting_to, resetting_to) + resource.save + redirect_to :back, {notice: "Reset password to #{resetting_to }"} + end + + member_action :create_reset, :method => :get do + reset_url = resource.create_tokened_reset_url + redirect_to :back, {notice: "Reset password url created: #{reset_url}"} + end + + show do |user| panel "Common" do @@ -73,6 +87,25 @@ ActiveAdmin.register JamRuby::User, :as => 'Users' do end end + row "Quick Password Reset" do |user| + span do + link_to("Reset Password to jellyandjam123", quick_reset_admin_user_path(user.id), :data => {:confirm => 'Reset password to jellyandjam123 ?'}) + end + end + + row "Send Password Reset Email" do |user| + span do + Rails.application.config.external_root_url + "/request_reset_password" + end + end + + row "Password Reset URL" do |user| + span do + link_to("Create Reset URL", create_reset_admin_user_path(user.id), :data => {:confirm => 'Are you sure?'}) + end + end + + row :jamclass_credits row :via_amazon row "Web Profile" do @@ -267,6 +300,7 @@ ActiveAdmin.register JamRuby::User, :as => 'Users' do @user.last_name = params[:jam_ruby_user][:last_name] @user.state = params[:jam_ruby_user][:state] @user.city = params[:jam_ruby_user][:city] + @user.is_platform_instructor = params[:jam_ruby_user][:is_platform_instructor] @user.gifted_jamtracks = params[:jam_ruby_user][:gifted_jamtracks] diff --git a/admin/app/admin/school_user_uploads.rb b/admin/app/admin/school_user_uploads.rb new file mode 100644 index 000000000..30ed6c6c6 --- /dev/null +++ b/admin/app/admin/school_user_uploads.rb @@ -0,0 +1,76 @@ +ActiveAdmin.register_page "SchoolUserUploads" do + + menu :label => 'School User Upload', :parent => 'Misc' + + page_action :upload_schooluseruploads, :method => :post do + User.transaction do + + puts params + + file = params[:jam_ruby_user][:csv] + + + created = 0 + already_existing = 0 + array_of_arrays = CSV.read(file.tempfile.path, headers:true, encoding: 'bom|utf-8') + array_of_arrays.each do |row| + school_name = row['School Name'] + school_tag = row['School ID'] + school = School.autocreate_find_from_upload(school_name, school_tag) + first_name = row['First Name'] + last_name = row['Last Name'] + email_address = row['Email Address'] + license_start = parse_date(row['License Start Date']) + license_end = parse_date(row['License End Date']) + source = row['Source'] + password = SecureRandom.uuid + options = { + first_name: first_name, + last_name: last_name, + email: email_address, + license_start: license_start, + license_end: license_end, + import_source: source, + school_id: school.id, + terms_of_service: true, + musician: true, + skip_recaptcha: true, + password: password, + password_confirmation: password + } + + parse_user_type(row['User Type'], options) + + instrument = Instrument.find('electric guitar') + instruments= [{instrument_id: instrument.id, proficiency_level: 3, priority: 1}] + options[:instruments] = instruments + user = User.signup(options) + + if user.errors.any? + puts "User #{user.name} #{user.email} had errors" + puts user.errors.inspect + already_existing = already_existing + 1 + else + puts "User #{user.email} created" + created = created + 1 + end + end + + redirect_to admin_schooluseruploads_path, :notice => "Created #{created} school students. Ignored #{already_existing} because already existed." + end + end + + content do + panel "Help" do + link_to "Download Sample CSV", asset_path("Sample_School_User_Upload.csv", target: "_blank", download: "Sample_School_User_Upload.csv") + end + + active_admin_form_for User.new, :url => admin_schooluseruploads_upload_schooluseruploads_path, :builder => ActiveAdmin::FormBuilder do |f| + f.inputs "Upload School Users" do + f.input :csv, as: :file, required: true, :label => "A school user upload" + end + f.actions + end + end +end + diff --git a/admin/app/assets/csvs/Sample_School_User_Upload.csv b/admin/app/assets/csvs/Sample_School_User_Upload.csv new file mode 100644 index 000000000..be9022424 --- /dev/null +++ b/admin/app/assets/csvs/Sample_School_User_Upload.csv @@ -0,0 +1 @@ +First Name,Last Name,Email Address,User Type,School ID,School Name,License Start Date,License End Date,Source Student,Student,seth+student1@jamkazam.com,Student,school_a,School A,1/1/20,1/1/21,K12 Student,Expired,seth+student2@jamkazam.com,Student,school_a,School A,1/2/19,1/1/20,K12 Teacher,Teacher,seth+teacher1@jamkazam.com,Student Instructor,school_a,School A,1/1/20,1/1/21,K12 Platform,Instructor,seth+platform1@jamkazam.com,Platform Instructor,school_a,School A,1/1/20,1/2/21,K12 \ No newline at end of file diff --git a/admin/app/controllers/arses_controller.rb b/admin/app/controllers/arses_controller.rb index 9e1559d35..82d73c2f1 100644 --- a/admin/app/controllers/arses_controller.rb +++ b/admin/app/controllers/arses_controller.rb @@ -10,8 +10,13 @@ class ArsesController < ApplicationController ip = params[:ip] username = params[:username] password = params[:password] + topology = params[:topology] + ars_id = params[:ars_id] + puts "TOPOLOGY #{topology}" - ars = Ars.find_by_name(name) + if ars_id + ars = Ars.find_by_id_int(ars_id) + end if ars.nil? ars = Ars.new ars.name = name @@ -22,6 +27,14 @@ class ArsesController < ApplicationController ars.ip = ip ars.password = password ars.username = username + if topology + ars.city = topology['city'] + ars.country = topology['country'] + ars.continent = topology['continent'] + ars.latitude = topology['latitude'] + ars.longitude = topology['longitude'] + ars.subdivision = topology['subdivision'] + end ars.save @ars = ars diff --git a/admin/app/helpers/application_helper.rb b/admin/app/helpers/application_helper.rb index 6e9385e59..c1545e10f 100644 --- a/admin/app/helpers/application_helper.rb +++ b/admin/app/helpers/application_helper.rb @@ -1,4 +1,43 @@ module ApplicationHelper + def parse_user_type(user_type, options) + if user_type == 'Student' + options[:student] = true + elsif user_type == 'Student Instructor' + options[:teacher] = true + elsif user_type == 'Platform Instructor' + options[:platform_instructor] = true + else + raise JamRuby::JamPermissionError, "Unknown user type #{user_type}" + end + end + + def parse_date(date) + delimiter = '/' + bits = date.split(delimiter) + + if bits.length != 3 + delimiter = '-' + bits = date.split(delimiter) + end + + if bits.length != 3 + raise JamRuby::JamPermissionError, "date #{date} has no '-' or '/'" + end + + if bits[2].length == 4 || (bits[0].length != 4 && bits[2].to_i > 12) # excel likes to do 1/1/20. So if last + if bits[2].length == 2 + # prepend year + + date = [bits[0], bits[1], '20' + bits[2]].join(delimiter) + end + Date.strptime(date, "%m#{delimiter}%d#{delimiter}%Y") + else + Date.strptime(date, "%Y#{delimiter}%m#{delimiter}%d") + end + + end + + end diff --git a/admin/app/views/admin/users/_form.html.slim b/admin/app/views/admin/users/_form.html.slim index df29c3115..adae73563 100644 --- a/admin/app/views/admin/users/_form.html.slim +++ b/admin/app/views/admin/users/_form.html.slim @@ -4,6 +4,7 @@ = f.input :admin = f.input :is_onboarder, label: 'Is Support Consultant' = f.input :subscribe_email, label: 'Subscribed to Emails?' + = f.input :is_platform_instructor, label: 'Is Platform Instructor?' = f.input :gifted_jamtracks, label: 'JamTrack Credits' = f.input :first_name = f.input :last_name diff --git a/admin/bin/start b/admin/bin/start new file mode 100755 index 000000000..39d09d1be --- /dev/null +++ b/admin/bin/start @@ -0,0 +1,3 @@ +#!/bin/bash + +bundle exec rails s -b 127.0.0.1 diff --git a/admin/config/application.rb b/admin/config/application.rb index 9e89690ac..cffb75506 100644 --- a/admin/config/application.rb +++ b/admin/config/application.rb @@ -37,6 +37,7 @@ module JamAdmin # Activate observers that should always be running. config.active_record.observers = "JamRuby::InvitedUserObserver" + config.assets.paths << "#{Rails.root}/app/assets/csvs" config.assets.prefix = "#{ENV['RAILS_RELATIVE_URL_ROOT']}/assets" # Set Time.zone default to the specified zone and make Active Record auto-convert to this zone. @@ -116,14 +117,16 @@ module JamAdmin config.email_social_alias = 'social@jamkazam.com' config.email_alerts_alias = 'alerts@jamkazam.com' # should be used for 'oh no' server down/service down sorts of emails config.email_generic_from = 'nobody@jamkazam.com' - config.email_smtp_address = 'smtp.sendgrid.net' + config.email_smtp_address = 'email-smtp.us-east-1.amazonaws.com' config.email_smtp_port = 587 config.email_smtp_domain = 'www.jamkazam.com' config.email_smtp_authentication = :plain - config.email_smtp_user_name = 'jamkazam' - config.email_smtp_password = 'snorkeltoesniffyfarce1' + config.email_smtp_user_name = 'AKIA2SXEHOQFKRW3OWMG' # ses-smtp-user.20200526-212148 + config.email_smtp_password = 'BJZEdTkTcuIrN1koG40PQ2JLHdMmTprC/aLj48Q5KhWJ' config.email_smtp_starttls_auto = true + config.verify_email_enabled = false + config.musician_count = '200,000+' config.facebook_app_id = ENV['FACEBOOK_APP_ID'] || '468555793186398' config.facebook_app_secret = ENV['FACEBOOK_APP_SECRET'] || '546a5b253972f3e2e8b36d9a3dd5a06e' diff --git a/admin/config/initializers/jam_ruby_ars.rb b/admin/config/initializers/jam_ruby_ars.rb new file mode 100644 index 000000000..2fe51d24c --- /dev/null +++ b/admin/config/initializers/jam_ruby_ars.rb @@ -0,0 +1,5 @@ +class JamRuby::Ars + + attr_accessible :password, :username, :active, :beta, :name, :provider, :id_int, :ip, :port, :continent, :country, :city, :subdivision, :latitude, :longitude, as: :admin + +end diff --git a/admin/config/initializers/jam_ruby_user.rb b/admin/config/initializers/jam_ruby_user.rb index 8b27e88a8..b6e0ca6e5 100644 --- a/admin/config/initializers/jam_ruby_user.rb +++ b/admin/config/initializers/jam_ruby_user.rb @@ -1,6 +1,6 @@ class JamRuby::User - attr_accessible :admin, :raw_password, :musician, :can_invite, :photo_url, :session_settings, :confirm_url, :teacher_attributes, :email_template # :invite_email + attr_accessible :admin, :raw_password, :musician, :can_invite, :photo_url, :session_settings, :confirm_url, :teacher_attributes, :email_template, :is_platform_instructor # :invite_email accepts_nested_attributes_for :teacher, allow_destroy: true diff --git a/db/up/find_sessions_2020.sql b/db/up/find_sessions_2020.sql index f95fe61b2..895f03624 100644 --- a/db/up/find_sessions_2020.sql +++ b/db/up/find_sessions_2020.sql @@ -58,11 +58,44 @@ ALTER TABLE arses ADD COLUMN beta BOOLEAN default FALSE; ALTER TABLE generic_state ADD COLUMN event_page_top_logo_url VARCHAR(100000) DEFAULT '/assets/event/eventbrite-logo.png'; +ALTER TABLE schools ADD CONSTRAINT schools_name_uniqkey UNIQUE (name); +ALTER TABLE schools ADD COLUMN school_tag VARCHAR(100) UNIQUE; +ALTER TABLE active_music_sessions ADD COLUMN school_id INT; +ALTER TABLE active_music_sessions ADD COLUMN is_platform_instructor BOOLEAN NOT NULL DEFAULT FALSE; +ALTER TABLE active_music_sessions ADD CONSTRAINT active_music_sessions_school_id_fkey FOREIGN KEY (school_id) REFERENCES schools(id); +ALTER TABLE music_sessions ADD COLUMN school_id INT; +ALTER TABLE music_sessions ADD CONSTRAINT music_sessions_school_id_fkey FOREIGN KEY (school_id) REFERENCES schools(id); +ALTER TABLE music_sessions ADD COLUMN is_platform_instructor BOOLEAN NOT NULL DEFAULT FALSE; +ALTER TABLE recordings ADD COLUMN school_id INT; +ALTER TABLE recordings ADD COLUMN is_platform_instructor BOOLEAN NOT NULL DEFAULT FALSE; +ALTER TABLE feeds ADD COLUMN school_id INT; +ALTER TABLE feeds ADD COLUMN is_platform_instructor BOOLEAN NOT NULL DEFAULT FALSE; +ALTER TABLE users ADD COLUMN is_platform_instructor BOOLEAN NOT NULL DEFAULT FALSE; +ALTER TABLE users ADD COLUMN import_source varchar(50); +ALTER TABLE users ADD COLUMN license_start date; +ALTER TABLE users ADD COLUMN license_end date; + + +CREATE INDEX users_is_a_student_idx ON users((1)) WHERE is_a_student; +CREATE INDEX users_is_a_teacher_idx ON users((1)) WHERE is_a_teacher; +CREATE INDEX users_is_platform_instructor_idx ON users((1)) WHERE is_platform_instructor; +CREATE INDEX ams_is_platform_instructor_idx ON active_music_sessions((1)) WHERE is_platform_instructor; +CREATE INDEX sms_is_platform_instructor_idx ON music_sessions((1)) WHERE is_platform_instructor; +CREATE INDEX users_schood_id_idx ON users USING btree (school_id); +CREATE INDEX feeds_schood_id_idx ON feeds USING btree (school_id); +CREATE INDEX feeds_is_platform_instructor_idx ON feeds((1)) WHERE is_platform_instructor; + +ALTER TABLE arses ADD COLUMN country VARCHAR(200); +ALTER TABLE arses ADD COLUMN city VARCHAR(200); +ALTER TABLE arses ADD COLUMN latitude NUMERIC(15,10); +ALTER TABLE arses ADD COLUMN longitude NUMERIC(15,10); +ALTER TABLE arses ADD COLUMN subdivision VARCHAR(200); +ALTER TABLE arses ADD COLUMN continent VARCHAR(200); + + ALTER TABLE users ADD COLUMN recurly_subscription_id VARCHAR(100) DEFAULT NULL; ALTER TABLE users ADD COLUMN recurly_token VARCHAR(200) DEFAULT NULL; ALTER TABLE users ADD COLUMN recurly_subscription_state VARCHAR(20) DEFAULT NULL; - - CREATE TABLE subscriptions ( id VARCHAR(64) PRIMARY KEY DEFAULT uuid_generate_v4(), name VARCHAR(200) UNIQUE NOT NULL UNIQUE NOT NULL, @@ -79,4 +112,4 @@ CREATE TABLE subscriptions ( max_players_per_session INT DEFAULT NULL, created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP -); \ No newline at end of file +); diff --git a/pb/src/client_container.proto b/pb/src/client_container.proto index db747dac8..0eb19091a 100644 --- a/pb/src/client_container.proto +++ b/pb/src/client_container.proto @@ -816,6 +816,12 @@ message Ars { optional string username = 4; optional string password = 5; optional int32 port = 6; + optional string country = 7; + optional string continent = 8; + optional string subdivision = 9; + optional double latitude = 10; + optional double longitude = 11; + optional string city = 12; } // target: client diff --git a/ruby/lib/jam_ruby/app/mailers/user_mailer.rb b/ruby/lib/jam_ruby/app/mailers/user_mailer.rb index daa048f00..1d23e2a63 100644 --- a/ruby/lib/jam_ruby/app/mailers/user_mailer.rb +++ b/ruby/lib/jam_ruby/app/mailers/user_mailer.rb @@ -35,8 +35,9 @@ module JamRuby end end - def welcome_message(user) + def welcome_message(user, reset_url = nil) @user = user + @reset_url = reset_url sendgrid_category "Welcome" sendgrid_unique_args :type => "welcome_message" @@ -218,6 +219,25 @@ module JamRuby end end + def school_welcome_message(user, reset_url) + @user = user + @subject= "Set a password on your new JamKazam account for your #{user.school.name} music program" + @school = user.school + @reset_url = reset_url + + sendgrid_category "Welcome" + sendgrid_unique_args :type => "welcome_message" + + sendgrid_recipients([user.email]) + sendgrid_substitute('@USERID', [user.id]) + sendgrid_substitute(EmailBatchProgression::VAR_FIRST_NAME, [user.first_name]) + + mail(:to => user.email, :subject => @subject) do |format| + format.text + format.html + end + end + def teacher_welcome_message(user) @user = user @subject= "Welcome to JamKazam and JamClass online lessons!" diff --git a/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/school_welcome_message.html.erb b/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/school_welcome_message.html.erb new file mode 100644 index 000000000..db1bf29cf --- /dev/null +++ b/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/school_welcome_message.html.erb @@ -0,0 +1,46 @@ +<% provide(:title, @subject) %> + + +<% if !@user.anonymous? %> +
Hello <%= @vars[EmailBatch::VAR_FIRST_NAME] %> -- +
+<% end %> + ++ Your school <%= @school.name %> has set up a JamKazam account for you, + so that you can participate in an online music education program through your school. + JamKazam is an application and a platform that lets you play music with other students over the Internet, live and in sync. + You can also use JamKazam to play and record yourself on your own. +
+ ++ To use the JamKazam app, you will need to sign in to the app using an email address and a password. + The email address is the one to which this email was sent. + Click the button below to set a password for your JamKazam account. + If you're worried this is a scam, please check with your school or music program instructor to verify that this is a legitimate email. +
+ ++ + Set Password + +
++ Your instructor will help you to start using the JamKazam app in your music program with other students. + If you already have your gear and want to set it up and start playing around with it, + you can check out our summary setup instructions + https://jamkazam.freshdesk.com/support/solutions/articles/66000259828 + and also learn about the features you can use to create, join, and play in online music sessions + https://jamkazam.freshdesk.com/support/solutions/66000073845. +
++ We hope you enjoy playing music on the JamKazam platform! If you run into trouble, please use this page to ask for help + https://jamkazam.freshdesk.com/support/tickets/new. +
+ + +Best Regards,
+ Team JamKazam
+ Your account was imported for you, so you'll need to set a password. + Click the button below to set a password for your JamKazam account. +
++ + Set Password + +
+For Playing Music Together Live & In Sync From Different Locations
JamKazam's Mac and Windows desktop apps let musicians play together live and in sync with
high-quality audio from different locations over the Internet, with an amazing feature set for
diff --git a/ruby/lib/jam_ruby/connection_manager.rb b/ruby/lib/jam_ruby/connection_manager.rb
index 02b1d0845..384110fa6 100644
--- a/ruby/lib/jam_ruby/connection_manager.rb
+++ b/ruby/lib/jam_ruby/connection_manager.rb
@@ -353,19 +353,22 @@ SQL
end
def update_session_controller(music_session_id)
+ tracks_changed = false
active_music_session = ActiveMusicSession.find(music_session_id)
if active_music_session
music_session = active_music_session.music_session
if music_session.session_controller_id && !active_music_session.users.exists?(music_session.session_controller.id)
# find next in line, because the current 'session controller' is not part of the session
- next_in_line(music_session, active_music_session)
+ tracks_changed = next_in_line(music_session, active_music_session)
end
end
+ tracks_changed
end
# determine who should be session controller after someone leaves
def next_in_line(music_session, active_music_session)
+ tracks_changed = false
session_users = active_music_session.users
# check friends 1st
@@ -374,7 +377,7 @@ SQL
music_session.session_controller = session_friends[0]
if music_session.save
active_music_session.tick_track_changes
- Notification.send_tracks_changed(active_music_session)
+ tracks_changed = true
return
end
end
@@ -385,7 +388,7 @@ SQL
music_session.session_controller = invited[0]
if music_session.save
active_music_session.tick_track_changes
- Notification.send_tracks_changed(active_music_session)
+ tracks_changed = true
return
end
end
@@ -397,16 +400,17 @@ SQL
music_session.session_controller = earliest
if music_session.save
active_music_session.tick_track_changes
- Notification.send_tracks_changed(active_music_session)
+ tracks_changed = true
return
end
end
- music_session.creator
+ tracks_changed
end
def join_music_session(user, client_id, music_session, as_musician, tracks, audio_latency, client_role = nil, parent_client_id = nil, video_sources=nil)
connection = nil
+ tracks_changed = false
ConnectionManager.active_record_transaction do |connection_manager|
db_conn = connection_manager.pg_conn
@@ -432,11 +436,15 @@ SQL
if connection.errors.any?
raise ActiveRecord::Rollback
else
- update_session_controller(music_session.id)
+ tracks_changed = update_session_controller(music_session.id)
end
end
+ if tracks_changed
+ Notification.send_tracks_changed(music_session.active_music_session)
+ end
+
connection
end
@@ -444,6 +452,7 @@ SQL
# if a blk is passed in, upon success, it will be called and you can issue notifications
# within the connection table lock
def leave_music_session(user, connection, music_session, &blk)
+ send_tracks_changed = false
ConnectionManager.active_record_transaction do |connection_manager|
conn = connection_manager.pg_conn
@@ -469,7 +478,7 @@ SQL
if result.cmd_tuples == 1
@log.debug("disassociated music_session with connection for client_id=#{client_id}, user_id=#{user_id}")
- update_session_controller(music_session.id)
+ send_tracks_changed = update_session_controller(music_session.id)
JamRuby::MusicSessionUserHistory.removed_music_session(user_id, music_session_id)
session_checks(conn, previous_music_session_id, user_id)
@@ -484,6 +493,10 @@ SQL
end
end
end
+
+ if send_tracks_changed
+ Notification.send_tracks_changed(music_session.active_music_session)
+ end
end
def lock_connections(conn)
diff --git a/ruby/lib/jam_ruby/constants/validation_messages.rb b/ruby/lib/jam_ruby/constants/validation_messages.rb
index da90d06cd..7dbaf3bb4 100644
--- a/ruby/lib/jam_ruby/constants/validation_messages.rb
+++ b/ruby/lib/jam_ruby/constants/validation_messages.rb
@@ -62,6 +62,17 @@ module ValidationMessages
FANS_CAN_NOT_JOIN = "Fans can not join this session"
CANT_JOIN_RECORDING_SESSION = "is currently recording"
CANT_JOIN_MULTIPLE_SESSIONS = 'You cannot join more than one music session'
+ CANT_JOIN_SCHOOL_SESSION = "You can not join school sessions"
+ CAN_ONLY_JOIN_SAME_SCHOOL_SESSION = "You can only join sessions from your school"
+ LICENSE_EXPIRED = "Your license has expired"
+ LICENSE_NOT_STARTED = "Your license has not started"
+
+ # chat
+ CAN_ONLY_CHAT_SAME_SCHOOL = "You can only message others from your school"
+ DISABLED_GLOBAL_SCHOOL_CHAT = "Global chat disabled for schools"
+
+ # permissions
+ CAN_ONLY_VIEW_SAME_SCHOOL = "You can only view other users from your school"
# recordings
ALREADY_BEING_RECORDED = "already being recorded"
diff --git a/ruby/lib/jam_ruby/message_factory.rb b/ruby/lib/jam_ruby/message_factory.rb
index 687a0fba1..f4d9844ec 100644
--- a/ruby/lib/jam_ruby/message_factory.rb
+++ b/ruby/lib/jam_ruby/message_factory.rb
@@ -68,8 +68,23 @@ module JamRuby
)
end
+ def ars_body(ars)
+ Jampb::Ars.new(
+ :id => ars.id_int,
+ :ip => ars.ip,
+ :username => ars.username,
+ :password => ars.password,
+ :port => ars.port,
+ :country => ars.country,
+ :continent => ars.continent,
+ :city => ars.city,
+ :subdivision => ars.subdivision,
+ :latitude => ars.latitude,
+ :longitude => ars.longitude
+ )
+ end
# create a login ack (login was successful)
- def login_ack(public_ip, client_id, token, heartbeat_interval, music_session_id, reconnected, user_id, connection_expire_time, username, client_id_int, client_update_data = nil, ars_list = nil)
+ def login_ack(public_ip, client_id, token, heartbeat_interval, music_session_id, reconnected, user_id, connection_expire_time, username, client_id_int, client_update_data = nil, arses = [])
client_update = Jampb::ClientUpdate.new(
product: client_update_data[:product],
version: client_update_data[:version],
@@ -77,18 +92,6 @@ module JamRuby
size: client_update_data[:size]
) if client_update_data
- arses = []
-
- ars_list.each do |ars|
- arses << Jampb::Ars.new(
- :id => ars.id_int,
- :ip => ars.ip,
- :username => ars.username,
- :password => ars.password,
- :port => ars.port
- )
- end if ars_list
-
login_ack = Jampb::LoginAck.new(
:public_ip => public_ip,
diff --git a/ruby/lib/jam_ruby/models/active_music_session.rb b/ruby/lib/jam_ruby/models/active_music_session.rb
index 32545b48b..489cc3e8a 100644
--- a/ruby/lib/jam_ruby/models/active_music_session.rb
+++ b/ruby/lib/jam_ruby/models/active_music_session.rb
@@ -199,6 +199,8 @@ module JamRuby
}
)
+ query = Search.scope_schools_together_sessions(query, user)
+
if as_musician
query = query.where(
%Q{
@@ -302,7 +304,7 @@ module JamRuby
end
# all sessions that are private and active, yet I can see
- def self.public_index(user, options)
+ def self.public_index(user, options)
session_id = options[:session_id]
genre = options[:genre]
@@ -317,6 +319,7 @@ module JamRuby
query = query.where("musician_access = TRUE")
+ query = Search.scope_schools_together_sessions(query, user)
# if not specified, default offset to 0
offset ||= 0
@@ -416,6 +419,8 @@ module JamRuby
}
)
+ query = Search.scope_schools_together_sessions(query, user)
+
query = query.offset(offset) if offset
query = query.limit(limit) if limit
@@ -607,6 +612,7 @@ module JamRuby
active_music_session.with_lock do # VRFS-1297
active_music_session.tick_track_changes
+ Notification.send_tracks_changed(active_music_session)
# VRFS-3986
connection = ConnectionManager.new.join_music_session(user, client_id, active_music_session, as_musician, tracks, audio_latency, client_role, parent_client_id, video_sources)
@@ -654,6 +660,8 @@ module JamRuby
active_music_session = ActiveMusicSession.new
active_music_session.id = music_session.id # copy the .id from music_session to active_music_session
active_music_session.creator = user
+ active_music_session.school_id = user.school_id
+ active_music_session.is_platform_instructor = user.is_platform_instructor
if music_session.fan_access
# create an icecast mount since regular users can listen in to the broadcast
@@ -873,6 +881,8 @@ module JamRuby
feed.music_session_id = self.id
end
+ feed.school_id = self.school_id
+ feed.is_platform_instructor = self.is_platform_instructor
feed.active = true
feed.save
diff --git a/ruby/lib/jam_ruby/models/chat_message.rb b/ruby/lib/jam_ruby/models/chat_message.rb
index 478962532..07baa73f0 100644
--- a/ruby/lib/jam_ruby/models/chat_message.rb
+++ b/ruby/lib/jam_ruby/models/chat_message.rb
@@ -24,6 +24,25 @@ module JamRuby
validates :user, presence: true
validates :message, length: {minimum: 1, maximum: 255}, no_profanity: true, unless: :ignore_message_checks
+ validate :same_school_protection
+ validate :no_global_for_schools
+
+ def no_global_for_schools
+ if self.channel == 'global' && user && !user.school_id.nil?
+ errors.add(:user, ValidationMessages::DISABLED_GLOBAL_SCHOOL_CHAT)
+ end
+ end
+
+ def same_school_protection
+ if user && target_user
+ if !user.is_platform_instructor && !target_user.is_platform_instructor
+ if user.school_id != target_user.school_id
+ errors.add(:target_user, ValidationMessages::CAN_ONLY_CHAT_SAME_SCHOOL)
+ end
+ end
+ end
+ end
+
def self.create(user, music_session, message, channel, client_id, target_user = nil, lesson_session = nil, purpose = nil, music_notation = nil, recording = nil)
source_user = user
@@ -88,6 +107,11 @@ module JamRuby
@@message_factory = MessageFactory.new
def index(user, params = {})
+ # TODO: school user scan't see chat
+ if params[:channel] == 'global' && !user.school_id.nil?
+ return [[], nil]
+ end
+
limit = params[:limit]
limit ||= 20
limit = limit.to_i
diff --git a/ruby/lib/jam_ruby/models/connection.rb b/ruby/lib/jam_ruby/models/connection.rb
index d8136a486..3481e99b1 100644
--- a/ruby/lib/jam_ruby/models/connection.rb
+++ b/ruby/lib/jam_ruby/models/connection.rb
@@ -108,6 +108,7 @@ module JamRuby
return false
end
+
if as_musician
unless self.user.musician
errors.add(:as_musician, ValidationMessages::FAN_CAN_NOT_JOIN_AS_MUSICIAN)
@@ -148,6 +149,23 @@ module JamRuby
errors.add(:music_session, ValidationMessages::CANT_JOIN_RECORDING_SESSION)
end
+ # same logic as Search.scope_schools_together_sessions
+ if !self.user.is_platform_instructor
+ if self.user.school_id.nil? && !music_session.school_id.nil?
+ errors.add(:music_session, ValidationMessages::CANT_JOIN_SCHOOL_SESSION)
+ elsif !self.user.school_id.nil? && (self.user.school_id != music_session.school_id)
+ errors.add(:music_session, ValidationMessages::CAN_ONLY_JOIN_SAME_SCHOOL_SESSION)
+ end
+ end
+
+ if self.user.license_expired?
+ errors.add(:music_session, ValidationMessages::LICENSE_EXPIRED)
+ end
+
+ if self.user.license_not_started?
+ errors.add(:music_session, ValidationMessages::LICENSE_NOT_STARTED)
+ end
+
# unless user.admin?
# num_sessions = Connection.where(:user_id => user_id)
# .where(["(music_session_id IS NOT NULL) AND (aasm_state != ?)",EXPIRED_STATE.to_s])
diff --git a/ruby/lib/jam_ruby/models/feed.rb b/ruby/lib/jam_ruby/models/feed.rb
index 89d522aae..befdc900a 100644
--- a/ruby/lib/jam_ruby/models/feed.rb
+++ b/ruby/lib/jam_ruby/models/feed.rb
@@ -37,6 +37,8 @@ module JamRuby
.limit(limit)
.where('feeds.recording_id is NULL OR (recordings.all_discarded = false AND recordings.deleted = false)') # remove any 'all_discarded recordings from the search results' or 'deleted'
+ query = Search.scope_schools_together_feeds(query, user)
+
# handle sort
if sort == 'date'
query = query.order('feeds.id DESC')
diff --git a/ruby/lib/jam_ruby/models/friend_request.rb b/ruby/lib/jam_ruby/models/friend_request.rb
index 3b6d930a7..f6b57a42b 100644
--- a/ruby/lib/jam_ruby/models/friend_request.rb
+++ b/ruby/lib/jam_ruby/models/friend_request.rb
@@ -15,6 +15,25 @@ module JamRuby
#validates :status, :inclusion => {:in => STATUS}
validates :message, no_profanity: true
+ validate :same_school_protection
+
+ def same_school_protection
+ if self.user_id && self.user.nil?
+ self.user = User.find(user_id)
+ end
+ if self.friend_id && self.friend.nil?
+ self.friend = User.find(friend_id)
+ end
+
+ if self.user && self.friend
+ if !self.user.is_platform_instructor && !self.friend.is_platform_instructor
+ if self.user.school_id != self.friend.school_id
+ errors.add(:friend, ValidationMessages::CAN_ONLY_CHAT_SAME_SCHOOL)
+ end
+ end
+ end
+ end
+
def to_s
"#{self.id} => #{self.user.to_s}:#{self.friend.to_s}"
end
@@ -32,10 +51,11 @@ module JamRuby
friend_request.user_id = user_id
friend_request.friend_id = friend_id
friend_request.message = message
- friend_request.save
+ if friend_request.save
+ # send notification
+ Notification.send_friend_request(friend_request.id, user_id, friend_id) unless supress_initial
+ end
- # send notification
- Notification.send_friend_request(friend_request.id, user_id, friend_id) unless supress_initial
else
ActiveRecord::Base.transaction do
@@ -52,10 +72,10 @@ module JamRuby
# create both records for this friendship
if friend_request.status == "accept"
- Friendship.save(friend_request.user_id, friend_request.friend_id)
-
- # send notification
- Notification.send_friend_request_accepted(friend_request.user_id, friend_request.friend_id)
+ if Friendship.save(friend_request.user_id, friend_request.friend_id)
+ # send notification
+ Notification.send_friend_request_accepted(friend_request.user_id, friend_request.friend_id)
+ end
end
end
end
diff --git a/ruby/lib/jam_ruby/models/music_session.rb b/ruby/lib/jam_ruby/models/music_session.rb
index d3744553c..96f8ca7a5 100644
--- a/ruby/lib/jam_ruby/models/music_session.rb
+++ b/ruby/lib/jam_ruby/models/music_session.rb
@@ -346,6 +346,8 @@ module JamRuby
new_session.is_unstructured_rsvp = self.is_unstructured_rsvp
new_session.legal_terms = true
new_session.session_controller = self.session_controller
+ new_session.school_id = self.school_id
+ new_session.is_platform_instructor = self.is_platform_instructor
# copy rsvp_slots, rsvp_requests, and rsvp_requests_rsvp_slots
RsvpSlot.where("music_session_id = '#{self.id}'").find_each do |slot|
@@ -602,6 +604,8 @@ module JamRuby
#query = query.where("music_sessions.user_id = '#{user.id}' OR invitations.id IS NOT NULL")
query = query.where("(rsvp_requests.id IS NOT NULL AND rsvp_requests_rsvp_slots.id IS NOT NULL AND rsvp_requests.user_id = '#{user.id}' AND rsvp_requests_rsvp_slots.chosen = true) OR (invitations.id IS NOT NULL) OR (music_sessions.user_id = '#{user.id}') ")
+ query = Search.scope_schools_together_sessions(query, user, 'music_sessions')
+
query = query.where("music_sessions.scheduled_start IS NULL OR #{session_not_started} OR #{session_finished} OR #{session_started_not_finished}")
query = query.where("music_sessions.create_type IS NULL OR (music_sessions.create_type != '#{CREATE_TYPE_QUICK_START}' AND music_sessions.create_type != '#{CREATE_TYPE_QUICK_PUBLIC}')")
query = query.order("music_sessions.scheduled_start ASC")
@@ -630,6 +634,8 @@ module JamRuby
}
)
+ query = Search.scope_schools_together_sessions(query, user, 'music_sessions')
+
query = query.where(%Q{music_sessions.old = FALSE AND music_sessions.canceled = FALSE AND
(music_sessions.create_type is NULL OR (music_sessions.create_type != '#{CREATE_TYPE_QUICK_START}' AND music_sessions.create_type != '#{CREATE_TYPE_QUICK_PUBLIC}')) AND
(music_sessions.scheduled_start is NULL OR music_sessions.scheduled_start > NOW() - '4 hour'::INTERVAL) AND rsvp_requests.user_id = '#{user.id}' #{filter_approved}}
@@ -663,6 +669,8 @@ module JamRuby
ms.is_unstructured_rsvp = options[:isUnstructuredRsvp] if options[:isUnstructuredRsvp]
ms.scheduled_start = parse_scheduled_start(options[:start], options[:timezone]) if options[:start] && options[:timezone]
ms.scheduled_start = options[:scheduled_start] if options[:scheduled_start]
+ ms.school_id = user.school_id
+ ms.is_platform_instructor = user.is_platform_instructor
if options[:lesson_session]
ms.lesson_session = options[:lesson_session]
end
@@ -1167,6 +1175,7 @@ SQL
# keep only rsvp/invitation/friend results. Nice tailored active list now!
query = query.where("open_rsvps = TRUE OR rsvp_requests.id IS NOT NULL OR invitations.id IS NOT NULL or music_sessions.user_id = '#{user.id}' OR (friendships.id IS NOT NULL AND friendships_2.id IS NOT NULL)")
+ query = Search.scope_schools_together_sessions(query, user, 'music_sessions')
# if not specified, default offset to 0
offset ||= 0
diff --git a/ruby/lib/jam_ruby/models/musician_search.rb b/ruby/lib/jam_ruby/models/musician_search.rb
index f11e36e20..1071f95a5 100644
--- a/ruby/lib/jam_ruby/models/musician_search.rb
+++ b/ruby/lib/jam_ruby/models/musician_search.rb
@@ -145,6 +145,7 @@ module JamRuby
def do_search(params={})
rel = User.musicians.where('users.id <> ?', self.user.id)
+ rel = Search.scope_schools_together(rel, self.user)
rel = self._genres(rel)
rel = self._ages(rel)
rel = self._studios(rel)
diff --git a/ruby/lib/jam_ruby/models/notification.rb b/ruby/lib/jam_ruby/models/notification.rb
index e0bb97fff..182d6ddb9 100644
--- a/ruby/lib/jam_ruby/models/notification.rb
+++ b/ruby/lib/jam_ruby/models/notification.rb
@@ -20,6 +20,16 @@ module JamRuby
validates :target_user, :presence => true
validates :message, length: {minimum: 1, maximum: 400}, no_profanity: true, if: :text_message?
validate :different_source_target, if: :text_message?
+ validate :same_school_protection
+ def same_school_protection
+ if source_user && target_user
+ if !source_user.is_platform_instructor && !target_user.is_platform_instructor
+ if source_user.school_id != target_user.school_id
+ errors.add(:target_user, ValidationMessages::CAN_ONLY_CHAT_SAME_SCHOOL)
+ end
+ end
+ end
+ end
def different_source_target
unless target_user_id.nil? || source_user_id.nil?
diff --git a/ruby/lib/jam_ruby/models/recording.rb b/ruby/lib/jam_ruby/models/recording.rb
index 23e92e063..926144983 100644
--- a/ruby/lib/jam_ruby/models/recording.rb
+++ b/ruby/lib/jam_ruby/models/recording.rb
@@ -44,6 +44,8 @@ module JamRuby
def add_to_feed
feed = Feed.new
feed.recording = self
+ feed.is_platform_instructor = self.is_platform_instructor
+ feed.school_id = self.school_id
end
def sanitize_active_admin
@@ -226,6 +228,8 @@ module JamRuby
recording = Recording.new
recording.music_session = nil
recording.owner = owner
+ recording.school_id = owner.school_id
+ recording.is_platform_instructor = owner.is_platform_instructor
recording.band = nil
recording.immediate = true # immediate in practice means 'the ios app uploaded this'
recording.video = params[:record_video]
@@ -268,6 +272,8 @@ module JamRuby
recording.music_session = music_session
recording.owner = owner
recording.band = music_session.band
+ recording.school_id = owner.school_id
+ recording.is_platform_instructor = owner.is_platform_instructor
recording.video = record_video == true || record_video == 'true'
if recording.save
diff --git a/ruby/lib/jam_ruby/models/school.rb b/ruby/lib/jam_ruby/models/school.rb
index 6a9f32bbd..86b5b9e2c 100644
--- a/ruby/lib/jam_ruby/models/school.rb
+++ b/ruby/lib/jam_ruby/models/school.rb
@@ -33,6 +33,22 @@ module JamRuby
after_create :create_affiliate
#before_save :stringify_avatar_info, :if => :updating_avatar
+ def self.autocreate_find_from_upload(school_name, school_tag)
+ if school_name.blank?
+ return nil
+ end
+
+ school = School.find_by_name(school_name)
+ if school.nil?
+ school = School.new
+ school.name = school_name
+ school.user = User.find_by_email('seth@jamkazam.com')
+ school.school_tag = school_tag
+ school.education = true
+ school.save!
+ end
+ school
+ end
def is_education?
education
end
diff --git a/ruby/lib/jam_ruby/models/search.rb b/ruby/lib/jam_ruby/models/search.rb
index 0fa2e28b8..132addef4 100644
--- a/ruby/lib/jam_ruby/models/search.rb
+++ b/ruby/lib/jam_ruby/models/search.rb
@@ -84,7 +84,8 @@ module JamRuby
User.musicians
end
@results = rel.where("(name_tsv @@ to_tsquery('jamenglish', ?))", tsquery).limit(10)
- @results
+
+ @results = Search.scope_schools_together(@results, user)
end
class << self
@@ -114,6 +115,73 @@ module JamRuby
srch
end
+ def scope_schools_together_feeds(rel, user)
+ if user.nil?
+ return rel.where("feeds.school_id is null")
+ end
+
+ # platform instructors can search anybody (non-school and school). So no nothing special for them.
+
+ if !user.is_platform_instructor
+ # for everyone else...
+ # make sure you can only see same-school. Or in the case of 'null school', you'll get other non-schoolers (i.e. normies)
+ # also, make sure anyone will find platform_instructors
+ if user.school_id.nil?
+ rel = rel.where("feeds.school_id is null")
+ else
+ rel = rel.where("feeds.school_id = #{user.school_id} OR feeds.is_platform_instructor")
+ end
+ end
+
+ rel
+ end
+
+ def scope_schools_together_chats(rel, user)
+ # TODO:
+ return rel
+ end
+
+
+ def scope_schools_together_sessions(rel, user, table_name = 'active_music_sessions')
+ if user.nil?
+ return rel.where("#{table_name}.school_id is null")
+ end
+ # platform instructors can search anybody (non-school and school). So no nothing special for them.
+
+ if !user.is_platform_instructor
+ # for everyone else...
+ # make sure you can only see same-school. Or in the case of 'null school', you'll get other non-schoolers (i.e. normies)
+ # also, make sure anyone will find platform_instructors
+ if user.school_id.nil?
+ rel = rel.where("#{table_name}.school_id is null")
+ else
+ rel = rel.where("#{table_name}.school_id = #{user.school_id} OR #{table_name}.is_platform_instructor")
+ end
+ end
+
+ rel
+ end
+
+ def scope_schools_together(rel, user)
+ if user.nil?
+ return rel.where("school_id is null")
+ end
+ # platform instructors can search anybody (non-school and school). So no nothing special for them.
+
+ if !user.is_platform_instructor
+ # for everyone else...
+ # make sure you can only see same-school. Or in the case of 'null school', you'll get other non-schoolers (i.e. normies)
+ # also, make sure anyone will find platform_instructors
+ if user.school_id.nil?
+ rel = rel.where("school_id is null")
+ else
+ rel = rel.where("school_id = #{user.school_id} OR is_platform_instructor")
+ end
+ end
+
+ rel
+ end
+
def text_search(params, user = nil)
srch = Search.new
unless (params.blank? || params[:query].blank? || 2 > params[:query].length)
@@ -171,6 +239,8 @@ module JamRuby
.where(['minst.instrument_id = ?', instrument])
end
+ rel = scope_schools_together(rel, user)
+
# to find appropriate musicians we need to join users with scores to get to those with no scores or bad scores
# weeded out
diff --git a/ruby/lib/jam_ruby/models/text_message.rb b/ruby/lib/jam_ruby/models/text_message.rb
index ca6d8b7bc..549182751 100644
--- a/ruby/lib/jam_ruby/models/text_message.rb
+++ b/ruby/lib/jam_ruby/models/text_message.rb
@@ -12,6 +12,17 @@ module JamRuby
belongs_to :target_user, :class_name => "JamRuby::User", :foreign_key => "target_user_id"
belongs_to :source_user, :class_name => "JamRuby::User", :foreign_key => "source_user_id"
+ validate :same_school_protection
+ def same_school_protection
+ if source_user && target_user
+ if !source_user.is_platform_instructor && !target_user.is_platform_instructor
+ if source_user.school_id != target_user.school_id
+ errors.add(:target_user, ValidationMessages::CAN_ONLY_CHAT_SAME_SCHOOL)
+ end
+ end
+ end
+ end
+
validates :message, length: {minimum: 1, maximum: 400}, no_profanity: true
def self.index(target_user_id, source_user_id, options = {})
diff --git a/ruby/lib/jam_ruby/models/user.rb b/ruby/lib/jam_ruby/models/user.rb
index 99bc0aa4b..f86bf186b 100644
--- a/ruby/lib/jam_ruby/models/user.rb
+++ b/ruby/lib/jam_ruby/models/user.rb
@@ -718,6 +718,16 @@ module JamRuby
self.birth_date.nil? ? nil : now.year - self.birth_date.year - (self.birth_date.to_date.change(:year => now.year) > now ? 1 : 0)
end
+ # has the user's license started? only valid if they have a license
+ def license_not_started?
+ license_start && Time.now < license_start
+ end
+
+ # has the user's license ended? Only valid if they have a license
+ def license_expired?
+ license_end && Time.now > license_end
+ end
+
def session_count
0
#MusicSession.where("user_id = ? AND started_at IS NOT NULL", self.id).size
@@ -957,8 +967,14 @@ module JamRuby
if user.reset_password_token != token
raise JamRuby::JamArgumentError.new("Invalid reset token", "token")
end
- if Time.now - user.reset_password_token_created > 3.days
- raise JamRuby::JamArgumentError.new("Password reset has expired", "token")
+ if user.import_source
+ if Time.now - user.reset_password_token_created > 180.days
+ raise JamRuby::JamArgumentError.new("Password reset has expired", "token")
+ end
+ else
+ if Time.now - user.reset_password_token_created > 3.days
+ raise JamRuby::JamArgumentError.new("Password reset has expired", "token")
+ end
end
if new_password.nil? || new_password == ""
raise JamRuby::JamArgumentError.new("Password is empty", "password")
@@ -997,6 +1013,13 @@ module JamRuby
user
end
+ def create_tokened_reset_url
+ self.reset_password_token = SecureRandom.urlsafe_base64
+ self.reset_password_token_created = Time.now
+ self.save
+ "#{APP_CONFIG.external_root_url}/reset_password_token?token=#{self.reset_password_token}&email=#{CGI.escape(email)}"
+ end
+
def self.band_index(user_id)
bands = Band.joins(:band_musicians)
.where(:bands_musicians => {:user_id => "#{user_id}"})
@@ -1422,6 +1445,10 @@ module JamRuby
test_drive_package_details = options[:test_drive_package]
under_13 = options[:under_13]
timezone = options[:timezone]
+ platform_instructor = options[:platform_instructor]
+ license_start = options[:license_start]
+ license_end = options[:license_end]
+ import_source = options[:import_source]
test_drive_package = TestDrivePackage.find_by_name(test_drive_package_details[:name]) if test_drive_package_details
@@ -1429,7 +1456,7 @@ module JamRuby
retailer = School.find(retailer_id) if retailer_id
user = User.new
user.validate_instruments = true
- UserManager.active_record_transaction do |user_manager|
+ User.transaction do
if school_invitation_code
school_invitation = SchoolInvitation.find_by_invitation_code(school_invitation_code)
@@ -1454,7 +1481,12 @@ module JamRuby
user.first_name = first_name if first_name.present?
user.last_name = last_name if last_name.present?
user.email = email
- user.subscribe_email = true
+ user.import_source = import_source
+ user.email_confirmed = !user.import_source.nil?
+ user.subscribe_email = import_source.nil?
+ user.license_start = license_start
+ user.license_end = license_end
+ user.is_platform_instructor = !!platform_instructor
user.terms_of_service = terms_of_service
user.reuse_card unless reuse_card.nil?
user.gifted_jamtracks = 0
@@ -1490,6 +1522,7 @@ module JamRuby
user.affiliate_referral = school.affiliate_partner
elsif user.is_a_teacher
school = School.find_by_id(school_id)
+ user.school_id = school_id
user.teacher = Teacher.build_teacher(user, validate_introduction: true, biography: "Empty biography", school_id: school_id)
user.affiliate_referral = school.affiliate_partner
end
@@ -1530,7 +1563,7 @@ module JamRuby
# user.country = location[:country]
user.birth_date = birth_date
- if musician
+ if musician && location
user.last_jam_addr = location[:addr]
user.last_jam_locidispid = location[:locidispid]
user.last_jam_updated_reason = JAM_REASON_REGISTRATION
@@ -1709,7 +1742,12 @@ module JamRuby
user.handle_test_drive_package(test_drive_package, test_drive_package_details) if test_drive_package
- if user.is_a_student
+ reset_url = nil
+ if user.import_source
+ reset_url = user.create_tokened_reset_url
+ end
+
+ if import_source.nil? && user.is_a_student
#if school && school.education
# UserMailer.student_education_welcome_message(user).deliver_now
#else
@@ -1734,8 +1772,20 @@ module JamRuby
#end
+ elsif user.is_a_student
+ if user.import_source
+ UserMailer.school_welcome_message(user, reset_url).deliver_now
+ else
+ UserMailer.student_welcome_message(user).deliver_now
+ end
elsif user.is_a_teacher
- UserMailer.teacher_welcome_message(user).deliver_now
+ if user.import_source
+ UserMailer.school_welcome_message(user, reset_url).deliver_now
+ else
+ UserMailer.teacher_welcome_message(user).deliver_now
+ end
+ elsif user.is_platform_instructor
+ UserMailer.welcome_message(user, reset_url).deliver_now
elsif user.education_interest
UserMailer.education_owner_welcome_message(user).deliver_now
elsif user.school_interest
diff --git a/web/app/assets/javascripts/react-components/FindSessionRow.js.jsx.coffee b/web/app/assets/javascripts/react-components/FindSessionRow.js.jsx.coffee
index fea2b82f2..312ffb2ac 100644
--- a/web/app/assets/javascripts/react-components/FindSessionRow.js.jsx.coffee
+++ b/web/app/assets/javascripts/react-components/FindSessionRow.js.jsx.coffee
@@ -8,8 +8,6 @@ MAX_MINUTES_SHOW_START = 15
@FindSessionRow = React.createClass({
- mixins: [Reflux.listenTo(AppStore, "onAppInit")]
-
ui: null
getInitialState: () ->
@@ -354,7 +352,7 @@ MAX_MINUTES_SHOW_START = 15
context.JK.SessionUtils.joinSession(sessionId)
joinLinkClicked: (session) ->
- context.JK.SessionUtils.ensureValidClient(@app, context.JK.GearUtils, @ensuredCallback.bind(this, session.id))
+ context.JK.SessionUtils.ensureValidClient(AppStore.app, context.JK.GearUtils, @ensuredCallback.bind(this, session.id))
rsvpLinkClicked: (session) ->
@ui.launchRsvpSubmitDialog(session.id)
diff --git a/web/app/assets/stylesheets/client/createSession.scss b/web/app/assets/stylesheets/client/createSession.scss
index 9e1a33cfd..4a0fbed0d 100644
--- a/web/app/assets/stylesheets/client/createSession.scss
+++ b/web/app/assets/stylesheets/client/createSession.scss
@@ -84,7 +84,7 @@
}
}
.learn-more-sessions-header {
- margin-top:40px;
+ margin-top:25px;
}
.learn-more-sessions {
a {
diff --git a/web/app/controllers/api_controller.rb b/web/app/controllers/api_controller.rb
index 9b3328527..cef52b25b 100644
--- a/web/app/controllers/api_controller.rb
+++ b/web/app/controllers/api_controller.rb
@@ -90,6 +90,18 @@ class ApiController < ApplicationController
@user = User.find(params[:id])
end
+ def guard_school_same_scope(user, target)
+ if !user || !target
+ return true
+ end
+ if !user.is_platform_instructor && !target.is_platform_instructor
+ return user.school_id == target.school_id
+ else
+ return true
+ end
+
+ end
+
def optional_auth_user
if current_user.nil?
@user = nil
diff --git a/web/app/controllers/api_music_sessions_controller.rb b/web/app/controllers/api_music_sessions_controller.rb
index 2a52877d5..37bb21c52 100644
--- a/web/app/controllers/api_music_sessions_controller.rb
+++ b/web/app/controllers/api_music_sessions_controller.rb
@@ -147,6 +147,8 @@ class ApiMusicSessionsController < ApiController
history.language = 'eng'
history.legal_policy = 'standard'
history.creator = current_user
+ history.school_id = current_user.school_id
+ history.is_platform_instructor = current_user.is_platform_instructor
history.save
if history.errors.any?
diff --git a/web/app/controllers/api_users_controller.rb b/web/app/controllers/api_users_controller.rb
index 166561ecc..d3b2fcc6b 100644
--- a/web/app/controllers/api_users_controller.rb
+++ b/web/app/controllers/api_users_controller.rb
@@ -60,6 +60,10 @@ class ApiUsersController < ApiController
end
def profile_show
+ if !guard_school_same_scope(current_user, User.find(params[:id]))
+ raise JamPermissionError, ValidationMessages::CAN_ONLY_VIEW_SAME_SCHOOL
+ end
+
@profile = User.includes([{musician_instruments: :instrument},
{band_musicians: :user},
{genre_players: :genre},
diff --git a/web/app/views/api_users/show.rabl b/web/app/views/api_users/show.rabl
index 9d221345c..45bd49a7c 100644
--- a/web/app/views/api_users/show.rabl
+++ b/web/app/views/api_users/show.rabl
@@ -64,7 +64,7 @@ if current_user && @user == current_user
node :show_jamtrack_guide do |user|
!user.first_played_jamtrack_at && user.jam_track_rights.count > 0
end
-
+
node :mods do |user|
user.mods_json
end
diff --git a/web/app/views/clients/_scheduledSession.html.erb b/web/app/views/clients/_scheduledSession.html.erb
index 54be5bf29..4cf0b4928 100644
--- a/web/app/views/clients/_scheduledSession.html.erb
+++ b/web/app/views/clients/_scheduledSession.html.erb
@@ -24,10 +24,10 @@