social_snippet-registry_core 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +15 -0
- data/.components +9 -0
- data/.gitignore +18 -0
- data/.travis.yml +26 -0
- data/Gemfile +17 -0
- data/LICENSE.txt +22 -0
- data/README.md +31 -0
- data/Rakefile +15 -0
- data/config.ru +9 -0
- data/config/apps.rb +26 -0
- data/config/boot.rb +50 -0
- data/config/database.rb +45 -0
- data/lib/social_snippet/registry/webapi.rb +5 -0
- data/lib/social_snippet/registry/webapi/controllers/v0/repositories_controller.rb +37 -0
- data/lib/social_snippet/registry/webapi/controllers/v0/token_controller.rb +13 -0
- data/lib/social_snippet/registry/webapi/controllers/v0/user_controller.rb +49 -0
- data/lib/social_snippet/registry/webapi/helpers/repository_helper.rb +18 -0
- data/lib/social_snippet/registry/webapi/helpers/url_helper.rb +29 -0
- data/lib/social_snippet/registry/webapi/models/repository.rb +75 -0
- data/lib/social_snippet/registry/webapi/models/user_account.rb +30 -0
- data/lib/social_snippet/registry/webapi/webapi_base.rb +12 -0
- data/lib/social_snippet/registry/webapi/webapi_v0.rb +3 -0
- data/lib/social_snippet/registry_core.rb +8 -0
- data/lib/social_snippet/registry_core/common_helpers.rb +11 -0
- data/lib/social_snippet/registry_core/config_helpers.rb +95 -0
- data/lib/social_snippet/registry_core/fetcher.rb +3 -0
- data/lib/social_snippet/registry_core/fetcher/fetcher_base.rb +19 -0
- data/lib/social_snippet/registry_core/fetcher/github_fetcher.rb +69 -0
- data/lib/social_snippet/registry_core/version.rb +5 -0
- data/lib/social_snippet/registry_core/version_helpers.rb +21 -0
- data/social_snippet-registry_core.gemspec +36 -0
- data/spec/spec_helper.rb +9 -0
- data/spec/spec_helpers/database_cleaner_helper.rb +18 -0
- data/spec/spec_helpers/factory_girl_helper.rb +9 -0
- data/spec/spec_helpers/rack_test_helper.rb +18 -0
- data/spec/webapi/controllers/v0/repositories_controller_spec.rb +232 -0
- data/spec/webapi/helpers/url_helper_spec.rb +49 -0
- data/spec/webapi/models/repository_spec.rb +72 -0
- metadata +256 -0
@@ -0,0 +1,75 @@
|
|
1
|
+
class Repository
|
2
|
+
|
3
|
+
include Mongoid::Document
|
4
|
+
include Mongoid::Timestamps # adds created_at and updated_at fields
|
5
|
+
|
6
|
+
# field <name>, :type => <type>, :default => <value>
|
7
|
+
|
8
|
+
# Repository's Name (e.g. "my-repo")
|
9
|
+
field :name, :type => String
|
10
|
+
|
11
|
+
# Repository's URL (e.g. "git://github.com/user/repo.git")
|
12
|
+
field :url, :type => String
|
13
|
+
|
14
|
+
# Repository's description (e.g. "This is my repository.")
|
15
|
+
field :desc, :type => String
|
16
|
+
|
17
|
+
# Repository's dependencies (e.g. ["dep-to-1", "dep-to-2", ...])
|
18
|
+
field :dependencies, :type => Array, :default => lambda { [] }
|
19
|
+
|
20
|
+
# You can define indexes on documents using the index macro:
|
21
|
+
# index :field <, :unique => true>
|
22
|
+
index({name: 1}, {unique: true})
|
23
|
+
|
24
|
+
# You can create a composite key in mongoid to replace the default id using the key macro:
|
25
|
+
# key :field <, :another_field, :one_more ....>
|
26
|
+
|
27
|
+
# validations
|
28
|
+
validates_presence_of :name
|
29
|
+
validates_presence_of :url
|
30
|
+
|
31
|
+
# methods
|
32
|
+
|
33
|
+
FIELD_KEYS = [
|
34
|
+
:name,
|
35
|
+
:url,
|
36
|
+
:desc,
|
37
|
+
:dependencies,
|
38
|
+
]
|
39
|
+
|
40
|
+
def to_object
|
41
|
+
FIELD_KEYS.reduce({}) do |obj, key|
|
42
|
+
obj[key.to_sym] = self[key]
|
43
|
+
obj
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def update_by_snippet_json(json_obj)
|
48
|
+
filter = %w(
|
49
|
+
desc
|
50
|
+
)
|
51
|
+
repo_info = json_obj.select {|k, v| filter.include? k }
|
52
|
+
write_attributes repo_info
|
53
|
+
# deps: hash to array
|
54
|
+
self.dependencies = json_obj["dependencies"] && json_obj["dependencies"].keys
|
55
|
+
end
|
56
|
+
|
57
|
+
class << self
|
58
|
+
|
59
|
+
def all_repos
|
60
|
+
all.map {|repo| repo.to_object }
|
61
|
+
end
|
62
|
+
|
63
|
+
def query(s)
|
64
|
+
where(:name => /#{s}/).map {|repo| repo.to_object } # TODO
|
65
|
+
end
|
66
|
+
|
67
|
+
def create_by_snippet_json(json_obj)
|
68
|
+
model = find_or_create_by(:name => json_obj["name"])
|
69
|
+
model.update_by_snippet_json json_obj
|
70
|
+
return model
|
71
|
+
end
|
72
|
+
|
73
|
+
end # class << self
|
74
|
+
|
75
|
+
end # Repository
|
@@ -0,0 +1,30 @@
|
|
1
|
+
class UserAccount
|
2
|
+
|
3
|
+
include Mongoid::Document
|
4
|
+
include Mongoid::Timestamps # adds created_at and updated_at fields
|
5
|
+
|
6
|
+
# field <name>, :type => <type>, :default => <value>
|
7
|
+
field :name, :type => String
|
8
|
+
field :github_user_id, :type => Integer
|
9
|
+
field :github_access_token, :type => String
|
10
|
+
field :github_repos, :type => Array
|
11
|
+
|
12
|
+
# You can define indexes on documents using the index macro:
|
13
|
+
# index :field <, :unique => true>
|
14
|
+
|
15
|
+
# You can create a composite key in mongoid to replace the default id using the key macro:
|
16
|
+
# key :field <, :another_field, :one_more ....>
|
17
|
+
|
18
|
+
def self.find_by_id(s)
|
19
|
+
if s.nil?
|
20
|
+
nil
|
21
|
+
else
|
22
|
+
begin
|
23
|
+
find s
|
24
|
+
rescue
|
25
|
+
nil
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
@@ -0,0 +1,8 @@
|
|
1
|
+
module SocialSnippt
|
2
|
+
module RegistryCore; end
|
3
|
+
end
|
4
|
+
require_relative "registry_core/common_helpers"
|
5
|
+
require_relative "registry_core/config_helpers"
|
6
|
+
require_relative "registry_core/version"
|
7
|
+
require_relative "registry_core/version_helpers"
|
8
|
+
require_relative "registry_core/fetcher"
|
@@ -0,0 +1,95 @@
|
|
1
|
+
module SocialSnippet::RegistryCore::ConfigHelpers
|
2
|
+
|
3
|
+
require "padrino"
|
4
|
+
require "rack/session/dalli"
|
5
|
+
require "rack/parser"
|
6
|
+
require "rack/tracker"
|
7
|
+
require "omniauth-github"
|
8
|
+
|
9
|
+
#
|
10
|
+
# call from padrino-app
|
11
|
+
#
|
12
|
+
|
13
|
+
def sspm_enable_tracker
|
14
|
+
unless ENV["SSPM_GOOGLE_ANALYTICS"].nil?
|
15
|
+
use ::Rack::Tracker do
|
16
|
+
handler :google_analytics, { tracker: ENV["SSPM_GOOGLE_ANALYTICS"] }
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def sspm_enable_json_params
|
22
|
+
logger.info "Enable JSON Params: #{self}"
|
23
|
+
|
24
|
+
use ::Rack::Parser, :parsers => {
|
25
|
+
"application/json" => proc { |data| JSON.parse data },
|
26
|
+
}
|
27
|
+
end
|
28
|
+
|
29
|
+
def sspm_enable_user_access_control
|
30
|
+
if settings.sspm_session
|
31
|
+
logger.info "Enable User Access Control: #{self}"
|
32
|
+
|
33
|
+
register ::Padrino::Admin::AccessControl
|
34
|
+
set :admin_model, "UserAccount"
|
35
|
+
set :login_page, :login
|
36
|
+
enable :authentication
|
37
|
+
enable :store_location
|
38
|
+
|
39
|
+
# check session
|
40
|
+
before do
|
41
|
+
if session[:user] && ( not logged_in? )
|
42
|
+
set_current_account session[:user]
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def sspm_enable_omniauth
|
49
|
+
return if @sspm_enable_omniauth_visited
|
50
|
+
@sspm_enable_omniauth_visited = true
|
51
|
+
|
52
|
+
if settings.sspm_session
|
53
|
+
logger.info "Enable GitHub Authentication: #{self}"
|
54
|
+
|
55
|
+
use OmniAuth::Builder do
|
56
|
+
provider(
|
57
|
+
:github,
|
58
|
+
ENV["SSPM_GITHUB_CLIENT_ID"],
|
59
|
+
ENV["SSPM_GITHUB_CLIENT_SECRET"],
|
60
|
+
{
|
61
|
+
:provider_ignores_state => true, # TODO: re-check
|
62
|
+
}
|
63
|
+
)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def sspm_enable_session
|
69
|
+
if settings.sspm_session
|
70
|
+
logger.info "Enable Session: #{self}"
|
71
|
+
|
72
|
+
set :protection, false
|
73
|
+
set :protect_from_csrf, false
|
74
|
+
disable :sessions
|
75
|
+
|
76
|
+
if ENV["SSPM_MEMCACHED_USERNAME"].nil?
|
77
|
+
memcached_client = Dalli::Client.new(ENV["SSPM_MEMCACHED_HOST"])
|
78
|
+
else
|
79
|
+
memcached_client = Dalli::Client.new(
|
80
|
+
ENV["SSPM_MEMCACHED_HOST"],
|
81
|
+
username: ENV["SSPM_MEMCACHED_USERNAME"],
|
82
|
+
password: ENV["SSPM_MEMCACHED_PASSWORD"],
|
83
|
+
)
|
84
|
+
end
|
85
|
+
use ::Rack::Session::Dalli, {
|
86
|
+
:cache => memcached_client,
|
87
|
+
:expire_after => 14 * 24 * 3600,
|
88
|
+
}
|
89
|
+
|
90
|
+
use ::Rack::Protection
|
91
|
+
use ::Rack::Protection::AuthenticityToken, :authenticity_param => '_csrf_token'
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
class SocialSnippet::RegistryCore::Fetcher::FetcherBase
|
2
|
+
|
3
|
+
require "version_sorter"
|
4
|
+
|
5
|
+
def latest_version(vers)
|
6
|
+
VersionSorter.rsort(vers).first
|
7
|
+
end
|
8
|
+
|
9
|
+
def versions(owner_id, repo_id)
|
10
|
+
refs_by(owner_id, repo_id).select do |ref|
|
11
|
+
VersionHelpers.is_version?(ref)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def snippet_json(url)
|
16
|
+
raise "not implemented"
|
17
|
+
end
|
18
|
+
|
19
|
+
end # FetcherBase
|
@@ -0,0 +1,69 @@
|
|
1
|
+
module SocialSnippet::RegistryCore::Fetcher
|
2
|
+
|
3
|
+
class GitHubFetcher < FetcherBase
|
4
|
+
|
5
|
+
require "octokit"
|
6
|
+
require "json"
|
7
|
+
require "base64"
|
8
|
+
|
9
|
+
SNIPPET_JSON_NAME = "snippet.json"
|
10
|
+
|
11
|
+
def snippet_json(url)
|
12
|
+
info = parse_url(url)
|
13
|
+
snippet_json_by info[:owner_id], info[:repo_id]
|
14
|
+
end
|
15
|
+
|
16
|
+
def is_github?(uri)
|
17
|
+
return uri.scheme === "git" &&
|
18
|
+
uri.host === "github.com" &&
|
19
|
+
/\/[a-z0-9\-]+\/[a-z0-9\-\.\_]+\.git/ === uri.path
|
20
|
+
end
|
21
|
+
|
22
|
+
def parse_url(url)
|
23
|
+
uri = URI.parse(url)
|
24
|
+
if is_github?(uri)
|
25
|
+
matches = /\/([a-z0-9\-]+)\/([a-z0-9\-\.\_]+)\.git/.match(uri.path)
|
26
|
+
return {
|
27
|
+
:owner_id => matches[1],
|
28
|
+
:repo_id => matches[2],
|
29
|
+
}
|
30
|
+
else
|
31
|
+
raise "should be passed GitHub URL"
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def client
|
36
|
+
@client ||= ::Octokit::Client.new(
|
37
|
+
:client_id => ENV["SSPM_GITHUB_CLIENT_ID"],
|
38
|
+
:client_secret => ENV["SSPM_GITHUB_CLIENT_SECRET"],
|
39
|
+
)
|
40
|
+
end
|
41
|
+
|
42
|
+
def snippet_json_by(owner_id, repo_id)
|
43
|
+
begin
|
44
|
+
opts = {}
|
45
|
+
opts[:path] = SNIPPET_JSON_NAME
|
46
|
+
|
47
|
+
# resolve version
|
48
|
+
vers = versions(owner_id, repo_id)
|
49
|
+
unless vers.empty?
|
50
|
+
opts[:ref] = latest_version(vers)
|
51
|
+
end
|
52
|
+
|
53
|
+
contents_info = client.contents("#{owner_id}/#{repo_id}", opts)
|
54
|
+
decoded_content = ::Base64.decode64(contents_info[:content])
|
55
|
+
return ::JSON.parse(decoded_content)
|
56
|
+
rescue ::Octokit::NotFound => error
|
57
|
+
raise "not found"
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def refs_by(owner_id, repo_id)
|
62
|
+
client.refs("#{owner_id}/#{repo_id}")
|
63
|
+
.map {|ref_info| ref_info[:ref] }
|
64
|
+
.map {|ref| ref.gsub /^refs\/[a-z]+\//, "" }
|
65
|
+
end
|
66
|
+
|
67
|
+
end # GitHubFetcher
|
68
|
+
|
69
|
+
end # SocialSnippet
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module SocialSnippet::RegistryCore::VersionHelpers
|
2
|
+
|
3
|
+
class << self
|
4
|
+
|
5
|
+
# Check given text whether matches version pattern
|
6
|
+
def test_version(pattern, version)
|
7
|
+
return true if pattern == "" || pattern.nil?
|
8
|
+
return true if pattern == version
|
9
|
+
# "2.1.0" and "2.1.1" match "2.1"
|
10
|
+
# "2.11.0" and "2.11.1" do not match "2.1"
|
11
|
+
return version.start_with?("#{pattern}.")
|
12
|
+
end
|
13
|
+
|
14
|
+
# Check given text is version string
|
15
|
+
def is_version?(s)
|
16
|
+
return /^([0]|[1-9][0-9]*)\.([0]|[1-9][0-9]*)\.([0]|[1-9][0-9]*)$/ === s
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
|
21
|
+
end # VersionHelpers
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'social_snippet/registry_core/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "social_snippet-registry_core"
|
8
|
+
spec.version = SocialSnippet::RegistryCore::VERSION
|
9
|
+
spec.authors = ["Hiroyuki Sano"]
|
10
|
+
spec.email = ["sh19910711@gmail.com"]
|
11
|
+
spec.summary = %q{The server-side core classes for social-snippet-registry}
|
12
|
+
spec.homepage = "https://sspm.herokuapp.com"
|
13
|
+
spec.license = "MIT"
|
14
|
+
|
15
|
+
spec.files = `git ls-files -z`.split("\x0")
|
16
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
17
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
18
|
+
spec.require_paths = ["lib"]
|
19
|
+
|
20
|
+
spec.required_ruby_version = ">= 1.9"
|
21
|
+
|
22
|
+
spec.add_runtime_dependency "bundler"
|
23
|
+
spec.add_runtime_dependency "rake"
|
24
|
+
|
25
|
+
spec.add_runtime_dependency "padrino", "~> 0.12"
|
26
|
+
spec.add_runtime_dependency "thin"
|
27
|
+
spec.add_runtime_dependency "mongoid", "~> 4.0"
|
28
|
+
spec.add_runtime_dependency "rack-parser"
|
29
|
+
spec.add_runtime_dependency "rack-tracker"
|
30
|
+
spec.add_runtime_dependency "slim"
|
31
|
+
spec.add_runtime_dependency "dalli"
|
32
|
+
|
33
|
+
spec.add_runtime_dependency "version_sorter"
|
34
|
+
spec.add_runtime_dependency "octokit"
|
35
|
+
spec.add_runtime_dependency "omniauth-github"
|
36
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
require "database_cleaner"
|
2
|
+
|
3
|
+
RSpec.configure do |config|
|
4
|
+
|
5
|
+
config.before(:suite) do
|
6
|
+
DatabaseCleaner.strategy = :truncation
|
7
|
+
DatabaseCleaner.clean_with :truncation
|
8
|
+
end
|
9
|
+
|
10
|
+
config.before(:each) do
|
11
|
+
DatabaseCleaner.start
|
12
|
+
end
|
13
|
+
|
14
|
+
config.after(:each) do
|
15
|
+
DatabaseCleaner.clean
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|