stoor 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +9 -0
- data/Gemfile +3 -0
- data/README.md +130 -0
- data/bin/stoor +7 -0
- data/config.ru +53 -0
- data/lib/stoor.rb +18 -0
- data/lib/stoor/decorate.rb +63 -0
- data/lib/stoor/fix_css_width.rb +35 -0
- data/lib/stoor/git_config.rb +24 -0
- data/lib/stoor/github_auth.rb +42 -0
- data/lib/stoor/logger.rb +18 -0
- data/lib/stoor/version.rb +3 -0
- data/lib/stoor/views/layout.rb +10 -0
- data/lib/stoor/views/logout.mustache +5 -0
- data/lib/stoor/views/logout.rb +9 -0
- data/log/.gitignore +1 -0
- data/public/.gitignore +1 -0
- data/stoor.gemspec +22 -0
- metadata +128 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,130 @@
|
|
1
|
+
This is an example of fronting Gollum with a small Sinatra app that authorizes against GitHub.
|
2
|
+
|
3
|
+
## Rationale
|
4
|
+
|
5
|
+
In our environment, the contents of our wiki are confidential and should not be pushed up to GitHub. We keep the wiki on
|
6
|
+
a local machine (behind a firewall), and put the wiki contents into a directory that is sync'd to box.com. (box.com is useful for confidential
|
7
|
+
data, because they will sign a HIPAA BAA.) Meanwhile, we'd like to authorize access by some means, so we use GitHub Oauth,
|
8
|
+
so that we can constrain access by GitHub Organization Team membership.
|
9
|
+
|
10
|
+
## Requirements
|
11
|
+
|
12
|
+
Ruby 1.9.2 or greater.
|
13
|
+
|
14
|
+
Unfortunately, this will no longer work on Ruby 1.8.7, because `gollum-lib` now wants Nokogiri 1.6.0 ([see?](https://github.com/gollum/gollum-lib/commit/eeb0a4a036001c7621d173e7152b91ed02b21ed0#commitcomment-4170065)), and
|
15
|
+
1.8.7 isn't supported. That's too bad, because it was nice that this would work on the system Ruby on a Mac.
|
16
|
+
|
17
|
+
## Setup
|
18
|
+
|
19
|
+
gem install stoor
|
20
|
+
|
21
|
+
## Usage examples
|
22
|
+
|
23
|
+
(Relax, the client id and secret below are fake.)
|
24
|
+
|
25
|
+
### The 'stoor' command
|
26
|
+
|
27
|
+
To get started, type:
|
28
|
+
|
29
|
+
stoor
|
30
|
+
|
31
|
+
This will run your gollum wiki on port 3000, though it will decorate the footer with a message saying who
|
32
|
+
the committer is. When not authenticating against GitHub, the default options for the wiki repo is used (i.e.,
|
33
|
+
the values for the GitHub commit will be what you see in `git config -l`).
|
34
|
+
|
35
|
+
The `stoor` command is a thin wrapper around the `thin` web server, and takes all `thin` options (`-p <port>`, etc.).
|
36
|
+
|
37
|
+
### Specify the Wiki repo location
|
38
|
+
|
39
|
+
WIKI_PATH=/Users/admin/wiki stoor
|
40
|
+
|
41
|
+
The `WIKI_PATH` environment variable provides for locating the wiki contents in a differet repo from the
|
42
|
+
Stoor application. It is strongly advised that you do this so that you can keep your wiki code and wiki
|
43
|
+
content separate.
|
44
|
+
|
45
|
+
### GitHub authorization
|
46
|
+
|
47
|
+
Require authorization via GitHub to the GitHub application with the given client id and secret
|
48
|
+
|
49
|
+
GITHUB_CLIENT_ID=780ec06a331b4f61a345 GITHUB_CLIENT_SECRET=f1e5439aff166c34f707747120acbf66ef233fc2 stoor
|
50
|
+
|
51
|
+
Access to the wiki will first run through GitHub OAuth against the app specified by the id and secret. For information
|
52
|
+
on setting up an application in GitHub and obtaining its id and secret, see <https://github.com/settings/applications/new>.
|
53
|
+
If you are running Stoor on localhost with Rackup, the typical settings would be:
|
54
|
+
|
55
|
+
Application Name | Main URL | Callback URL
|
56
|
+
--- | --- |
|
57
|
+
YourAppName | http://localhost:3000 | http://localhost:3000/auth/github/callback
|
58
|
+
|
59
|
+
**NOTE:** No matter what your domain and port, the callback path must be `/auth/github/callback`.
|
60
|
+
|
61
|
+
**NOTE:** See also `STOOR_DOMAIN` below: The domain specified for the cookie should match the domain in your GitHub
|
62
|
+
application settings.
|
63
|
+
|
64
|
+
### Prefer a certain email domain
|
65
|
+
|
66
|
+
If there is more than one email associated with the GitHub user, prefer the one from the specified domain (otherwise the first email will be used)
|
67
|
+
|
68
|
+
GITHUB_EMAIL_DOMAIN=7fff.com GITHUB_CLIENT_ID=780ec06a331b4f61a345 GITHUB_CLIENT_SECRET=f1e5439aff166c34f707747120acbf66ef233fc2 stoor
|
69
|
+
|
70
|
+
### Require GitHub team
|
71
|
+
|
72
|
+
GITHUB_TEAM_ID=11155 GITHUB_CLIENT_ID=780ec06a331b4f61a345 GITHUB_CLIENT_SECRET=f1e5439aff166c34f707747120acbf66ef233fc2 stoor
|
73
|
+
|
74
|
+
If the user is not a member of the specified team, they aren't allowed access.
|
75
|
+
|
76
|
+
### Specify the domain (this is to ensure that cookies are set for the correct domain)
|
77
|
+
|
78
|
+
STOOR_DOMAIN=wiki.local # default: localhost
|
79
|
+
|
80
|
+
### Specify the cookie secret
|
81
|
+
|
82
|
+
STOOR_SECRET="honi soit qui mal y pense" # default: stoor
|
83
|
+
|
84
|
+
### Specify the cookie timeout
|
85
|
+
|
86
|
+
STOOR_EXPIRE_AFTER=600 # In seconds; default: 3600
|
87
|
+
|
88
|
+
### Wide display
|
89
|
+
|
90
|
+
STOOR_WIDE=y # Main wiki content will take 90% of browser width; widens tables as well
|
91
|
+
|
92
|
+
## How I run it
|
93
|
+
|
94
|
+
I like having my own personal wiki. Since Apache is ubiquitous on Macs, I run the Wiki with configuration in `/etc/apache2/httpd.conf`,
|
95
|
+
~~~and just use my system Ruby~~~ some Ruby provided by rbenv, and Passenger.
|
96
|
+
|
97
|
+
I create an extra name for 127.0.0.1 in `/etc/hosts` such as `wiki.local`. Then:
|
98
|
+
|
99
|
+
gem install passenger
|
100
|
+
passenger-install-apache2-module
|
101
|
+
|
102
|
+
Then in `/etc/apache2/httpd.conf`:
|
103
|
+
|
104
|
+
LoadModule passenger_module /opt/boxen/rbenv/versions/1.9.2-p320/lib/ruby/gems/1.9.1/gems/passenger-4.0.19/buildout/apache2/mod_passenger.so
|
105
|
+
PassengerRoot /opt/boxen/rbenv/versions/1.9.2-p320/lib/ruby/gems/1.9.1/gems/passenger-4.0.19
|
106
|
+
PassengerDefaultRuby /opt/boxen/rbenv/versions/1.9.2-p320/bin/ruby
|
107
|
+
|
108
|
+
NameVirtualHost *:80
|
109
|
+
|
110
|
+
<VirtualHost *:80>
|
111
|
+
SetEnv GITHUB_CLIENT_ID 780ec06a331b4f61a345
|
112
|
+
SetEnv GITHUB_CLIENT_SECRET f1e5439aff166c34f707747120acbf66ef233fc2
|
113
|
+
SetEnv GITHUB_EMAIL_DOMAIN 7fff.com
|
114
|
+
SetEnv STOOR_DOMAIN wiki.local
|
115
|
+
SetEnv STOOR_EXPIRE_AFTER 60
|
116
|
+
SetEnv WIKI_PATH /Users/jgn/Dropbox/wiki
|
117
|
+
ServerName wiki.local
|
118
|
+
DocumentRoot "/opt/boxen/rbenv/versions/1.9.2-p320/lib/ruby/gems/1.9.1/gems/stoor-0.0.1/public"
|
119
|
+
<Directory "/opt/boxen/rbenv/versions/1.9.2-p320/lib/ruby/gems/1.9.1/gems/stoor-0.0.1/public">
|
120
|
+
Allow from all
|
121
|
+
Options -MultiViews
|
122
|
+
</Directory>
|
123
|
+
</VirtualHost>
|
124
|
+
|
125
|
+
and finally:
|
126
|
+
|
127
|
+
sudo apachectl -k restart
|
128
|
+
|
129
|
+
Now browse your wiki at <http://wiki.local>
|
130
|
+
|
data/bin/stoor
ADDED
data/config.ru
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
$LOAD_PATH << File.join(File.dirname(__FILE__), 'lib')
|
4
|
+
require 'rubygems'
|
5
|
+
require 'logger'
|
6
|
+
require 'bundler/setup'
|
7
|
+
require 'sinatra_auth_github'
|
8
|
+
require 'gollum/app'
|
9
|
+
require 'stoor'
|
10
|
+
|
11
|
+
# Force the NullLogger to be a no-op, since it keeps getting bound into the
|
12
|
+
# Request instance.
|
13
|
+
module Rack
|
14
|
+
class NullLogger
|
15
|
+
def initialize(app)
|
16
|
+
@app = app
|
17
|
+
end
|
18
|
+
|
19
|
+
def call(env)
|
20
|
+
@app.call(env)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
ENV['RACK_ENV'] ||= 'development'
|
26
|
+
log_frag = "#{File.dirname(__FILE__)}/log/#{ENV['RACK_ENV']}"
|
27
|
+
access_logger = Logger.new("#{log_frag}_access.log")
|
28
|
+
access_logger.instance_eval do
|
29
|
+
def write(msg); self.send(:<<, msg); end
|
30
|
+
end
|
31
|
+
access_logger.level = Logger::INFO
|
32
|
+
log_stream = File.open("#{log_frag}.log", 'a+')
|
33
|
+
log_stream.sync = true
|
34
|
+
|
35
|
+
domain = ENV['STOOR_DOMAIN'] || 'localhost'
|
36
|
+
secret = ENV['STOOR_SECRET'] || 'stoor'
|
37
|
+
expire_after = (ENV['STOOR_EXPIRE_AFTER'] || '3600').to_i
|
38
|
+
|
39
|
+
wiki_path = ENV['WIKI_PATH_IN_USE'] = ENV['WIKI_PATH'] || File.expand_path(File.dirname(__FILE__))
|
40
|
+
|
41
|
+
use Rack::CommonLogger, access_logger
|
42
|
+
use Stoor::Logger, log_stream, Logger::INFO
|
43
|
+
use Rack::Session::Cookie, :domain => domain, :key => 'rack.session', :secret => secret, :expire_after => expire_after
|
44
|
+
|
45
|
+
use Stoor::GithubAuth
|
46
|
+
use Stoor::GitConfig
|
47
|
+
use Stoor::Decorate
|
48
|
+
use Stoor::FixCssWidth if ENV['STOOR_WIDE']
|
49
|
+
|
50
|
+
Precious::App.set(:gollum_path, wiki_path)
|
51
|
+
Precious::App.set(:default_markup, :markdown)
|
52
|
+
Precious::App.set(:wiki_options, { :universal_toc =>false })
|
53
|
+
run Precious::App
|
data/lib/stoor.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'stoor/logger'
|
2
|
+
require 'stoor/github_auth'
|
3
|
+
require 'stoor/git_config'
|
4
|
+
require 'stoor/decorate'
|
5
|
+
require 'stoor/fix_css_width'
|
6
|
+
require 'stoor/views/layout'
|
7
|
+
require 'stoor/views/logout'
|
8
|
+
|
9
|
+
# In at least gollum 2.4.13 and later:
|
10
|
+
# https://github.com/gollum/gollum/blob/master/lib/gollum/uri_encode_component.rb#L36
|
11
|
+
# seems to get scoped funny, and I see this:
|
12
|
+
# NoMethodError - undefined method `URIEncodeComponent' for #<URI::Parser:0x007f91db50bd78>:
|
13
|
+
# This fixes it.
|
14
|
+
if RUBY_VERSION == '1.9.2'
|
15
|
+
def encodeURIComponent(componentString)
|
16
|
+
::URI::URIEncodeComponent(componentString)
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
module Stoor
|
2
|
+
class Decorate
|
3
|
+
include Rack::Utils
|
4
|
+
|
5
|
+
FOOTER_REGEXP = /(<div id="footer">)(.*?)(<\/div>)/im
|
6
|
+
|
7
|
+
def initialize(app); @app = app; end
|
8
|
+
|
9
|
+
def call(env)
|
10
|
+
@request = Rack::Request.new(env)
|
11
|
+
|
12
|
+
if @request.session['gollum.author'].nil?
|
13
|
+
@request.logger.info "No 'gollum.author' in session - skipping page decoration."
|
14
|
+
return @app.call(env)
|
15
|
+
end
|
16
|
+
|
17
|
+
status, headers, response = @app.call(env)
|
18
|
+
headers = HeaderHash.new(headers)
|
19
|
+
|
20
|
+
if !STATUS_WITH_NO_ENTITY_BODY.include?(status) &&
|
21
|
+
!headers['transfer-encoding'] &&
|
22
|
+
headers['content-type'] &&
|
23
|
+
headers['content-type'].include?("text/html")
|
24
|
+
|
25
|
+
# TODO: If the response isn't an Array, it's a Rack::File or something, so ignore
|
26
|
+
if response.respond_to? :inject
|
27
|
+
content = response.inject("") { |content, part| content << part }
|
28
|
+
if match_data = content.match(FOOTER_REGEXP)
|
29
|
+
new_body = "" <<
|
30
|
+
match_data.pre_match <<
|
31
|
+
match_data[1] <<
|
32
|
+
before_existing_footer <<
|
33
|
+
match_data[2] <<
|
34
|
+
after_existing_footer <<
|
35
|
+
match_data[3] <<
|
36
|
+
match_data.post_match
|
37
|
+
headers['Content-Length'] = new_body.bytesize.to_s
|
38
|
+
return [status, headers, [new_body]]
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
[status, headers, response]
|
44
|
+
end
|
45
|
+
|
46
|
+
def before_existing_footer
|
47
|
+
<<-HTML
|
48
|
+
<div style="float: left;">
|
49
|
+
HTML
|
50
|
+
end
|
51
|
+
|
52
|
+
def after_existing_footer
|
53
|
+
<<-HTML
|
54
|
+
</div>
|
55
|
+
<div style="float: right;">
|
56
|
+
<p style="text-align: right; font-size: .9em; line-height: 1.6em; color: #999; margin: 0.9em 0;">
|
57
|
+
Commiting as <b>#{@request.session['gollum.author'][:name]}</b> (#{@request.session['gollum.author'][:email]})#{" | <a href='/logout'>Logout</a>" if ENV['GITHUB_AUTHORIZED']}
|
58
|
+
</p>
|
59
|
+
</div>
|
60
|
+
HTML
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module Stoor
|
2
|
+
class FixCssWidth
|
3
|
+
include Rack::Utils
|
4
|
+
|
5
|
+
ADDITIONAL_STYLES = '<style type="text/css">#wiki-wrapper { width: 90%; } .markdown-body table { width: 100%; }</style>'
|
6
|
+
|
7
|
+
def initialize(app); @app = app; end
|
8
|
+
|
9
|
+
def call(env)
|
10
|
+
@request = Rack::Request.new(env)
|
11
|
+
|
12
|
+
status, headers, response = @app.call(env)
|
13
|
+
headers = HeaderHash.new(headers)
|
14
|
+
|
15
|
+
if !STATUS_WITH_NO_ENTITY_BODY.include?(status) &&
|
16
|
+
!headers['transfer-encoding'] &&
|
17
|
+
headers['content-type'] &&
|
18
|
+
headers['content-type'].include?("text/html")
|
19
|
+
|
20
|
+
# TODO: If the response isn't an Array, it's a Rack::File or something, so ignore
|
21
|
+
if response.respond_to? :inject
|
22
|
+
content = response.inject("") { |content, part| content << part }
|
23
|
+
if content =~ /<body>/
|
24
|
+
pre, match, post = $`, $&, $'
|
25
|
+
new_body = pre + match + ADDITIONAL_STYLES + post
|
26
|
+
headers['Content-Length'] = new_body.bytesize.to_s
|
27
|
+
return [status, headers, [new_body]]
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
[status, headers, response]
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Stoor
|
2
|
+
class GitConfig
|
3
|
+
def initialize(app); @app = app; end
|
4
|
+
|
5
|
+
def call(env)
|
6
|
+
@request = Rack::Request.new(env)
|
7
|
+
unless @request.session['gollum.author']
|
8
|
+
if ENV['WIKI_PATH_IN_USE']
|
9
|
+
if name = git_option_value('user.name')
|
10
|
+
if email = git_option_value('user.email')
|
11
|
+
@request.session['gollum.author'] = { :name => name, :email => email }
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
@app.call(env)
|
17
|
+
end
|
18
|
+
|
19
|
+
def git_option_value(option)
|
20
|
+
`cd #{ENV['WIKI_PATH_IN_USE']} && git config --get #{option}`.strip
|
21
|
+
rescue
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module Stoor
|
2
|
+
class GithubAuth < Sinatra::Base
|
3
|
+
|
4
|
+
set :github_options, {
|
5
|
+
:scopes => "user,user:email",
|
6
|
+
:client_id => ENV['GITHUB_CLIENT_ID'],
|
7
|
+
:secret => ENV['GITHUB_CLIENT_SECRET']
|
8
|
+
}
|
9
|
+
|
10
|
+
register Sinatra::Auth::Github
|
11
|
+
register Mustache::Sinatra
|
12
|
+
|
13
|
+
get '/logout' do
|
14
|
+
logout!
|
15
|
+
mustache :logout
|
16
|
+
end
|
17
|
+
|
18
|
+
get '/*' do
|
19
|
+
ENV['GITHUB_AUTHORIZED'] = nil
|
20
|
+
|
21
|
+
pass unless ENV['GITHUB_CLIENT_ID'] && ENV['GITHUB_CLIENT_SECRET']
|
22
|
+
|
23
|
+
pass if request.path_info =~ /\./
|
24
|
+
|
25
|
+
authenticate!
|
26
|
+
if ENV['GITHUB_TEAM_ID']
|
27
|
+
github_team_authenticate!(ENV['GITHUB_TEAM_ID'])
|
28
|
+
end
|
29
|
+
|
30
|
+
ENV['GITHUB_AUTHORIZED'] = "yes"
|
31
|
+
|
32
|
+
email = nil
|
33
|
+
emails = github_user.api.emails
|
34
|
+
if ENV['GITHUB_EMAIL_DOMAIN']
|
35
|
+
email = emails.find { |e| e =~ /#{ENV['GITHUB_EMAIL_DOMAIN']}/ }
|
36
|
+
end
|
37
|
+
email ||= emails.first
|
38
|
+
session['gollum.author'] = { :name => github_user.name, :email => email }
|
39
|
+
pass
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
data/lib/stoor/logger.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
# Like Rack::Logger, but provide for defining the stream
|
2
|
+
# at initialization.
|
3
|
+
module Stoor
|
4
|
+
class Logger
|
5
|
+
def initialize(app, stream = nil, level = ::Logger::INFO)
|
6
|
+
@app, @stream, @level = app, stream, level
|
7
|
+
end
|
8
|
+
|
9
|
+
def call(env)
|
10
|
+
stream = @stream || env['rack.errors']
|
11
|
+
logger = ::Logger.new(stream)
|
12
|
+
logger.level = @level
|
13
|
+
|
14
|
+
env['rack.logger'] = logger
|
15
|
+
@app.call(env)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
class Stoor::GithubAuth
|
2
|
+
module Views
|
3
|
+
class Layout < Precious::Views::Layout
|
4
|
+
def self.template_file
|
5
|
+
# Steal Gollum's layout so we get the CSS, JavaScript, etc.
|
6
|
+
@template_file ||= File.join(File.dirname(Precious::App.new!.method(:wiki_page).source_location[0]), 'templates', 'layout.mustache')
|
7
|
+
end
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
data/log/.gitignore
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
!.gitignore
|
data/public/.gitignore
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
!.gitignore
|
data/stoor.gemspec
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
$LOAD_PATH.unshift File.expand_path(File.join('..', 'lib'), __FILE__)
|
2
|
+
require 'stoor/version'
|
3
|
+
|
4
|
+
Gem::Specification.new do |s|
|
5
|
+
s.name = 'stoor'
|
6
|
+
s.version = Stoor::VERSION
|
7
|
+
s.date = Time.now.utc.strftime('%Y-%m-%d')
|
8
|
+
s.summary = 'Front-end for Gollum'
|
9
|
+
s.description = 'Front-end for Gollum'
|
10
|
+
s.authors = ['John G. Norman']
|
11
|
+
s.email = 'john@7fff.com'
|
12
|
+
s.files = `git ls-files`.split("\n")
|
13
|
+
s.homepage = 'https://rubygems.org/gems/stoor'
|
14
|
+
s.rdoc_options = ['--charset=UTF-8']
|
15
|
+
s.require_paths = ['lib']
|
16
|
+
s.test_files = `git ls-files spec`.split("\n")
|
17
|
+
s.add_dependency 'thin', '~> 1.5.1'
|
18
|
+
s.add_dependency 'gollum', '~> 2.5.0'
|
19
|
+
s.add_dependency 'sinatra_auth_github', '~> 1.0.0'
|
20
|
+
s.add_dependency 'json', '~> 1.8.0'
|
21
|
+
s.executables << 'stoor'
|
22
|
+
end
|
metadata
ADDED
@@ -0,0 +1,128 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: stoor
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- John G. Norman
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-09-25 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: thin
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 1.5.1
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 1.5.1
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: gollum
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ~>
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: 2.5.0
|
38
|
+
type: :runtime
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ~>
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: 2.5.0
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: sinatra_auth_github
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ~>
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: 1.0.0
|
54
|
+
type: :runtime
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ~>
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 1.0.0
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: json
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ~>
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: 1.8.0
|
70
|
+
type: :runtime
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ~>
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: 1.8.0
|
78
|
+
description: Front-end for Gollum
|
79
|
+
email: john@7fff.com
|
80
|
+
executables:
|
81
|
+
- stoor
|
82
|
+
extensions: []
|
83
|
+
extra_rdoc_files: []
|
84
|
+
files:
|
85
|
+
- .gitignore
|
86
|
+
- Gemfile
|
87
|
+
- README.md
|
88
|
+
- bin/stoor
|
89
|
+
- config.ru
|
90
|
+
- lib/stoor.rb
|
91
|
+
- lib/stoor/decorate.rb
|
92
|
+
- lib/stoor/fix_css_width.rb
|
93
|
+
- lib/stoor/git_config.rb
|
94
|
+
- lib/stoor/github_auth.rb
|
95
|
+
- lib/stoor/logger.rb
|
96
|
+
- lib/stoor/version.rb
|
97
|
+
- lib/stoor/views/layout.rb
|
98
|
+
- lib/stoor/views/logout.mustache
|
99
|
+
- lib/stoor/views/logout.rb
|
100
|
+
- log/.gitignore
|
101
|
+
- public/.gitignore
|
102
|
+
- stoor.gemspec
|
103
|
+
homepage: https://rubygems.org/gems/stoor
|
104
|
+
licenses: []
|
105
|
+
post_install_message:
|
106
|
+
rdoc_options:
|
107
|
+
- --charset=UTF-8
|
108
|
+
require_paths:
|
109
|
+
- lib
|
110
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
111
|
+
none: false
|
112
|
+
requirements:
|
113
|
+
- - ! '>='
|
114
|
+
- !ruby/object:Gem::Version
|
115
|
+
version: '0'
|
116
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
117
|
+
none: false
|
118
|
+
requirements:
|
119
|
+
- - ! '>='
|
120
|
+
- !ruby/object:Gem::Version
|
121
|
+
version: '0'
|
122
|
+
requirements: []
|
123
|
+
rubyforge_project:
|
124
|
+
rubygems_version: 1.8.23
|
125
|
+
signing_key:
|
126
|
+
specification_version: 3
|
127
|
+
summary: Front-end for Gollum
|
128
|
+
test_files: []
|