-
-
Notifications
You must be signed in to change notification settings - Fork 0
/
server.rb
117 lines (95 loc) · 2.44 KB
/
server.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
require 'sinatra/base'
require 'octokit'
require 'redis'
require 'json'
require 'sinatra/auth/github'
require 'dotenv'
require 'tilt/erb'
Dotenv.load
class OverSharer < Sinatra::Base
configure :production do
require 'rack-ssl-enforcer'
use Rack::SslEnforcer
end
set :method_override, true
configure do
@@redis = Redis.new(url: ENV["REDIS_URL"])
end
use Rack::Session::Cookie, {
:http_only => true,
:secret => ENV['SESSION_SECRET'] || SecureRandom.hex
}
set :github_options, { :scopes => 'repo,repo_private' }
ENV['WARDEN_GITHUB_VERIFIER_SECRET'] ||= SecureRandom.hex
register Sinatra::Auth::Github
def redis
self.class.class_variable_get(:@@redis)
end
def get_doc(id)
data = redis.get(id)
JSON.parse(data) if data
end
def set_doc(id, doc)
redis.set id, doc.to_json
end
def pullable?(repo)
client = Octokit::Client.new access_token: github_user.token
!!client.repository(repo)
rescue
false
end
error 404 do
erb :index, locals: { msg: "Not found" }
end
error 406 do
erb :index, locals: { msg: "Unauthorized" }
end
get "/" do
erb :index, locals: { msg: "" }
end
post "/" do
# parse the GitHub URL
begin
url = URI.parse params[:github_url]
match, repo, ref, path = url.path.match(/\A\/([^\/]+\/[^\/]+)\/blob\/([^\/]+)\/(.*)\z/).to_a
rescue URI::InvalidURIError
halt erb :index, locals: { msg: "Invalid URL" }
end
# Confirm user can pull from the repo
authenticate!
halt 406 unless pullable?(repo)
# Store the doc and token
id = SecureRandom.uuid
set_doc id, {
repo: repo,
ref: ref,
path: path,
token: github_user.token
}
redirect "/#{id}"
end
get "/:id" do
doc = get_doc params[:id]
halt 404 unless doc
client = Octokit::Client.new access_token: doc["token"]
begin
response = client.contents doc["repo"], path: doc["path"], ref: doc["ref"]
rescue Octokit::NotFound
halt 404
end
markdown = Base64.decode64(response.content).force_encoding("UTF-8")
html = client.markdown markdown, mode: "gfm", context: doc["repo"]
erb :show, locals: {
repo: doc["repo"],
ref: doc["ref"],
path: doc["path"],
url: response.html_url,
contents: html,
created_by: client.user
}
end
delete "/:id" do
redis.del params[:id]
erb :index, locals: { msg: "Document unshared" }
end
end