Skip to content

Commit afd7f18

Browse files
author
Eric Berry
committed
MEGA WIP
1 parent c7f59b8 commit afd7f18

31 files changed

+410
-104
lines changed

.env-example

+1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ export CAMO_KEY=
99
export CAMPAIGN_DEMO_ID=395
1010
export CLOUDFRONT_HOST=
1111
export CODEFUND_ANALYTICS_KEY=
12+
export CODEFUND_API_TOKEN=
1213
export DATABASE_URL=
1314
export DEFAULT_HOST=app.codefund.io
1415
export DOCRAPTOR_API_KEY=

Gemfile

+8
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,14 @@ gem "typhoeus", "~> 1.3.1"
8585
gem "uglifier", ">= 1.3.0"
8686
gem "webpacker", "~> 5.0.1"
8787

88+
# API-related gems
89+
gem "grape", "~> 1.3.2"
90+
gem "grape-entity", "~> 0.8.0"
91+
gem 'grape_on_rails_routes', "~> 0.3.2"
92+
gem 'swagger-ui_rails', "~> 0.1.7"
93+
gem 'grape-swagger', "~> 1.1.0"
94+
gem 'grape-swagger-rails', "~> 0.3.1"
95+
8896
group :development, :test do
8997
gem "awesome_print"
9098
gem "byebug", platforms: [:mri, :mingw, :x64_mingw]

Gemfile.lock

+49
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,28 @@ GEM
176176
dotenv-rails (2.7.5)
177177
dotenv (= 2.7.5)
178178
railties (>= 3.2, < 6.1)
179+
dry-configurable (0.11.5)
180+
concurrent-ruby (~> 1.0)
181+
dry-core (~> 0.4, >= 0.4.7)
182+
dry-equalizer (~> 0.2)
183+
dry-container (0.7.2)
184+
concurrent-ruby (~> 1.0)
185+
dry-configurable (~> 0.1, >= 0.1.3)
186+
dry-core (0.4.9)
187+
concurrent-ruby (~> 1.0)
188+
dry-equalizer (0.3.0)
189+
dry-inflector (0.2.0)
190+
dry-logic (1.0.6)
191+
concurrent-ruby (~> 1.0)
192+
dry-core (~> 0.2)
193+
dry-equalizer (~> 0.2)
194+
dry-types (1.4.0)
195+
concurrent-ruby (~> 1.0)
196+
dry-container (~> 0.3)
197+
dry-core (~> 0.4, >= 0.4.4)
198+
dry-equalizer (~> 0.3)
199+
dry-inflector (~> 0.1, >= 0.1.2)
200+
dry-logic (~> 1.0, >= 1.0.2)
179201
email_address (0.1.16)
180202
netaddr (>= 2.0.4, < 3)
181203
simpleidn
@@ -203,6 +225,22 @@ GEM
203225
full-name-splitter (0.1.2)
204226
globalid (0.4.2)
205227
activesupport (>= 4.2.0)
228+
grape (1.3.2)
229+
activesupport
230+
builder
231+
dry-types (>= 1.1)
232+
mustermann-grape (~> 1.0.0)
233+
rack (>= 1.3.0)
234+
rack-accept
235+
grape-entity (0.8.0)
236+
activesupport (>= 3.0.0)
237+
multi_json (>= 1.3.2)
238+
grape-swagger (1.1.0)
239+
grape (~> 1.3.0)
240+
grape-swagger-rails (0.3.1)
241+
railties (>= 3.2.12)
242+
grape_on_rails_routes (0.3.2)
243+
rails (>= 3.1.1)
206244
hashdiff (1.0.1)
207245
heroku-deflater (0.6.3)
208246
rack (>= 1.4.5)
@@ -295,6 +333,8 @@ GEM
295333
mustache (1.1.1)
296334
mustermann (1.1.1)
297335
ruby2_keywords (~> 0.0.1)
336+
mustermann-grape (1.0.1)
337+
mustermann (>= 1.0.0)
298338
net-http-digest_auth (1.4.1)
299339
net-http-persistent (3.1.0)
300340
connection_pool (~> 2.2)
@@ -346,6 +386,8 @@ GEM
346386
puma (4.3.3)
347387
nio4r (~> 2.0)
348388
rack (2.2.2)
389+
rack-accept (0.4.5)
390+
rack (>= 0.4)
349391
rack-attack (6.2.2)
350392
rack (>= 1.0, < 3)
351393
rack-contrib (2.2.0)
@@ -523,6 +565,7 @@ GEM
523565
unicode_utils (~> 1.4)
524566
strings-ansi (0.2.0)
525567
stripe (5.4.1)
568+
swagger-ui_rails (0.1.7)
526569
systemu (2.6.5)
527570
tag_columns (0.1.8)
528571
activesupport
@@ -620,6 +663,11 @@ DEPENDENCIES
620663
erb_lint
621664
faker
622665
full-name-splitter (~> 0.1.2)
666+
grape (~> 1.3.2)
667+
grape-entity (~> 0.8.0)
668+
grape-swagger (~> 1.1.0)
669+
grape-swagger-rails (~> 0.3.1)
670+
grape_on_rails_routes (~> 0.3.2)
623671
hashdiff
624672
heroku-deflater (~> 0.6.3)
625673
hiredis (~> 0.6.3)
@@ -688,6 +736,7 @@ DEPENDENCIES
688736
stimulus_reflex (~> 3.1.2)
689737
stopwords-filter (~> 0.4.1)
690738
stripe (~> 5.4.1)
739+
swagger-ui_rails (~> 0.1.7)
691740
tag_columns (~> 0.1.8)
692741
teamocil
693742
tocer

app/assets/config/manifest.js

+2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
11
//= link_tree ../images
22
//= link_directory ../javascripts .js
33
//= link_directory ../stylesheets .css
4+
//= link grape_swagger_rails/application.css
5+
//= link grape_swagger_rails/application.js

app/controllers/api/base.rb

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
class API::Base < Grape::API
2+
helpers API::Auth
3+
4+
mount API::Emails
5+
mount API::Users
6+
7+
# :nocov:
8+
if Rails.env.development?
9+
add_swagger_documentation add_version: true
10+
end
11+
# :nocov:
12+
end

app/controllers/api/defaults.rb

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
module API::Defaults
2+
extend ActiveSupport::Concern
3+
4+
included do
5+
prefix "api"
6+
default_format :json
7+
format :json
8+
9+
helpers do
10+
def permitted_params
11+
@permitted_params ||= declared(params, include_missing: false)
12+
end
13+
14+
def logger
15+
Rails.logger
16+
end
17+
end
18+
19+
rescue_from ActiveRecord::RecordNotFound do |e|
20+
error_response(message: e.message, status: 404)
21+
end
22+
23+
rescue_from ActiveRecord::RecordInvalid do |e|
24+
error_response(message: e.message, status: 422)
25+
end
26+
27+
# Global exception handler, used for error notifications
28+
rescue_from :all do |e|
29+
if Rails.env.development?
30+
raise e
31+
else
32+
# Raven for exception logging, or something like it...
33+
# Raven.capture_exception(e)
34+
# error_response(message: "Internal server error", status: 500)
35+
end
36+
end
37+
end
38+
end

app/controllers/api/emails.rb

+58
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
class API::Emails < Grape::API
2+
include API::Defaults
3+
4+
resource :emails do
5+
6+
# index ......................................................
7+
8+
desc "Return a list of emails", { :entity => Entity::Email }
9+
get '/' , http_codes: [
10+
[200, 'Ok', Entity::Email]
11+
] do
12+
emails = current_user.emails.all
13+
present emails, with: Entity::Email
14+
end
15+
16+
# show ......................................................
17+
18+
desc "Just a single email", { :entity => Entity::Email }
19+
params do
20+
requires :id, type: Integer
21+
end
22+
get ':id', http_codes: [
23+
[200, "Ok", Entity::Email]
24+
] do
25+
email = current_user.emails.find(params[:id])
26+
present email, with: Entity::Email
27+
end
28+
29+
# create ......................................................
30+
31+
# desc "Create a new email", { :entity => Entity::Email }
32+
# params do
33+
# requires :cc_addresses, type: Array, desc: ""
34+
# requires :content, type: String, desc: ""
35+
# requires :delivered_at, type: String, desc: ""
36+
# requires :subject :string not null
37+
# requires :to_addresses :text default([]), is an Array
38+
# requires :created_at :datetime not null
39+
# requires :updated_at :datetime not null
40+
# requires :message_id :string not null
41+
42+
# requires :title, type: String, desc: "The title for this todo"
43+
# optional :description, type: String, desc: "The description for this todo"
44+
# end
45+
# post '/', http_codes: [
46+
# [200, "Ok", Entity::Todo]
47+
# ] do
48+
# todo = Todo.new
49+
# todo.title = params[:title] if params[:title]
50+
# todo.description = params[:description] if params[:description]
51+
# todo.save
52+
53+
# status 200
54+
# present todo, with: Entity::Todo
55+
# end
56+
57+
end
58+
end

app/controllers/api/users.rb

+61
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
class API::Users < Grape::API
2+
include API::Defaults
3+
4+
# Require administrator authentication
5+
before { administrator? }
6+
7+
resource :users do
8+
9+
# index ......................................................
10+
11+
desc "Return a list of users", { :entity => Entity::User }
12+
get '/' , http_codes: [
13+
[200, 'Ok', Entity::User]
14+
] do
15+
users = User.all
16+
present users, with: Entity::User
17+
end
18+
19+
# show ......................................................
20+
21+
desc "Just a single email", { :entity => Entity::Email }
22+
params do
23+
requires :id, type: Integer
24+
end
25+
get ':id', http_codes: [
26+
[200, "Ok", Entity::Email]
27+
] do
28+
email = current_user.emails.find(params[:id])
29+
present email, with: Entity::Email
30+
end
31+
32+
# create ......................................................
33+
34+
# desc "Create a new email", { :entity => Entity::Email }
35+
# params do
36+
# requires :cc_addresses, type: Array, desc: ""
37+
# requires :content, type: String, desc: ""
38+
# requires :delivered_at, type: String, desc: ""
39+
# requires :subject :string not null
40+
# requires :to_addresses :text default([]), is an Array
41+
# requires :created_at :datetime not null
42+
# requires :updated_at :datetime not null
43+
# requires :message_id :string not null
44+
45+
# requires :title, type: String, desc: "The title for this todo"
46+
# optional :description, type: String, desc: "The description for this todo"
47+
# end
48+
# post '/', http_codes: [
49+
# [200, "Ok", Entity::Todo]
50+
# ] do
51+
# todo = Todo.new
52+
# todo.title = params[:title] if params[:title]
53+
# todo.description = params[:description] if params[:description]
54+
# todo.save
55+
56+
# status 200
57+
# present todo, with: Entity::Todo
58+
# end
59+
60+
end
61+
end

app/controllers/user_emails_controller.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ class UserEmailsController < ApplicationController
33
before_action :set_user, only: :index
44

55
def index
6-
emails = ActionMailbox::InboundEmail.includes([:raw_email_attachment]).with_user(@user).order(delivered_at: :desc)
6+
emails = Email.with_email(@user.email).order(delivered_at: :desc)
77
@pagy, @emails = pagy(emails)
88
end
99

app/helpers/api/auth.rb

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
module API::Auth
2+
3+
def warden
4+
env['warden']
5+
end
6+
7+
def authenticated?
8+
if warden.authenticated?
9+
return true
10+
elsif params[:api_key] and
11+
@current_user = User.where(api_key: params[:api_key]).first
12+
else
13+
error!({"error" => "Token invalid or expired"}, 401)
14+
end
15+
end
16+
17+
def administrator?
18+
authenticated? && current_user.administrator?
19+
end
20+
21+
def current_user
22+
@current_user
23+
end
24+
25+
end

app/lib/extensions.rb

-1
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,3 @@ module Extensions
55
Date.send :include, Extensions::DateHelpers
66
ActiveStorage::Blob.send :include, Extensions::ActiveStorageBlob
77
ActiveStorage::Attachment.send :include, Extensions::ActiveStorageAttachment
8-
ActionMailbox::InboundEmail.send :include, Extensions::ActionMailboxInboundEmail

app/lib/extensions/action_mailbox_inbound_email.rb

-26
This file was deleted.

app/mailboxes/eric_mailbox.rb

+7-6
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,14 @@
11
class EricMailbox < ApplicationMailbox
22
before_processing :require_user
3-
after_processing :record_user_ids
43

54
def process
6-
# Twiddle thumbs
5+
Email.create from_address: mail.from.first,
6+
subject: mail.subject,
7+
content: mail.body.decoded,
8+
message_id: inbound_email.message_id,
9+
to_addresses: mail.to.to_a.sort,
10+
cc_addresses: mail.cc.to_a.sort,
11+
delivered_at: (DateTime.parse(mail.raw_source.match(%r{Date: (.*)\r\n})[1]) rescue inbound_email.created_at)
712
end
813

914
private
@@ -12,8 +17,4 @@ def require_user
1217
@user = User.find_by(email: mail.from)
1318
return bounced! unless @user
1419
end
15-
16-
def record_user_ids
17-
inbound_email.add_metadata!
18-
end
1920
end

0 commit comments

Comments
 (0)