inteliguide-multitenancy 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,14 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ *.bundle
11
+ *.so
12
+ *.o
13
+ *.a
14
+ mkmf.log
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
@@ -0,0 +1 @@
1
+ Copyright (c) 2015 Lyconic
@@ -0,0 +1,2 @@
1
+ # multitenancy
2
+ Shared multitenancy logic for the Inteliguide Suite
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+
@@ -0,0 +1,27 @@
1
+ require "multitenancy/version"
2
+ require "multitenancy/tenant"
3
+ require "multitenancy/middleware"
4
+
5
+ module Multitenancy
6
+ def self.connection
7
+ if defined?(ActiveRecord)
8
+ Thread.current[:tenant_conn] || ActiveRecord::Base.connection
9
+ else
10
+ Thread.current[:tenant_conn]
11
+ end
12
+ end
13
+
14
+ def self.connection=(connection)
15
+ Thread.current[:tenant_conn] = connection
16
+ end
17
+
18
+ def self.domain; @domain; end
19
+
20
+ def self.domain=(uri)
21
+ @domain = uri.to_s
22
+ end
23
+
24
+ def self.enabled?
25
+ !!ENV['MULTITENANT']
26
+ end
27
+ end
@@ -0,0 +1,33 @@
1
+ module Multitenancy
2
+ class Middleware
3
+ attr_reader :app, :header
4
+
5
+ def initialize(app, header = 'HTTP_HOST')
6
+ @app = app
7
+ @header = header
8
+ end
9
+
10
+ def call(env)
11
+ subdomain = env[header].to_s.sub(/^http(s)?:\/\//, '')
12
+ subdomain = subdomain.sub(/\.(inteli|patrol)guide\.(net|com)/, '').downcase
13
+ subdomain = env.fetch('TENANT', 'localhost') if development?(subdomain)
14
+
15
+ if subdomain.length > 0
16
+ Tenant.load(subdomain) or return [404, { 'Content-Type' => 'text/html', 'Content-Length' => '9' }, ['Not Found']]
17
+ end
18
+
19
+ @app.call(env)
20
+ ensure
21
+ Tenant.current = nil
22
+ end
23
+
24
+ private
25
+
26
+ def development?(server_name)
27
+ return true if server_name =~ /^localhost(?:\:[0-9]+)$/
28
+ return true if server_name =~ /\.local$/
29
+ return true if server_name =~ /^(?:[0-9]{1,3}\.){3}[0-9]{1,3}(?:\:[0-9]+)$/
30
+ false
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,49 @@
1
+ require 'virtus'
2
+
3
+ class Tenant
4
+ UnknownTenantError = Class.new(StandardError)
5
+
6
+ include Virtus.model
7
+
8
+ attribute :id, Integer
9
+ attribute :subdomain, String
10
+ attribute :name, String
11
+
12
+ class << self
13
+ def current
14
+ Thread.current[:tenant]
15
+ end
16
+
17
+ def current=(value)
18
+ Thread.current[:tenant] = value
19
+ end
20
+
21
+ def current_id
22
+ return nil unless current
23
+ current.id
24
+ end
25
+
26
+ def load(subdomain)
27
+ find_by :subdomain, subdomain
28
+ end
29
+
30
+ def find_by(field, value)
31
+ return current if current && current.send(field) == value
32
+
33
+ table = Arel::Table.new(:tenants)
34
+ query = table.project([table[:id], table[:subdomain], table[:name]]).where(table[field].eq(value))
35
+ record = Multitenancy.connection.select_one(query)
36
+
37
+ self.current = nil
38
+ self.current = new(record) if record
39
+ end
40
+
41
+ def find_by!(field, value)
42
+ find_by(field, value) or raise UnknownTenantError, "Unknown Tenant #{field}: #{value}"
43
+ end
44
+ end
45
+
46
+ def uri(domain = Multitenancy.domain)
47
+ URI("https://#{ subdomain }.#{ domain }")
48
+ end
49
+ end
@@ -0,0 +1,3 @@
1
+ module Multitenancy
2
+ VERSION = "0.0.2"
3
+ end
@@ -0,0 +1,26 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'multitenancy/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "inteliguide-multitenancy"
8
+ spec.version = Multitenancy::VERSION
9
+ spec.authors = ["Adam Lassek"]
10
+ spec.email = ["alassek@lyconic.com"]
11
+ spec.summary = %q{Multitenancy logic for the Inteliguide Suite}
12
+ spec.homepage = "https://lyconic.com/#inteliguide"
13
+
14
+ spec.files = `git ls-files -z`.split("\x0")
15
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
16
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
17
+ spec.require_paths = ["lib"]
18
+
19
+ spec.add_dependency "virtus"
20
+
21
+ spec.add_runtime_dependency "rack"
22
+ spec.add_runtime_dependency "arel"
23
+
24
+ spec.add_development_dependency "bundler", "~> 1.7"
25
+ spec.add_development_dependency "rake", "~> 10.0"
26
+ end
metadata ADDED
@@ -0,0 +1,136 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: inteliguide-multitenancy
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Adam Lassek
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2016-05-14 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: virtus
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
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: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: rack
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '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: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: arel
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '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: '0'
62
+ - !ruby/object:Gem::Dependency
63
+ name: bundler
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ~>
68
+ - !ruby/object:Gem::Version
69
+ version: '1.7'
70
+ type: :development
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ~>
76
+ - !ruby/object:Gem::Version
77
+ version: '1.7'
78
+ - !ruby/object:Gem::Dependency
79
+ name: rake
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ~>
84
+ - !ruby/object:Gem::Version
85
+ version: '10.0'
86
+ type: :development
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ~>
92
+ - !ruby/object:Gem::Version
93
+ version: '10.0'
94
+ description:
95
+ email:
96
+ - alassek@lyconic.com
97
+ executables: []
98
+ extensions: []
99
+ extra_rdoc_files: []
100
+ files:
101
+ - .gitignore
102
+ - Gemfile
103
+ - LICENSE.txt
104
+ - README.md
105
+ - Rakefile
106
+ - lib/multitenancy.rb
107
+ - lib/multitenancy/middleware.rb
108
+ - lib/multitenancy/tenant.rb
109
+ - lib/multitenancy/version.rb
110
+ - multitenancy.gemspec
111
+ homepage: https://lyconic.com/#inteliguide
112
+ licenses: []
113
+ post_install_message:
114
+ rdoc_options: []
115
+ require_paths:
116
+ - lib
117
+ required_ruby_version: !ruby/object:Gem::Requirement
118
+ none: false
119
+ requirements:
120
+ - - ! '>='
121
+ - !ruby/object:Gem::Version
122
+ version: '0'
123
+ required_rubygems_version: !ruby/object:Gem::Requirement
124
+ none: false
125
+ requirements:
126
+ - - ! '>='
127
+ - !ruby/object:Gem::Version
128
+ version: '0'
129
+ requirements: []
130
+ rubyforge_project:
131
+ rubygems_version: 1.8.23.2
132
+ signing_key:
133
+ specification_version: 3
134
+ summary: Multitenancy logic for the Inteliguide Suite
135
+ test_files: []
136
+ has_rdoc: