Skip to content
This repository was archived by the owner on Aug 3, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 15 additions & 21 deletions app.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@
require 'json'
require 'jwt'

require_relative 'helpers/init'
require_relative 'routes/init'
require_relative 'models/init'
require_relative './models/init'
require_relative './routes/init'
require_relative './helpers/init'

class GrootRecruiterService < Sinatra::Base
register Sinatra::AuthsRoutes
Expand All @@ -38,40 +38,34 @@ class GrootRecruiterService < Sinatra::Base
enable :logging
end

configure :development do
enable :unsecure

db = Config.load_config("development")
DataMapper::Logger.new($stdout, :debug)
configure :development, :production do
db = Config.load_config("database")
DataMapper.setup(
:default,
"mysql://" + db["user"] + ":" + db["password"] + "@" + db["hostname"]+ "/" + db["name"]
)
use BetterErrors::Middleware

# you need to set the application root in order to abbreviate filenames
# within the application:
BetterErrors.application_root = File.expand_path('..', __FILE__)
DataMapper.auto_upgrade!
end

configure :test do
db = Config.load_config("test")
db = Config.load_config("test_database")
DataMapper.setup(
:default,
"mysql://" + db["user"] + ":" + db["password"] + "@" + db["hostname"]+ "/" + db["name"]
)
end

configure :development do
enable :unsecure

DataMapper::Logger.new($stdout, :debug)
use BetterErrors::Middleware

BetterErrors.application_root = File.expand_path('..', __FILE__)
DataMapper.auto_upgrade!
end

configure :production do
disable :unsecure

db = Config.load_config("production")
DataMapper.setup(
:default,
"mysql://" + db["user"] + ":" + db["password"] + "@" + db["hostname"]+ "/" + db["name"]
)
end

DataMapper.finalize
Expand Down
11 changes: 0 additions & 11 deletions config/database.yaml.template

This file was deleted.

6 changes: 3 additions & 3 deletions config/secrets.yaml.template
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,13 @@ groot:
jwt:
secret: 'SECRET_JWT_TOKEN'

development:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

perhaps make it development_db and test_db since there is no filename context now

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 resolved

database:
user: root
password: ""
hostname: localhost
name: groot_recruiter_service_dev
name: groot_recruiter_service

test:
test_database:
user: root
password: ""
hostname: localhost
Expand Down
23 changes: 11 additions & 12 deletions helpers/auth.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,9 @@
require 'pry'

module Auth
VERIFY_CORPORATE_URL = '/groups/committees/corporate?isMember='
VERIFY_COMMITTEE_URL = '/groups/committees/'
VALIDATE_SESSION_URL = '/session/'

def self.verify_request(request)
Config.load_config("groot")["request_key"] == request['HTTP_AUTHORIZATION']
end

def self.services_url
Config.load_config("groot")["host"]
end
Expand All @@ -26,17 +22,16 @@ def self.groot_access_key
end

# Verifies that an admin (defined by groups service) originated this request
def self.verify_corporate(request)
def self.verify_credentials(type, request)
netid = request['HTTP_NETID']

uri = URI.parse("#{Auth.services_url}#{VERIFY_CORPORATE_URL}#{netid}")
uri = URI.parse("#{Auth.services_url}#{VERIFY_COMMITTEE_URL}#{type}?isMember=#{netid}")
http = Net::HTTP.new(uri.host, uri.port)
request = Net::HTTP::Get.new(uri.request_uri)
request['Authorization'] = self.groot_access_key
request['Authorization'] = Auth.groot_access_key

response = http.request(request)
return false unless response.code == "200"
JSON.parse(response.body)["isValid"]
return response.code == "200"
end

# Verifies that the session (validated by users service) is active
Expand All @@ -61,7 +56,11 @@ def self.verify_session(request)
JSON.parse(response.body)["token"] == session_token
end

def self.verify_corporate_session(request)
self.verify_session(request) && self.verify_corporate(request)
def self.verify_admin_session(request)
self.verify_session(request) && (
self.verify_credentials('admin', request) ||
self.verify_credentials('top4', request) ||
self.verify_credentials('corporate', request)
)
end
end
1 change: 0 additions & 1 deletion helpers/config.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
# The Groot Project is open source software, released under the University of
# Illinois/NCSA Open Source License. You should have received a copy of
# this license in a file with the distribution.
require 'yaml'

module Config
def self.load_config(section)
Expand Down
3 changes: 1 addition & 2 deletions helpers/errors.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,7 @@ module Errors
ACCOUNT_EXPIRED = ResponseFormat.error "Your account has expired! Please reach out to [email protected] so that your account can be renewed!"
DUPLICATE_ACCOUNT = ResponseFormat.error "An account with these credentials already exists."

VERIFY_CORPORATE_SESSION = ResponseFormat.error "Corporate session could not be verified"
VERIFY_GROOT = ResponseFormat.error "Request did not originate from groot"
VERIFY_ADMIN_SESSION = ResponseFormat.error "Corporate session could not be verified"

FUTURE_DATE = ResponseFormat.error "You entered a date from the future"
INVALID_DATE = ResponseFormat.error "Date was not in a readable format"
Expand Down
8 changes: 2 additions & 6 deletions routes/auth.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,21 +12,17 @@ def self.registered(app)
app.set port: 4567
app.set bind: '0.0.0.0'

app.before do
halt(401, Errors::VERIFY_GROOT) unless Auth.verify_request(env) || GrootRecruiterService.unsecure
end

app.get '/status' do
ResponseFormat.message("OK")
end

app.get '/status/corporate' do
halt(403, Errors::VERIFY_CORPORATE_SESSION) unless Auth.verify_corporate(env)
halt(403, Errors::VERIFY_ADMIN_SESSION) unless Auth.verify_corporate(env)
ResponseFormat.message("OK")
end

app.get '/status/session' do
halt(403, Errors::VERIFY_CORPORATE_SESSION) unless Auth.verify_session(env)
halt(403, Errors::VERIFY_ADMIN_SESSION) unless Auth.verify_session(env)
ResponseFormat.message("OK")
end

Expand Down
4 changes: 2 additions & 2 deletions routes/jobs.rb
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ def self.registered(app)
end

app.put '/jobs/:job_id/approve' do
halt(400, Errors::VERIFY_CORPORATE_SESSION) unless Auth.verify_corporate_session(env)
halt(400, Errors::VERIFY_ADMIN_SESSION) unless Auth.verify_admin_session(env)

status, error = Job.validate(params, [:job_id])
halt(status, ResponseFormat.error(error)) if error
Expand All @@ -51,7 +51,7 @@ def self.registered(app)
end

app.delete '/jobs/:job_id' do
halt(400, Errors::VERIFY_CORPORATE_SESSION) unless Auth.verify_corporate_session(env)
halt(400, Errors::VERIFY_ADMIN_SESSION) unless Auth.verify_admin_session(env)

status, error = Job.validate(params, [:job_id])
halt(status, ResponseFormat.error(error)) if error
Expand Down
18 changes: 9 additions & 9 deletions routes/recruiters.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ module Sinatra
module RecruitersRoutes
def self.registered(app)
app.get '/recruiters' do
halt 401, Errors::VERIFY_CORPORATE_SESSION unless Auth.verify_corporate_session(env)
halt 401, Errors::VERIFY_ADMIN_SESSION unless Auth.verify_admin_session(env)

conditions = {}.tap do |conditions|
conditions[:type] = params[:type] if params[:type] && Recruiter.validate(params, [:type])
Expand Down Expand Up @@ -49,7 +49,7 @@ def self.registered(app)
end

app.post '/recruiters' do
halt 401, Errors::VERIFY_CORPORATE_SESSION unless Auth.verify_corporate_session(env)
halt 401, Errors::VERIFY_ADMIN_SESSION unless Auth.verify_admin_session(env)

params = ResponseFormat.get_params(request.body.read)

Expand Down Expand Up @@ -83,14 +83,14 @@ def self.registered(app)
end

app.get '/recruiters/:recruiter_id' do
halt 401, Errors::VERIFY_CORPORATE_SESSION unless Auth.verify_corporate_session(env)
halt 401, Errors::VERIFY_ADMIN_SESSION unless Auth.verify_admin_session(env)

recruiter = Recruiter.get(params[:recruiter_id]) || halt(404, Errors::RECRUITER_NOT_FOUND)
ResponseFormat.data(recruiter)
end

app.put '/recruiters/:recruiter_id' do
halt 401, Errors::VERIFY_CORPORATE_SESSION unless Auth.verify_corporate_session(env)
halt 401, Errors::VERIFY_ADMIN_SESSION unless Auth.verify_admin_session(env)

recruiter_id = params[:recruiter_id]
params = ResponseFormat.get_params(request.body.read)
Expand Down Expand Up @@ -138,7 +138,7 @@ def self.registered(app)
end

app.get '/recruiters/:recruiter_id/invite' do
halt 401, Errors::VERIFY_CORPORATE_SESSION unless Auth.verify_corporate_session(env)
halt 401, Errors::VERIFY_ADMIN_SESSION unless Auth.verify_admin_session(env)

recruiter = Recruiter.get(params[:recruiter_id])
halt 404, Errors::RECRUITER_NOT_FOUND unless recruiter
Expand All @@ -155,7 +155,7 @@ def self.registered(app)
end

app.post '/recruiters/:recruiter_id/invite' do
halt 401, Errors::VERIFY_CORPORATE_SESSION unless Auth.verify_corporate_session(env)
halt 401, Errors::VERIFY_ADMIN_SESSION unless Auth.verify_admin_session(env)

recruiter_id = params[:recruiter_id]
params = ResponseFormat.get_params(request.body.read)
Expand All @@ -176,7 +176,7 @@ def self.registered(app)
end

app.put '/recruiters/:recruiter_id/renew' do
halt 401, Errors::VERIFY_CORPORATE_SESSION unless Auth.verify_corporate_session(env)
halt 401, Errors::VERIFY_ADMIN_SESSION unless Auth.verify_admin_session(env)

recruiter = Recruiter.get(params[:recruiter_id])
halt 404, Errors::RECRUITER_NOT_FOUND unless recruiter
Expand All @@ -187,14 +187,14 @@ def self.registered(app)
end

app.post '/recruiters/reset' do
halt 401, Errors::VERIFY_CORPORATE_SESSION unless Auth.verify_corporate_session(env)
halt 401, Errors::VERIFY_ADMIN_SESSION unless Auth.verify_admin_session(env)

Recruiter.update(invited: false)
ResponseFormat.message("Reset all recruiter invitations. You can now invite recruiters to fairs again")
end

app.delete '/recruiters/:recruiter_id' do
halt(400, Errors::VERIFY_CORPORATE_SESSION) unless Auth.verify_corporate_session(env)
halt(400, Errors::VERIFY_ADMIN_SESSION) unless Auth.verify_admin_session(env)

recruiter = Recruiter.get(params[:recruiter_id])
halt 404, Errors::RECRUITER_NOT_FOUND unless recruiter
Expand Down
8 changes: 4 additions & 4 deletions routes/students.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ module StudentsRoutes
def self.registered(app)
app.get '/students' do
payload = JWTAuth.decode(env)
halt 401, Errors::VERIFY_CORPORATE_SESSION unless Auth.verify_corporate_session(env) || (payload[:code] == 200)
halt 401, Errors::VERIFY_ADMIN_SESSION unless Auth.verify_admin_session(env) || (payload[:code] == 200)

graduation_start_date = Date.parse(params[:graduationStart]) rescue nil
graduation_end_date = Date.parse(params[:graduationEnd]) rescue nil
Expand Down Expand Up @@ -78,7 +78,7 @@ def self.registered(app)
end

app.put '/students/:netid/approve' do
halt 401, Errors::VERIFY_CORPORATE_SESSION unless Auth.verify_corporate_session(env)
halt 401, Errors::VERIFY_ADMIN_SESSION unless Auth.verify_admin_session(env)

status, error = Student.validate(params, [:netid])
halt status, ResponseFormat.error(error) if error
Expand All @@ -98,7 +98,7 @@ def self.registered(app)
end

app.delete '/students/:netid' do
halt 401, Errors::VERIFY_CORPORATE_SESSION unless Auth.verify_corporate_session(env)
halt 401, Errors::VERIFY_ADMIN_SESSION unless Auth.verify_admin_session(env)

student = Student.first(netid: params[:netid]) || halt(404, Errors::STUDENT_NOT_FOUND)
AWS.delete_resume(student.netid, student.resume_url)
Expand All @@ -108,7 +108,7 @@ def self.registered(app)
end

app.post '/students/remind' do
halt 401, Errors::VERIFY_CORPORATE_SESSION unless Auth.verify_corporate_session(env)
halt 401, Errors::VERIFY_ADMIN_SESSION unless Auth.verify_admin_session(env)
params = ResponseFormat.get_params(request.body.read)

status, error = Student.validate(params, [:email, :last_updated_at])
Expand Down
8 changes: 0 additions & 8 deletions spec/helpers/auth_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,6 @@
.to receive(:request)
.and_return(double(code: "200", body: {token: token, isValid: 'true' }.to_json))
end

describe 'self.verify_request' do
it 'should verify the token on the header' do
get "/status", {}, { "HTTP_AUTHORIZATION" => "#{token}" }

expect(last_response).to be_ok
end
end

describe 'self.verify_corporate' do
it 'should make a post request to the right service' do
Expand Down
11 changes: 5 additions & 6 deletions spec/routes/jobs_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@

RSpec.describe Sinatra::JobsRoutes do
before :each do
expect(Auth).to receive(:verify_request).and_return(true)
allow(Auth).to receive(:verify_corporate_session).and_return(true)
allow(Auth).to receive(:verify_admin_session).and_return(true)
end

def match_job(datum, job)
Expand Down Expand Up @@ -99,12 +98,12 @@ def match_job(datum, job)

describe "PUT /jobs/:job_id/approve" do
it 'should not allow a non-corporate user to access this route' do
allow(Auth).to receive(:verify_corporate_session).and_return(false)
allow(Auth).to receive(:verify_admin_session).and_return(false)

put "/jobs/#{job.id}/approve"
expect(last_response).not_to be_ok
json_data = JSON.parse(last_response.body)
expect_error(json_data, Errors::VERIFY_CORPORATE_SESSION)
expect_error(json_data, Errors::VERIFY_ADMIN_SESSION)
end

it 'should approve an unapproved job' do
Expand Down Expand Up @@ -133,12 +132,12 @@ def match_job(datum, job)

describe "DELETE /jobs/:job_id" do
it 'should not allow a non-corporate user to access this route' do
allow(Auth).to receive(:verify_corporate_session).and_return(false)
allow(Auth).to receive(:verify_admin_session).and_return(false)

delete "/jobs/#{job.id}"
expect(last_response).not_to be_ok
json_data = JSON.parse(last_response.body)
expect_error(json_data, Errors::VERIFY_CORPORATE_SESSION)
expect_error(json_data, Errors::VERIFY_ADMIN_SESSION)
end

it 'should return an error if it cannot find the job by id' do
Expand Down
Loading