Skip to content

Commit

Permalink
Add very basic (and untested) features
Browse files Browse the repository at this point in the history
- Autenticate
- List active and closed jobs
- Get general information about a job
  • Loading branch information
leosoto committed Nov 3, 2019
1 parent 33b516d commit d70bb46
Show file tree
Hide file tree
Showing 12 changed files with 259 additions and 1 deletion.
5 changes: 5 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ gem 'bootsnap', '>= 1.4.2', require: false
group :development, :test do
# Call 'byebug' anywhere in the code to stop execution and get a debugger console
gem 'byebug', platforms: [:mri, :mingw, :x64_mingw]
gem 'rspec-rails', '~> 3.8'
end

group :development do
Expand All @@ -39,3 +40,7 @@ end

# Windows does not include zoneinfo files, so bundle the tzinfo-data gem
gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]

gem 'nokogiri'
gem 'rest-client'
gem 'httparty'
43 changes: 43 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -62,10 +62,19 @@ GEM
byebug (11.0.1)
concurrent-ruby (1.1.5)
crass (1.0.5)
diff-lcs (1.3)
domain_name (0.5.20190701)
unf (>= 0.0.5, < 1.0.0)
erubi (1.9.0)
ffi (1.11.1)
globalid (0.4.2)
activesupport (>= 4.2.0)
http-accept (1.7.0)
http-cookie (1.0.3)
domain_name (~> 0.5)
httparty (0.17.1)
mime-types (~> 3.0)
multi_xml (>= 0.5.2)
i18n (1.7.0)
concurrent-ruby (~> 1.0)
listen (3.1.5)
Expand All @@ -80,11 +89,16 @@ GEM
marcel (0.3.3)
mimemagic (~> 0.3.2)
method_source (0.9.2)
mime-types (3.3)
mime-types-data (~> 3.2015)
mime-types-data (3.2019.1009)
mimemagic (0.3.3)
mini_mime (1.0.2)
mini_portile2 (2.4.0)
minitest (5.13.0)
msgpack (1.3.1)
multi_xml (0.6.0)
netrc (0.11.0)
nio4r (2.5.2)
nokogiri (1.10.5)
mini_portile2 (~> 2.4.0)
Expand Down Expand Up @@ -122,6 +136,28 @@ GEM
rb-fsevent (0.10.3)
rb-inotify (0.10.0)
ffi (~> 1.0)
rest-client (2.1.0)
http-accept (>= 1.7.0, < 2.0)
http-cookie (>= 1.0.2, < 2.0)
mime-types (>= 1.16, < 4.0)
netrc (~> 0.8)
rspec-core (3.9.0)
rspec-support (~> 3.9.0)
rspec-expectations (3.9.0)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.9.0)
rspec-mocks (3.9.0)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.9.0)
rspec-rails (3.9.0)
actionpack (>= 3.0)
activesupport (>= 3.0)
railties (>= 3.0)
rspec-core (~> 3.9.0)
rspec-expectations (~> 3.9.0)
rspec-mocks (~> 3.9.0)
rspec-support (~> 3.9.0)
rspec-support (3.9.0)
ruby_dep (1.5.0)
spring (2.1.0)
spring-watcher-listen (2.0.1)
Expand All @@ -139,6 +175,9 @@ GEM
thread_safe (0.3.6)
tzinfo (1.2.5)
thread_safe (~> 0.1)
unf (0.1.4)
unf_ext
unf_ext (0.0.7.6)
websocket-driver (0.7.1)
websocket-extensions (>= 0.1.0)
websocket-extensions (0.1.4)
Expand All @@ -150,9 +189,13 @@ PLATFORMS
DEPENDENCIES
bootsnap (>= 1.4.2)
byebug
httparty
listen (>= 3.0.5, < 3.2)
nokogiri
puma (~> 3.11)
rails (~> 6.0.0)
rest-client
rspec-rails (~> 3.8)
spring
spring-watcher-listen (~> 2.0.0)
sqlite3 (~> 1.4)
Expand Down
9 changes: 9 additions & 0 deletions app/controllers/application_controller.rb
Original file line number Diff line number Diff line change
@@ -1,2 +1,11 @@
class ApplicationController < ActionController::API
include ActionController::HttpAuthentication::Token::ControllerMethods
before_action :require_valid_auth_token_and_set_session

def require_valid_auth_token_and_set_session
authenticate_or_request_with_http_token do |token, options|
@session = Session.where(token: token).first
@session.present?
end
end
end
14 changes: 14 additions & 0 deletions app/controllers/jobs_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
class JobsController < ApplicationController
def active
render json: @session.active_jobs
end

def closed
render json: @session.closed_jobs
end

def show
render json: @session.job(request.fullpath)
end

end
19 changes: 19 additions & 0 deletions app/controllers/sessions_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
class SessionsController < ApplicationController
skip_before_action :require_valid_auth_token_and_set_session

def create
session = Session.where(email: session_params[:email]).first_or_initialize
session.update(session_params)
if session.valid?
render json: {token: session.token}
else
render json: {errors: session.errors}, status: :unprocessable_entity
end
end

private

def session_params
params.permit(:email, :password)
end
end
109 changes: 109 additions & 0 deletions app/models/session.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
class Session < ApplicationRecord
validates :email, :password, presence: true
validates :email, :token, uniqueness: true
validate :email_and_password_work

before_save :generate_token, if: :password_changed?

def generate_token
self.token = SecureRandom.base64(32)
end

def active_jobs
parse_jobs(get('/dashboard/active.json'))
end

def closed_jobs
parse_jobs(get('/dashboard/closed.json'))
end

def job(job_url)
parse_job(get(job_url + '.json'))
end

private

def parse_job(gob_job)
iteration = gob_job[:job_iteration]
job = iteration[:job]
iteration.slice(
:active, :url
).merge(
job.slice(
:title,
:min_salary, :max_salary,
:remote, :city, :country,
:category_name, :tags, :perks, :modality, :seniority,
:functions, :functions_headline,
:benefits, :benefits_headline,
:desirable, :desirable_headline,
:unpublished
).merge(
public_url: job[:url],
company_public_url: job[:company_profile],
company_name: job[:company]
)
).merge(
{
phases: parse_phases(iteration[:phases])
}
)
end


def parse_phases(phases)
phases.sort_by { |phase| phase[:position] }. map do |phase|
phase.slice(
:position, :title, :description, :kind,
:job_applications_count, :job_applications_url
)
end
end

def parse_jobs(gob_jobs)
gob_jobs[:job_iterations].map do |job_iteration|
{url: job_iteration[:url], title: job_iteration[:job][:title]}
end

end

def email_and_password_work
get('/dashboard.json')
rescue RestClient::ExceptionWithResponse => e
errors.add(:password, "Invalid email or password")
Rails.logger.error("Unexpected response: #{e.response}")
end

def get(path, params = {})
response = RestClient.get(
"https://www.getonbrd.com" + path,
params.merge(cookies: cookies)
)
JSON.parse(response, symbolize_names: true)
end

def cookies
@cookies ||= cookies_from_email_and_password
end

def cookies_from_email_and_password
response = RestClient.get('https://www.getonbrd.com/members/auth/login')
page = Nokogiri::HTML(response.body)
csrf_token = page.css('meta[name=csrf-token]').first['content']
response = RestClient.post(
'https://www.getonbrd.com/members/auth/login',
{
authenticity_token: csrf_token,
team_member: {
email: email,
password: password,
}
},
{cookies: response.cookies}
)
raise RestClient::ExceptionWithResponse.new(response)
rescue RestClient::Found => e
return e.response.cookies
end
end

12 changes: 11 additions & 1 deletion config/routes.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,13 @@
Rails.application.routes.draw do
# For details on the DSL available within this file, see https://guides.rubyonrails.org/routing.html
resources :sessions, only: [:create]
resources :jobs, only: [] do
collection do
get 'active'
get 'closed'
end

member do
get '/processes/:id', to: 'jobs#show'
end
end
end
11 changes: 11 additions & 0 deletions db/migrate/20191103034455_create_sessions.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
class CreateSessions < ActiveRecord::Migration[6.0]
def change
create_table :sessions do |t|
t.string :email
t.string :password
t.string :token

t.timestamps
end
end
end
23 changes: 23 additions & 0 deletions db/schema.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# This file is auto-generated from the current state of the database. Instead
# of editing this file, please use the migrations feature of Active Record to
# incrementally modify your database, and then regenerate this schema definition.
#
# This file is the source Rails uses to define your schema when running `rails
# db:schema:load`. When creating a new database, `rails db:schema:load` tends to
# be faster and is potentially less error prone than running all of your
# migrations from scratch. Old migrations may fail to apply correctly if those
# migrations use external dependencies or application code.
#
# It's strongly recommended that you check this file into your version control system.

ActiveRecord::Schema.define(version: 2019_11_03_034455) do

create_table "sessions", force: :cascade do |t|
t.string "email"
t.string "password"
t.string "token"
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
end

end
5 changes: 5 additions & 0 deletions spec/controllers/jobs_controller_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
require 'rails_helper'

RSpec.describe JobsController, type: :controller do

end
5 changes: 5 additions & 0 deletions spec/controllers/sessions_controller_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
require 'rails_helper'

RSpec.describe SessionsController, type: :controller do

end
5 changes: 5 additions & 0 deletions spec/models/session_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
require 'rails_helper'

RSpec.describe Session, type: :model do
pending "add some examples to (or delete) #{__FILE__}"
end

0 comments on commit d70bb46

Please sign in to comment.