rails/app/controllers/api/v1/students_controller.rb
class API::V1::StudentsController < API::APIController
# POST api/v1/students
def create
registration = API::V1::StudentRegistration.new(student_registration_strong_params(params))
# This was added to allow for registering after logging in the first time with SSO
# But it also occurs if a user is able to access the registration form while being
# logged in a different window.
if current_user
# If the user has a portal_teacher or portal_student, we don't want them re-registering
# The errors in this case will be passed down to the registration form.
# The use of class_word is so the error message is shown in the form.
if current_user.portal_teacher
return error(class_word: I18n.t('Registration.ErrorLoggedInAsTeacher'))
elsif current_user.portal_student
return error(class_word: I18n.t('Registration.ErrorLoggedInAsStudent'));
else
registration.set_user current_user
end
end
if registration.valid?
registration.save
attributes = registration.attributes
attributes.delete(:password)
attributes.delete(:password_confirmation)
#
# For students, get rid of email address after registration
#
if session['omniauth_email']
session['omniauth_email'] = nil
end
if session[:omniauth_origin]
attributes["omniauth_origin"] = session[:omniauth_origin]
session[:omniauth_origin] = nil
end
render :json => attributes
else
return error(registration.errors)
end
end
# GET api/v1/students/check_class_word
def check_class_word
class_word = params.require(:class_word)
found = Portal::Clazz.find_by_class_word(class_word)
if found
render :json => {'message' => 'ok'}
else
return error({'class_word' => 'class word not found'})
end
end
# POST api/v1/students/:id/check_password
# Why not GET like in check_class_word? We don't want to put password in URL params.
def check_password
student_id = params.require(:id)
password = params.require(:password)
login = Portal::Student.find(student_id).user.login
return render :json => {'message' => 'ok'} if User.authenticate(login, password)
return error({'password' => 'password incorrect'}, 401)
end
def join_class
result = get_portal_clazz_by_word(params)
return error(result[:error]) if result[:error]
portal_clazz = result[:portal_clazz]
if current_visitor.anonymous?
return error("You must be logged in to sign up for a class!")
end
if current_visitor.portal_teacher
return error("You can't signup for a class while logged in as a teacher!")
end
student = current_visitor.portal_student
if !student
grade_level = view_context.find_grade_level(params)
student = Portal::Student.create(:user_id => current_visitor.id, :grade_level_id => grade_level.id)
end
student.process_class_word(params[:class_word])
render_ok
end
# similar to #check_class_word but uses different error message to be consistent with #join_class
def confirm_class_word
result = get_portal_clazz_by_word(params)
if result[:error]
error(result[:error])
else
portal_clazz = result[:portal_clazz]
render :json => { success: true, data: {teacher_name: portal_clazz.teacher.user.name} }, :status => :ok
end
end
def register
result = get_portal_clazz_by_id(params)
return error(result[:error]) if result[:error]
portal_clazz = result[:portal_clazz]
user_attributes = params[:user]
if !user_attributes
return error("Missing user parameters")
end
if user_attributes[:first_name].nil?
return error("Missing user first_name parameter")
end
if user_attributes[:last_name].nil?
return error("Missing user last_name parameter")
end
portal_clazz = result[:portal_clazz]
if !portal_clazz.is_teacher?(current_user)
return error("You must be a teacher of the class to register and add students")
end
grade_level = view_context.find_grade_level(params)
user_attributes[:login] = Portal::Student.generate_user_login(user_attributes[:first_name], user_attributes[:last_name])
user_attributes[:email] = Portal::Student.generate_user_email
user = User.new(user_strong_params(user_attributes))
if !user.valid?
return error(user.errors.full_messages.uniq.join(". ").gsub("..", "."))
end
# temporarily disable sending email notifications for state change events
user.skip_notifications = true
if !user.save
return error("Unable to save newly created user")
end
user.confirm
if current_settings.allow_default_class || grade_level.nil?
portal_student = Portal::Student.create(:user_id => user.id)
else
portal_student = Portal::Student.create(:user_id => user.id, :grade_level_id => grade_level.id)
end
if !portal_student
return error("Unable to create student")
end
if !portal_student.student_clazzes.create(:clazz_id => portal_clazz.id, :student_id => portal_student.id, :start_time => Time.now)
return error("Unable to add student to class")
end
render :json => {
success: true,
data: {
user: {
id: user.id,
login: user.login,
email: user.email
},
student: {
id: portal_student.id
},
clazz: {
id: portal_clazz.id
}
}
}, :status => :ok
end
def add_to_class
result = get_portal_clazz_by_id(params)
return error(result[:error]) if result[:error]
portal_clazz = result[:portal_clazz]
student_id = params[:student_id]
if !student_id
return error("Missing student_id parameter")
end
student = Portal::Student.find_by_id(student_id)
if !student
return error("Invalid student_id: #{student_id}")
end
if !portal_clazz.is_teacher?(current_user)
return error("You must be a teacher of the class to add students")
end
student.add_clazz(portal_clazz)
render_ok
end
def remove_from_class
student_clazz_id = params[:student_clazz_id]
if !student_clazz_id
return error("Missing student_clazz_id parameter")
end
student_clazz = Portal::StudentClazz.find_by_id(student_clazz_id)
if !student_clazz
return error("Invalid student_clazz_id: #{student_clazz_id}")
end
portal_clazz = student_clazz.clazz
if !portal_clazz.is_teacher?(current_user)
return error("You must be a teacher of the class to remove students")
end
student_clazz.destroy
render_ok
end
private
def render_ok
render :json => { success: true }, :status => :ok
end
def get_portal_clazz_by_word(params)
class_word = params[:class_word]
if !class_word
return {error: "Missing class_word parameter"}
end
portal_clazz = Portal::Clazz.find_by_class_word(class_word)
if !portal_clazz
return {error: "The class word you provided, \"#{class_word}\", was not valid! Please check with your teacher to ensure you have the correct word."}
end
return {portal_clazz: portal_clazz}
end
def get_portal_clazz_by_id(params)
clazz_id = params[:clazz_id]
if !clazz_id
return {error: "Missing clazz_id parameter"}
end
portal_clazz = Portal::Clazz.find_by_id(clazz_id)
if !portal_clazz
return {error: "Invalid clazz_id: #{clazz_id}"}
end
return {portal_clazz: portal_clazz}
end
def teacher_of_class?(clazz)
true
end
def user_strong_params(params)
params && params.permit(:first_name, :last_name, :email, :login, :password, :password_confirmation)
end
def student_registration_strong_params(params)
params && params.permit(:first_name, :last_name, :email, :login, :password, :password_confirmation,
:email_subscribed, :sign_up_path, :asked_age, :have_consent, :class_word)
end
end