utter 1.0.6 → 1.0.9

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: aaca52bdee87dcd076358931bbb3f331b439b609
4
- data.tar.gz: 546fcac5095b7da7c2be234db664503cc04fce3c
3
+ metadata.gz: f0200b470531e6b81be6eaaf1996ccf285d33a3b
4
+ data.tar.gz: 6f4925e7644d3125fb601e57624c04e34e006f68
5
5
  SHA512:
6
- metadata.gz: acb9d767cd45681d665a0407d96c37cdb9019cd23982e772e4e0e1ab3cd1cf9e5971dcedcb7ed8cdef196ccf070469dd86c67645d742f5291a18a6eea5bb7963
7
- data.tar.gz: 7707900d5300e69d7e3909fd0ba8a6c1c0552684673a5c163dcc8dbc1f0636c5e1227576de6d61c5c751ab0ea4f9edd96a6f4ad7f2de933c19deaf078b279eef
6
+ metadata.gz: f0cab0ac0c1a72a2e71a89fc810246a1c269a71327b0a0e2c814c49212a4880d5850cfe75d2b381b0a937287ca12f3677ccdc93443d569ec0b6904f8b2718d15
7
+ data.tar.gz: 09419fd90b9b0cb6c93424056274b15f20a056ad2b563477055a6d897bf65dc74936936fe9c960debe53b80b0c9e7d535069cf35e3374abc514e5ae6f0c1b226
data/README.md CHANGED
@@ -1,19 +1,253 @@
1
- Utter
2
- =====
1
+ What is Utter?
2
+ ==============
3
+ Utter is a Domain-specific Microservices Framework written in Ruby for building both regular and advanced Rule-based web APIs.
4
+
5
+
6
+ What is a Domain-specific Microservice?
7
+ ========================================
8
+ A domain is an area of knowledge such as an industry field or a subject of interest.
9
+ Building an application often requires the utilization of knowledge from a number of different domains.
10
+
11
+ Utter as a tool is used to manifest the implementation of an Application Model into a number of isolated domains, each refereed to as a `Domain-specific Microservice`.
12
+
13
+ A Domain-specific Microservice provides an isolation of a domain via defining its bounded context within a single service.
14
+ Such isolation supports the inhabitance of autonomous small teams.
15
+
16
+ Autonomous small teams are more capable of defining and hence understanding the problems involved within a bounded-context domain.
17
+
18
+ As business-inhereted intricate problems on domain basis it is easier to define domain basis as opposed to the much more difficult to define application-as-a-whole basis.
19
+
20
+ Each Utter Domain-specific Microservice incorporate its Domain-specific knowledge via extensions.
21
+
22
+
23
+ Utter is a - Simplicity Fuck'n Matters - microservies framework for building fun-sized independently deployable services.
24
+
25
+ Via using Utter each microservice, you create shall exhibit the following Domain-Driven Design coherences:
26
+ • Complete functionally Resource representation
27
+ • Append-only Data management
28
+ • Each microservice handles one resource (or verb), e.g Clients, Shop Items, Carts, Checkout, etc.
29
+ - minmizes the number of choices of Design Patterns per service.
30
+
31
+ fully acknowldges the philosphy of ... with the caveats of ...
32
+
33
+ - seperate reading data from writing data.
34
+
35
+
36
+ autonomous small teams, advocating complex pieces of logic should have , intricate
37
+
38
+ A Domain-specific Microservice is a declarative Rule-based web service, in the sense that allows a client to interact with it via a Domain-speific Ubiquitous Language(DDD) that changes the state of the system it represents.
39
+
40
+ In the same sense that natural langauges evolve while preserving its grammer rules, the Domain-specific Ubiquitious Language have a schema which acts as its grammer, or syntax if you may.
41
+
42
+
43
+ The format of the DUL is JSON, making it easily interchangable among different systems and the microservice components.
44
+
45
+ Example
46
+ #{events: [
47
+ #{facts: [
48
+ #{productions: [
49
+ #{production_rules: [
50
+ {rules: [
51
+ {subject: {name: "3am abdo", type: "souq"}, predicat: {action: "wants"}, object: {service: "delivery", type: "cup of tea", quantity: "1" }},
52
+ {subject: {name: "ss", age: "11"}, predicat: {action: kill, method: car accident}, object: {name: "john", age: "33"}},
53
+ {subject: {name: "ss", age: "11"}, predicat: {action: kill, method: car accident}, object: {name: "john", age: "33"}},
54
+ {subject: {name: "ss", age: "11"}, predicat: {action: kill, method: car accident}, object: {name: "john", age: "33"}}
55
+ ]}
56
+
57
+ #Declarative microservice means that events changing the state of the system are domain-specific yet indepentant from the technologies(languages\libraries\frameworks) used to implement the microservice. A level of abstraction for interfacing with the domain and not with the implmention technologies.
58
+
59
+
60
+ #Utter define a 'Declarative API' as an API that consists of a number of microservices, that takes a JSON payload of "events" form an API client that declares what the system should do (as opposed to how it should do it) and the backend of the API carries the exact same results regardless of the techinical details (implmentation language (ruby, python, etc.) or frameworks used).
61
+
62
+
63
+ Rules allow us to represent certain kinds of knowledge that are difficult to employ a conventional procedural program.
64
+ Rule-based programs also separate the knowledge from the rest of the program in such a way that a change in the knowledge base is not propagated throughout the program like a change in a procedural program can be.
65
+
66
+
67
+
68
+ What's Utter Main UseCase?
69
+ ===========================
70
+ WRITING EFFECTIVE USE CASES: http://alistair.cockburn.us/get/2465
71
+
72
+ Problem:
73
+
74
+ Solution:
75
+ "The programmer should understand what he is doing, that his growing product remains firmly within his intellectual grip" - Dijkstra
76
+
77
+ Utter offers you the gift of simplicity via an architectural agility that you get from building simple (one fold,), easy(a very near mental leap) microservices;
78
+ this dominates all other kinds of agility. Good design is about seperating things apart, in the sense that "less is more".
79
+
80
+ Utter helps you divide up your software project into fun-sized independently deployable microservices.
81
+
82
+ Utter lets you build fun-sized independently deployable API endpoints.
83
+
84
+ Reusability\Usability
85
+ ====================
86
+ each utter scopes down its microservice be domain-specific, making it fun-sized codebase. that each domain framework used-by\created-for the microservice can be extended via plugins and reused declarativly in another microservice of the same domain.
87
+
88
+ Mapping a single domain into many mircroservices. but one microservice to focus on one aspect of the domain and customize its domain stack via extneded middlewares.
89
+
90
+ Encapsulating functinality is not a new idea, but what makes utter stands out is that the developed codebase now is not only reusable, but actually Usable from the prespective of other microservice developers, as they access the functionality declarativly, without worrying about the implmentation details.
91
+
92
+ Utter Middleware extensiable architecture makes every compnenet reusable. and Declarative programming makes every component created via Utter highly usable.
93
+
94
+
95
+ What is the Domain-specific Microservices Architectural Pattern?
96
+ ============================================================
97
+ An architectural pattern is a general, reusable solution to a commonly occurring problem in software architecture within a given context.[1] Architectural patterns are similar to software design pattern but have a broader scope. The architectural patterns address various issues in software engineering, such as computer hardware performance limitations, high availability and minimization of a business risk. Some architectural patterns have been implemented within software frameworks.
98
+
99
+ When developing a software architecture, we have to consider not only functional requirements, but also non-functional requirements, such as performance, robustness, failure tolerance, throughput, adaptability, extendibility, reusability, and so on. Indeed, one of the purposes of software architectures is to be able to quickly tell how a piece of software satisfies its requirements.
100
+
101
+
102
+ What is a Domains-specific Microservice?
103
+ ==================================================
104
+ A Domain-specific Mircoservice is a web service responsible to utilize the knowledge of a specific domain.
105
+
106
+ How to define the scope of a domain?
107
+ ======================================
108
+ Domain scoping is the process that dentifies the domain of interest, the stakeholders and their goals.
109
+ Domain scoping is economically viable and promises success.
110
+
111
+
112
+
113
+ When to extend a domain vs dividing it up into an n number of finer-grained scoped domains?
114
+ =============================================================================================
115
+ Knowledge utilized within an Domain-specific Microservice should only belong to its core domain. If the case arises that supporting domains or other generic domains are identifable, then they should be scoped out into their own domains.
116
+
117
+ How to extend a domain?
118
+ =======================
119
+
120
+
121
+
122
+ What does Utter consits of under the hood?
123
+ ==========================================
124
+ Sinatra
125
+ Mushin
126
+ SSD
127
+ DiskCloud
128
+
129
+ What is mushin?
130
+ ===============
131
+ Building an application often requires the utilization of knowledge from a number of different domains.
132
+ Domain­specific frameworks are source code artifacts, rather limited to mainstream domains such as web, desktop, and mobile development;
133
+ and they incorporate knowledge from other domains, via extensions.
134
+ Mushin argues that a diversity of domain­specific frameworks might positively influence the construction of software applications.
135
+ Hence Mushin intends to support domain­specific framework developers, via providing a generative approach for building domain­specific frameworks,
136
+ Hoping that this may aid the convergence towards a diversity of domain­specific frameworks and their corresponding ecosystems.
137
+
138
+ Utter is a - Simplicity Fuck'n Matters - microservies framework for building fun-sized independently deployable services.
139
+
140
+ Via using Utter each microservice, you create shall exhibit the following Domain-Driven Design coherences:
141
+ • Complete functionally Resource representation
142
+ • Append-only Data management
143
+ • Each microservice handles one resource (or verb), e.g Clients, Shop Items, Carts, Checkout, etc.
144
+ - minmizes the number of choices of Design Patterns per service.
145
+
146
+ fully acknowldges the philosphy of ... with the caveats of ...
147
+
148
+ - seperate reading data from writing data.
149
+
150
+ Independant
151
+ =============
152
+ - Independent Hires\Outsourcing
153
+ By dividing up your system into Utter services you can safely hire\outsource outsource development for some functionality without the need for them to ever touch your codebase, Simply all they need is the documentation of the APIs they are to interact with.
154
+
155
+ - Independent Deployability is key
156
+ It enables separation and independent evolution of
157
+ • code base
158
+ • technology stacks
159
+ • scaling
160
+ • and features, too
161
+
162
+ - Independent code base
163
+ Each service has its own software repository
164
+ • Codebase is maintainable for developers – it fits into their brain
165
+ • Tools work fast – building, testing, refactoring code takes seconds
166
+ • Service startup only takes seconds
167
+ • No accidental cross-dependencies between code bases
168
+
169
+ - Independent technology stacks
170
+ Each service is implemented on its own technology stacks
171
+ • The technology stack can be selected to fit the task best
172
+ • Teams can also experiment with new technologies within a single microservice
173
+ • No system-wide standardized technology stack also means
174
+ • No struggle to get your technology introduced to the canon
175
+ • No piggy-pack dependencies to unnecessary technologies or libraries
176
+ • It‘s only your own dependency hell you need to struggle with 
177
+ • Selected technology stacks are often very lightweight
178
+ • A microservice is often just a single process that is started via command line, and not code and
179
+ configuration that is deployed to a container.
180
+
181
+ - Independent Scaling
182
+ Each microservice can be scaled independently.
183
+ Identified bottlenecks can be addressed directly.
184
+ Data sharding can be applied to microservices as needed (Utter uses DiskCloud).
185
+ Parts of the system that do not represent bottlenecks can remain simple and un-scaled.
186
+
187
+ - Independent evolution of Features:
188
+ Microservices can be extended without affecting other services,
189
+ For example, you can deploy a new version of (a part of) the UI without re-deploying the whole systemi,
190
+ You can also go so far as to replace the service by a complete rewrite. But you have to ensure that the service interface remains stable
191
+
192
+
193
+
194
+ ref: http://www.pst.ifi.lmu.de/Lehre/wise-14-15/mse/microservice-architectures.pdf
195
+
196
+
197
+ What is Utter?
198
+ ==============
199
+ - An utter microservice is an endpoint (a web delivery mechanism) on top of a single domain-based bounded context (mushin domain along with plugins).
200
+ - Each utter application is a dockerized straightforward-to-test isolated "SINGLE" versioned independently-deployable Endpoint(with an n number of routes) along with a domain bounded-context.
201
+ - your API documentation acts as the registery of which each team member knows what services are available on which endpoinnds and versions.
202
+ - you build an endpoint service, you deploy it indepentently, you update the centerilized API docs. and the rest of your team and the world get to start using it.
203
+ - utter gives you fine-tuning for which part of your application needs horizontal scale resources, as your application is really divided up into microserices.
204
+ - utter builds endpoints that logs out with 'Correlation IDs' that helps you to stacktrace errors and visualize how services talk to each other.
205
+ - normally the term “micro” refers to the sizing: a microservice must be manageable by a single development team (5-9
206
+ developers), Utter argues that a service is a single endpoint/single domain (usually managed by a pair of software engineers). Utter belives that this enforced constrain makes you scale down your domain and its endpoint interfaces small enough but not too small.
207
+ - Independent deployability implies no shared state and inter-process communication (often via HTTP REST-ish
208
+ interfaces)
209
+ - Functional system decomposition means vertical slicing
210
+ (in contrast to horizontal slicing through layers)
211
+ - Microservices are fun-sized services, as in
212
+ “still fun to develop and deploy”
3
213
 
4
- Utter is microservies framework for building independently deployable services.
5
214
 
6
215
  Why Utter
7
216
  ==========
8
217
  Utter loves sinatra! thats why it is built on top of it, but make smart descions to faciliate the building of microservices.
218
+ Utter doesn't GIVE A RAT ASS about SQL-based backends integrations (IF YOUR OLD SQL TROLLS AREN't DEAD ALREADY, FIRE'M ALL).
9
219
 
10
220
  Alternative Frameworks
11
221
  =======================
12
222
  Utter sees Grape as poluted framework.
13
- Utter sees Rails as MUST-Avoid framework.
223
+ Utter sees Rails as an ALMOST-ALWAYS A MUST-Avoid framework.
224
+ Utter sees the Lotus as NOT focused enough on microservices.
225
+ Utter sees Padrino as Rails wanna-be that provides TOO MANY options! (not microservices specific)
226
+ Utter sees Ramaze, NYNY, Nancy, Cuba, Camping, Crepe, Hobbit, Kenji, Brooklyn as absoulte yet a GOTO to steal some good ideas!
227
+ As simplicity is a Prequesite for Reliability, IT FUCK'N MATTERS!
228
+
229
+ Utter Project Structure
230
+ =========================
231
+ - ProjectName::V1::MicroserviceName (`utter new project` asks you about projectname, version, endpoint name i.e gitlapse::v1::lapses)
232
+ - microservice (a microservice web delivery mechanism (interface) of the application Domain bounded context) - NOTE it is "endpoint" and NOT "endpoints"
233
+ - lib
234
+ - lapses_microservice.rb
235
+ - spec
236
+ - lapses_microservice_spec.rb
237
+ - domain (a mushin domain framework, along with its middlewares - thats the lib and spec of your application) - NOTE it is "domain" and NOT "domains"
238
+ - lib
239
+ - lapse.rb (uses mushin framework stack)
240
+ - middleware_name.rb (middleware plugin)
241
+ - middleware_name.rb (middleware plugin)
242
+ - spec
243
+ - lapses_spec.rb
244
+ - Dockerfile
245
+ - Gemfile
246
+ - Rakefile (for running domain and endpoint tests) (rake is also used for building, and running dockerfile as subtitute for my run.sh)
14
247
 
15
- Example:
16
- ========
248
+ Utter Examples
249
+ ===============
250
+ Example: ========
17
251
  > utter deploy user@serverip
18
252
  1. Uses puma and nginx Dockerfile to create a proxy container and bind it to the host server
19
253
  2. this command makes a packages gem with the following structure for each endpoint and uploads it to the server
@@ -70,10 +304,18 @@ Example:
70
304
  ====================
71
305
  - Utter deploy command deploys for each endpoint (endpoint gem + Dockerfile, DATA docker-volume for SSD), nginx image for mapping ports and services.
72
306
 
73
-
74
-
75
307
  External Refs:
76
308
  - http://martinfowler.com/articles/microservices.html
77
309
  - http://highscalability.com/blog/2014/4/8/microservices-not-a-free-lunch.html
78
310
 
311
+ What is a Rule-based Microservice (Advanced)
312
+ =============================================
313
+ A rule-based microservice is a service that allows you to send a set of production-rules(facts) that describe what you like the status of your application to be.
314
+ In oppostion a normal microservice would ask you to send primative data which you would normall catch on the backend and mainpulate somehow to make it ready suitable to change the state of your application.
315
+
316
+ In that sense rule-based microservice allows its clients to interact with it via a "Rule Book". clients read the "Rule Book" and send facts to the microservice, the microservice checks the "Rule book" and updates the status of the application accordingly. And as the microservice is domain-specific so is the Rule Book, meaning the clients can always get an Expert's advice on what the status of the application should be. This makes the Microservice highly usable!
317
+
318
+ More info is always found on hackspree videos or blogposts at hackspree.com; videos and blogposts are part of active hackspree online workshops to which users can register to fully if they like. Also other contributors who provide consulting services for Utter, Mushin, etc. can edit this wikipage on github to add their corrsponding references as well, by no means this is exclusive to hackspree.
79
319
 
320
+ https://www.hackspree.com/microservices-course/whatismicroservices.video
321
+ https://www.hackspree.com/ChainofResponsibilityDesignPattern
data/bin/console CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
3
  require "bundler/setup"
4
- require "utter"
4
+ #require "utter"
5
5
 
6
6
  # You can add fixtures and/or initialization code here to make experimenting
7
7
  # with your gem easier. You can also use a different console, if you like.
@@ -10,5 +10,8 @@ require "utter"
10
10
  # require "pry"
11
11
  # Pry.start
12
12
 
13
- require "irb"
14
- IRB.start
13
+ #require "irb"
14
+ #IRB.start
15
+ require 'pry'
16
+
17
+ Pry.start
data/bin/scaffold.rb ADDED
@@ -0,0 +1,131 @@
1
+ #TODO remove highline and use Thor generators
2
+ # http://whatisthor.com/
3
+ # http://blog.plataformatec.com.br/2009/07/creating-your-own-generators-with-thor/
4
+
5
+ require 'highline'
6
+ # Basic usage
7
+
8
+ cli = HighLine.new
9
+
10
+
11
+ # project name
12
+ answer = cli.ask "What's your project name?"
13
+ puts "You have answered: #{answer}"
14
+
15
+ # microservice version
16
+ answer = cli.ask "What's your microservice version?"
17
+ puts "You have answered: #{answer}"
18
+
19
+
20
+ cli.choose do |menu|
21
+ menu.prompt = "What's your miroservice version?"
22
+ menu.choice(:v1) do
23
+ cli.say("confirmed v1")
24
+ end
25
+
26
+ menu.choices(:v2) do
27
+ cli.say("confirmed v2")
28
+ end
29
+
30
+ menu.choices(:v3) do
31
+ cli.say("confirmed v3")
32
+ end
33
+
34
+ menu.choices(:v4) do
35
+ cli.say("confirmed v4")
36
+ end
37
+
38
+ menu.choices(:v5) do
39
+ cli.say("confirmed v5")
40
+ end
41
+ end
42
+
43
+
44
+
45
+
46
+ # microservice version
47
+ answer = cli.ask "What's your microservice name?"
48
+ puts "You have answered: #{answer}"
49
+
50
+ # microservice type
51
+ #answer = cli.ask "Is your microservice public or private?"
52
+ #puts "You have answered: #{answer}"
53
+
54
+
55
+ cli.choose do |menu|
56
+ menu.prompt = "What's your miroservice type?"
57
+ menu.choice(:public) do
58
+ cli.say("confirmed 'Public' microservice!")
59
+ end
60
+ menu.choices(:private) do
61
+ cli.say("confirmed 'Private' microservice!")
62
+ end
63
+ end
64
+
65
+
66
+
67
+ # microservice deployment
68
+ #answer = cli.ask "What's your microservice host IP?"
69
+ #puts "You have answered: #{answer}"
70
+ #cli.ask("Enter your host password: ") { |q| q.echo = "x" }
71
+
72
+ #cli.choose do |menu|
73
+ # menu.prompt = "Please choose your favorite programming language? "
74
+ # menu.choice(:ruby) { cli.say("Good choice!") }
75
+ # menu.choices(:python, :perl) { cli.say("Not from around here, are you?") }
76
+ #end
77
+
78
+
79
+ =begin
80
+
81
+ # Default answer
82
+
83
+ cli.ask("Company? ") { |q| q.default = "none" }
84
+
85
+
86
+ # Validation
87
+
88
+ cli.ask("Age? ", Integer) { |q| q.in = 0..105 }
89
+ cli.ask("Name? (last, first) ") { |q| q.validate = /\A\w+, ?\w+\Z/ }
90
+
91
+
92
+ # Type conversion for answers:
93
+
94
+ cli.ask("Birthday? ", Date)
95
+ cli.ask("Interests? (comma sep list) ", lambda { |str| str.split(/,\s*/) })
96
+
97
+
98
+ # Reading passwords:
99
+
100
+ cli.ask("Enter your password: ") { |q| q.echo = false }
101
+ cli.ask("Enter your password: ") { |q| q.echo = "x" }
102
+
103
+
104
+ # ERb based output (with HighLine's ANSI color tools):
105
+ cli.say("This should be <%= color('bold', BOLD) %>!")
106
+
107
+
108
+ # Menus:
109
+
110
+ cli.choose do |menu|
111
+ menu.prompt = "Please choose your favorite programming language? "
112
+ menu.choice(:ruby) { cli.say("Good choice!") }
113
+ menu.choices(:python, :perl) { cli.say("Not from around here, are you?") }
114
+ menu.default = :ruby
115
+ end
116
+
117
+
118
+ ## Using colored indices on Menus
119
+
120
+ #HighLine::Menu.index_color = :rgb_77bbff # set default index color
121
+
122
+ cli.choose do |menu|
123
+ # menu.index_color = :rgb_999999 # override default color of index
124
+ # you can also use constants like :blue
125
+ menu.prompt = "Please choose your favorite programming language? "
126
+ menu.choice(:ruby) { cli.say("Good choice!") }
127
+ menu.choices(:python, :perl) { cli.say("Not from around here, are you?") }
128
+ end
129
+
130
+
131
+ =end
@@ -0,0 +1,7 @@
1
+ This directory contains common microservice templates
2
+ - auth microservice template
3
+ - logging microservice template
4
+ - admin microservice template
5
+
6
+ - User generate a template and specifiy certain attr to customize the template to their own needs.
7
+ - User then use/further developm the generated microservice.
@@ -0,0 +1,76 @@
1
+ =begin
2
+ #TODO write RDoc
3
+ module Utter
4
+ module Internals
5
+ class Auth < Rack::Auth::Basic #TODO digest is better than basic?
6
+ def call(env)
7
+ request = Rack::Request.new(env)
8
+
9
+ case request.path when '/docs'
10
+ @app.call(env) # skip auth to access documentation
11
+ else
12
+ super # perform auth
13
+ #TODO use json "sinatra/json" here to ensure all outcoming response are in json
14
+
15
+ #res = Rack::Response.new
16
+
17
+ # This will automatically set the Content-Length header for you
18
+ ##res.write "Hello from Rack!"
19
+
20
+ # You can get/set headers with square bracket syntax:
21
+ ##res["Content-Type"] = "Content-type: application/json; charset=utf-8"
22
+
23
+ # returns the standard [status, headers, body] array
24
+ ##res.finish
25
+
26
+ # You can set and delete cookies
27
+ # res.set_cookie("user_id", 1)
28
+ # res.delete_cookie("user_id"
29
+ end
30
+ end
31
+ end
32
+
33
+ # Any class that inherits from Endpoint, may include Utter::Token to add security
34
+ # token, a token can be used for authenticating a signed-in user or as an API for your system.
35
+ #
36
+ # Usage
37
+ #
38
+ # via curl https://api.example.com/v1/endpoint_name -u token_value:
39
+ # via Browser http://token_value@localhost:4567/
40
+ # If you need to authenticate via bearer auth (e.g., for a cross-origin request), use -H "Authorization: Bearer #{token_value}" instead of -u token_value:
41
+ #
42
+ # More Info
43
+ # - https://en.wikipedia.org/wiki/Digest_access_authentication
44
+ # - https://github.com/rack/rack/blob/master/lib/rack/auth/basic.rb
45
+ module Secured
46
+ def self.included(base)
47
+ base.class_eval do
48
+
49
+ use Auth, "#{self}" do |username, password|
50
+
51
+ $log.info "username #{username}, password #{username}"
52
+
53
+ if !username.nil? && !password.nil? then
54
+ if !User.ssd(username).nil? then
55
+ if password == User.ssd(username).password then
56
+ true # Access Granted
57
+ else
58
+ false # Access Denied
59
+ end
60
+ end
61
+ end
62
+ end
63
+
64
+ # 404 Error!
65
+ not_found do
66
+ status 404
67
+ "404 - Check #{self} API documentation"
68
+ end
69
+
70
+ end
71
+ end
72
+ end
73
+
74
+ end
75
+ end
76
+ =end
@@ -0,0 +1,39 @@
1
+ #TODO write RDoc
2
+ require 'fileutils'
3
+ require 'sinatra'
4
+ require "sinatra/json"
5
+ require 'securerandom'
6
+ require 'sinatra/cross_origin'
7
+ require 'net/http' # Net::HTTP.get('example.com', '/index.html') # => String
8
+
9
+ module Utter
10
+ module Internals
11
+
12
+ class Microservice < Sinatra::Base
13
+ # if cross_origin is required\loaded then make register Sinatra::CrossOrigin
14
+ # And
15
+ #register Sinatra::CrossOrigin
16
+
17
+ #TODO set a flag to disable this in production for security
18
+ # this helps testing APIs on localmachines as CORS fucks developers time.
19
+ # But not recommended to be set while in production enviroments
20
+ before do
21
+ response.headers["Access-Control-Allow-Origin"] = "*"
22
+ response.headers["Access-Control-Allow-Methods"] = "POST"
23
+ p response.headers.inspect
24
+ end
25
+
26
+ configure { set :server, :puma }
27
+
28
+ end
29
+
30
+ #class Public::Microservice < Utter::Microservice; end
31
+
32
+ #class Private::Microservice < Utter::Microservice
33
+ #TODO do somthing here to make it secure via some mechanism!
34
+ # as we don't do websites, we striclty focus on APIs we can use HTTP basic auth to make it secure!?
35
+
36
+ #end
37
+
38
+ end
39
+ end
@@ -0,0 +1,2 @@
1
+ # how a client find out which URI::PORT a specific microservice is mounted on
2
+ #TODO check docker gems and docker-compose
@@ -0,0 +1,2 @@
1
+ # how a client registers a specific microservice and mount it on URI::PORT
2
+ #TODO check docker gems and docker-compose
@@ -1,3 +1,4 @@
1
+ #TODO delete as mushin domains wouldn't require utter users to use this model, they should be using a mushin middleware of some kind to store their shit
1
2
  #TODO write RDoc
2
3
  module Utter
3
4
  class Model
@@ -0,0 +1,12 @@
1
+ require 'minitest'
2
+ require 'minitest/spec'
3
+ require "minitest/autorun"
4
+ require "minitest/pride"
5
+
6
+ module Utter
7
+ module Spec
8
+ # use it to build specs
9
+ class Endpoint
10
+ end
11
+ end
12
+ end
data/lib/utter.rb CHANGED
@@ -1,13 +1,68 @@
1
1
  require 'logger'
2
+ require 'mushin'
2
3
 
3
- require_relative "utter/version"
4
- require_relative "utter/store"
5
- require_relative "utter/model"
6
- require_relative "utter/endpoint"
7
- require_relative "utter/auth"
8
-
4
+ #require_relative "internals/core/store"
5
+ #require_relative "internals/core/auth"
6
+ require_relative "internals/core/microservice"
9
7
 
10
8
 
9
+ # Utter defines its interfacing points here. Utter communicate seamlessly
10
+ # via this facade pattern to its internals. This allows all Utter applications
11
+ # makes it easy to have consistant improvments without updating their codebases.
12
+ #
13
+ #NOTE According to Semantic Versioning 2.0.0 (http://semver.org/); Any changes
14
+ # to this file would require an upgrade to a new Major version.
11
15
  module Utter
16
+ # MAJOR version when you make incompatible API changes,
17
+ # MINOR version when you add functionality in a backwards-compatible manner, and
18
+ # PATCH version when you make backwards-compatible bug fixes.
19
+ VERSION = "1.0.9"
20
+
12
21
  $log = Logger.new(STDOUT)
22
+
23
+ # Utter choose to provide its functionality via Classes vs Modules as an assertive way of specifing behaviour.
24
+
25
+ # Auth is used to build authentication Microservices and is also used utter generated templates.
26
+ #class Auth < Utter::Internals::Auth; end
27
+
28
+ # BASIC FEATURE
29
+ #TODO configuring an options {} to define if a microservice is public or private
30
+ # Public::Microservice can be used to provide a microservice that doesn't require authentication.
31
+ #class Public::Microservice < Utter::Internals::Public::Microservice; end
32
+ # Private::Microservice can be used to provide a microservice that DOES require authentication.
33
+ class Microservice < Utter::Internals::Microservice; end
34
+
35
+ # BASIC FEATURE
36
+ # Usage of non domain-specific stack inside a microservice would be like
37
+ # Stack.new do
38
+ # use Trace, "A opts hash", x
39
+ # use Trace, "B opts hash", "B params hash"
40
+ # use Trace, "C opts hash", "C params hash"
41
+ # end
42
+ # Very helpful if you just want to build extenstions conforming to Mushin ducking interface of :initialize(app), :call(env)
43
+ # Yet it is strongly encourged to require your own domain-specific frameworks generated via mushin inexample, and use only
44
+ # a constraining yourself for a single domain-framework per microservice. example
45
+ #
46
+ # require 'domainframeworkXYZ'
47
+ # require 'domainframeworkXYZ_ext_1'
48
+ # require 'domainframeworkXYZ_ext_2'
49
+ # require 'domainframeworkXYZ_ext_3'
50
+ # DomainFrameworkXYZ::Stack do
51
+ # use DomainFrameworkXYZ_EXT_1, opts, params
52
+ # use DomainFrameworkXYZ_EXT_2, opts, params
53
+ # use DomainFrameworkXYZ_EXT_3, opts, params
54
+ # end
55
+ # this way your work on that domain is ackonwledge\enhanced by the community at large.
56
+ class Stack < Mushin::Stack
57
+ # Manipulating the Stack
58
+ # Implicitly insert storage via SSD ext (NOONE ELSE NEEDS TO KNOW ABOUT SSD, EXCEPT HERE! BEAUTIFUL!!!!!!)
59
+ # or Explicitly insert it while being in the microservice this way develoeprs get to choose when to use
60
+ # the right tool for the job. Example SSD for somthing, and Redis for some Caching microservice, etc.
61
+ end
62
+
63
+ # ADVANCED FEATURE
64
+ #TODO expose mushin rule-based capabilities via Utter to provide json rule-based microservices
65
+
66
+ # Asserts that Utter::Internals namespace is inaccessible directly for Utter apps.
67
+ private_constant :Internals
13
68
  end
data/samples/README.md ADDED
@@ -0,0 +1,3 @@
1
+ maybe uploads microservice is a bad choice! as being rule-based any uploads
2
+ will be part of the rules {} sent as base64. so there should not be any uplaods endpoints or microservice instead
3
+ it should be a plural noun! like lapses
@@ -8,9 +8,9 @@
8
8
  require './app'
9
9
 
10
10
  map('/public') do
11
- run API::V1::PublicEndpoint
11
+ run API::V1::Public::Microservice
12
12
  end
13
13
 
14
14
  map('/private') do
15
- run API::V1::PrivateEndpoint
15
+ run API::V1::Private::Microservice
16
16
  end
@@ -3,7 +3,7 @@ require 'utter'
3
3
 
4
4
  module API
5
5
  module V1
6
- class PublicEndpoint < Utter::Endpoint
6
+ class PublicEndpoint < Utter::Public::Endpoint
7
7
  $log.info("mounting #{self}")
8
8
  get '/' do
9
9
  "public info"
@@ -11,7 +11,7 @@ module API
11
11
  run! if app_file == $0
12
12
  end
13
13
 
14
- class PrivateEndpoint < Utter::Endpoint
14
+ class PrivateEndpoint < Utter::Private::Endpoint
15
15
  $log.info("mounting #{self}")
16
16
  get '/' do
17
17
  "private info (eyes only)"
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+ ruby '2.3.1'
3
+
4
+ gem 'utter'
@@ -0,0 +1,34 @@
1
+ GEM
2
+ remote: https://rubygems.org/
3
+ specs:
4
+ multi_json (1.12.1)
5
+ rack (1.6.4)
6
+ rack-protection (1.5.3)
7
+ rack
8
+ sinatra (1.4.7)
9
+ rack (~> 1.5)
10
+ rack-protection (~> 1.4)
11
+ tilt (>= 1.3, < 3)
12
+ sinatra-cross_origin (0.3.2)
13
+ sinatra-json (0.1.0)
14
+ multi_json (~> 1.0)
15
+ sinatra (~> 1.0)
16
+ ssd (0.1.4)
17
+ tilt (2.0.5)
18
+ utter (1.0.5)
19
+ sinatra
20
+ sinatra-cross_origin
21
+ sinatra-json
22
+ ssd
23
+
24
+ PLATFORMS
25
+ ruby
26
+
27
+ DEPENDENCIES
28
+ utter
29
+
30
+ RUBY VERSION
31
+ ruby 2.3.1p112
32
+
33
+ BUNDLED WITH
34
+ 1.12.5
@@ -0,0 +1,17 @@
1
+ # config.ru (run with rackup)
2
+ ##begin
3
+ # require 'rack/show_exceptions'
4
+ #rescue LoadError
5
+ # require 'rack/showexceptions'
6
+ #end
7
+ require 'bundler/setup'
8
+ Bundler.require(:default)
9
+
10
+ require 'utter'
11
+ #require './app'
12
+ Dir[File.dirname(__FILE__) + 'domain/lib/*.rb'].each {|file| require file }
13
+ Dir[File.dirname(__FILE__) + 'microservice/lib/*.rb'].each {|file| require file }
14
+
15
+ map('/') do
16
+ run API::V1::Torrents
17
+ end
@@ -0,0 +1,11 @@
1
+ class Echo
2
+ def initialize(app, message)
3
+ @app = app
4
+ @message = message
5
+ end
6
+
7
+ def call(env)
8
+ puts @message
9
+ @app.call(env)
10
+ end
11
+ end
@@ -0,0 +1,14 @@
1
+ #require 'rack/show_exceptions'
2
+
3
+ module API
4
+ module V1
5
+ class Torrents < Utter::Microservice
6
+ $log.info("mounting #{self}")
7
+ get '/' do
8
+ "public info"
9
+ "private info (eyes only)"
10
+ end
11
+ #run! if app_file == $0
12
+ end
13
+ end
14
+ end
data/utter.gemspec CHANGED
@@ -1,7 +1,7 @@
1
1
  # coding: utf-8
2
2
  lib = File.expand_path('../lib', __FILE__)
3
3
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
- require 'utter/version'
4
+ require_relative 'lib/utter'
5
5
 
6
6
  Gem::Specification.new do |spec|
7
7
  spec.name = "utter"
@@ -9,8 +9,8 @@ Gem::Specification.new do |spec|
9
9
  spec.authors = ["zotherstupidguy"]
10
10
  spec.email = ["zotherstupidguy@gmail.com"]
11
11
 
12
- spec.summary = %q{Utter is microservies framework for building independently deployable services.}
13
- # spec.description = %q{TODO: Write a longer description or delete this line.}
12
+ spec.summary = %q{Utter is a Domain-specific Microservices Framework written in Ruby.}
13
+ spec.description = %q{ Utter is a Domain-specific Microservices Framework written in Ruby. Utter helps you divide up your software project into fun-sized independently deployable API endpoints.}
14
14
  spec.homepage = "https://github.com/utter-rb"
15
15
  spec.license = "MIT"
16
16
 
@@ -27,9 +27,22 @@ Gem::Specification.new do |spec|
27
27
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
28
28
  spec.require_paths = ["lib"]
29
29
 
30
+ spec.add_development_dependency "pry"
31
+ spec.add_runtime_dependency "pry"
32
+
33
+ spec.add_development_dependency "highline"
34
+ spec.add_runtime_dependency "highline"
35
+
36
+
30
37
  spec.add_development_dependency "bundler", "~> 1.12"
38
+ spec.add_runtime_dependency "bundler", "~> 1.12" #TODO use bundler to generate customized Gemfile for Utter generated files
39
+
31
40
  spec.add_development_dependency "rake", "~> 10.0"
41
+ spec.add_runtime_dependency "rake", "~> 10.0"
42
+
32
43
  spec.add_development_dependency "minitest", "~> 5.0"
44
+ spec.add_runtime_dependency "minitest", "~> 5.0"
45
+
33
46
 
34
47
  spec.add_development_dependency "sinatra"
35
48
  spec.add_runtime_dependency 'sinatra'
@@ -40,10 +53,17 @@ Gem::Specification.new do |spec|
40
53
  spec.add_development_dependency "sinatra-cross_origin"
41
54
  spec.add_runtime_dependency "sinatra-cross_origin"
42
55
 
43
- spec.add_development_dependency "ssd"
44
- spec.add_runtime_dependency "ssd"
56
+ spec.add_development_dependency "ssd"
57
+ spec.add_runtime_dependency "ssd"
58
+
59
+ spec.add_development_dependency "rack-test"
60
+ spec.add_runtime_dependency "rack-test"
61
+
62
+
63
+ spec.add_development_dependency "puma"
64
+ spec.add_runtime_dependency "puma"
45
65
 
46
- spec.add_development_dependency "puma"
47
- spec.add_runtime_dependency "puma"
66
+ spec.add_development_dependency "mushin"
67
+ spec.add_runtime_dependency "mushin"
48
68
 
49
69
  end
metadata CHANGED
@@ -1,15 +1,71 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: utter
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.6
4
+ version: 1.0.9
5
5
  platform: ruby
6
6
  authors:
7
7
  - zotherstupidguy
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2016-09-15 00:00:00.000000000 Z
11
+ date: 2016-10-02 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: pry
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: pry
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: highline
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: highline
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
13
69
  - !ruby/object:Gem::Dependency
14
70
  name: bundler
15
71
  requirement: !ruby/object:Gem::Requirement
@@ -24,6 +80,20 @@ dependencies:
24
80
  - - "~>"
25
81
  - !ruby/object:Gem::Version
26
82
  version: '1.12'
83
+ - !ruby/object:Gem::Dependency
84
+ name: bundler
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '1.12'
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '1.12'
27
97
  - !ruby/object:Gem::Dependency
28
98
  name: rake
29
99
  requirement: !ruby/object:Gem::Requirement
@@ -38,6 +108,20 @@ dependencies:
38
108
  - - "~>"
39
109
  - !ruby/object:Gem::Version
40
110
  version: '10.0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: rake
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: '10.0'
118
+ type: :runtime
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - "~>"
123
+ - !ruby/object:Gem::Version
124
+ version: '10.0'
41
125
  - !ruby/object:Gem::Dependency
42
126
  name: minitest
43
127
  requirement: !ruby/object:Gem::Requirement
@@ -52,6 +136,20 @@ dependencies:
52
136
  - - "~>"
53
137
  - !ruby/object:Gem::Version
54
138
  version: '5.0'
139
+ - !ruby/object:Gem::Dependency
140
+ name: minitest
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - "~>"
144
+ - !ruby/object:Gem::Version
145
+ version: '5.0'
146
+ type: :runtime
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - "~>"
151
+ - !ruby/object:Gem::Version
152
+ version: '5.0'
55
153
  - !ruby/object:Gem::Dependency
56
154
  name: sinatra
57
155
  requirement: !ruby/object:Gem::Requirement
@@ -164,6 +262,34 @@ dependencies:
164
262
  - - ">="
165
263
  - !ruby/object:Gem::Version
166
264
  version: '0'
265
+ - !ruby/object:Gem::Dependency
266
+ name: rack-test
267
+ requirement: !ruby/object:Gem::Requirement
268
+ requirements:
269
+ - - ">="
270
+ - !ruby/object:Gem::Version
271
+ version: '0'
272
+ type: :development
273
+ prerelease: false
274
+ version_requirements: !ruby/object:Gem::Requirement
275
+ requirements:
276
+ - - ">="
277
+ - !ruby/object:Gem::Version
278
+ version: '0'
279
+ - !ruby/object:Gem::Dependency
280
+ name: rack-test
281
+ requirement: !ruby/object:Gem::Requirement
282
+ requirements:
283
+ - - ">="
284
+ - !ruby/object:Gem::Version
285
+ version: '0'
286
+ type: :runtime
287
+ prerelease: false
288
+ version_requirements: !ruby/object:Gem::Requirement
289
+ requirements:
290
+ - - ">="
291
+ - !ruby/object:Gem::Version
292
+ version: '0'
167
293
  - !ruby/object:Gem::Dependency
168
294
  name: puma
169
295
  requirement: !ruby/object:Gem::Requirement
@@ -192,7 +318,37 @@ dependencies:
192
318
  - - ">="
193
319
  - !ruby/object:Gem::Version
194
320
  version: '0'
195
- description:
321
+ - !ruby/object:Gem::Dependency
322
+ name: mushin
323
+ requirement: !ruby/object:Gem::Requirement
324
+ requirements:
325
+ - - ">="
326
+ - !ruby/object:Gem::Version
327
+ version: '0'
328
+ type: :development
329
+ prerelease: false
330
+ version_requirements: !ruby/object:Gem::Requirement
331
+ requirements:
332
+ - - ">="
333
+ - !ruby/object:Gem::Version
334
+ version: '0'
335
+ - !ruby/object:Gem::Dependency
336
+ name: mushin
337
+ requirement: !ruby/object:Gem::Requirement
338
+ requirements:
339
+ - - ">="
340
+ - !ruby/object:Gem::Version
341
+ version: '0'
342
+ type: :runtime
343
+ prerelease: false
344
+ version_requirements: !ruby/object:Gem::Requirement
345
+ requirements:
346
+ - - ">="
347
+ - !ruby/object:Gem::Version
348
+ version: '0'
349
+ description: " Utter is a Domain-specific Microservices Framework written in Ruby.
350
+ Utter helps you divide up your software project into fun-sized independently deployable
351
+ API endpoints."
196
352
  email:
197
353
  - zotherstupidguy@gmail.com
198
354
  executables: []
@@ -207,17 +363,27 @@ files:
207
363
  - README.md
208
364
  - Rakefile
209
365
  - bin/console
366
+ - bin/scaffold.rb
210
367
  - bin/setup
211
- - examples/Gemfile
212
- - examples/Gemfile.lock
213
- - examples/app.rb
214
- - examples/config.ru
368
+ - bin/templates/README.md
369
+ - lib/internals/core/auth.rb
370
+ - lib/internals/core/microservice.rb
371
+ - lib/internals/core/service_discovery.rb
372
+ - lib/internals/core/service_registration.rb
373
+ - lib/internals/core/store.rb
374
+ - lib/internals/testing/model_delete.rb
375
+ - lib/internals/testing/spec.rb
215
376
  - lib/utter.rb
216
- - lib/utter/auth.rb
217
- - lib/utter/endpoint.rb
218
- - lib/utter/model.rb
219
- - lib/utter/store.rb
220
- - lib/utter/version.rb
377
+ - samples/README.md
378
+ - samples/upjoystream::v1::auth/Gemfile
379
+ - samples/upjoystream::v1::auth/Gemfile.lock
380
+ - samples/upjoystream::v1::auth/config.ru
381
+ - samples/upjoystream::v1::auth/microservice/lib/app.rb
382
+ - samples/upjoystream::v1::torrents/Gemfile
383
+ - samples/upjoystream::v1::torrents/Gemfile.lock
384
+ - samples/upjoystream::v1::torrents/config.ru
385
+ - samples/upjoystream::v1::torrents/domain/lib/echo_ext.rb
386
+ - samples/upjoystream::v1::torrents/microservice/lib/app.rb
221
387
  - utter.gemspec
222
388
  homepage: https://github.com/utter-rb
223
389
  licenses:
@@ -239,8 +405,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
239
405
  version: '0'
240
406
  requirements: []
241
407
  rubyforge_project:
242
- rubygems_version: 2.5.1
408
+ rubygems_version: 2.6.7
243
409
  signing_key:
244
410
  specification_version: 4
245
- summary: Utter is microservies framework for building independently deployable services.
411
+ summary: Utter is a Domain-specific Microservices Framework written in Ruby.
246
412
  test_files: []
data/lib/utter/auth.rb DELETED
@@ -1,74 +0,0 @@
1
- #TODO write RDoc
2
- module Utter
3
-
4
- class Auth < Rack::Auth::Basic
5
- def call(env)
6
- request = Rack::Request.new(env)
7
-
8
- case request.path when '/docs'
9
- @app.call(env) # skip auth to access documentation
10
- else
11
- super # perform auth
12
- #TODO use json "sinatra/json" here to ensure all outcoming response are in json
13
-
14
- #res = Rack::Response.new
15
-
16
- # This will automatically set the Content-Length header for you
17
- ##res.write "Hello from Rack!"
18
-
19
- # You can get/set headers with square bracket syntax:
20
- ##res["Content-Type"] = "Content-type: application/json; charset=utf-8"
21
-
22
- # returns the standard [status, headers, body] array
23
- ##res.finish
24
-
25
- # You can set and delete cookies
26
- # res.set_cookie("user_id", 1)
27
- # res.delete_cookie("user_id"
28
- end
29
- end
30
- end
31
-
32
-
33
- # Any class that inherits from Endpoint, may include Utter::Token to add security
34
- # token, a token can be used for authenticating a signed-in user or as an API for your system.
35
- #
36
- # Usage
37
- #
38
- # via curl https://api.example.com/v1/endpoint_name -u token_value:
39
- # via Browser http://token_value@localhost:4567/
40
- # If you need to authenticate via bearer auth (e.g., for a cross-origin request), use -H "Authorization: Bearer #{token_value}" instead of -u token_value:
41
- #
42
- # More Info
43
- # - https://en.wikipedia.org/wiki/Digest_access_authentication
44
- # - https://github.com/rack/rack/blob/master/lib/rack/auth/basic.rb
45
- module Secured
46
- def self.included(base)
47
- base.class_eval do
48
-
49
- use Auth, "#{self}" do |username, password|
50
-
51
- $log.info "username #{username}, password #{username}"
52
-
53
- if !username.nil? && !password.nil? then
54
- if !User.ssd(username).nil? then
55
- if password == User.ssd(username).password then
56
- true # Access Granted
57
- else
58
- false # Access Denied
59
- end
60
- end
61
- end
62
- end
63
-
64
- # 404 Error!
65
- not_found do
66
- status 404
67
- "404 - Check #{self} API documentation"
68
- end
69
-
70
- end
71
- end
72
- end
73
-
74
- end
@@ -1,27 +0,0 @@
1
- #TODO write RDoc
2
- require 'fileutils'
3
- require 'sinatra'
4
- require "sinatra/json"
5
- require 'securerandom'
6
- require 'sinatra/cross_origin'
7
- require 'net/http' # Net::HTTP.get('example.com', '/index.html') # => String
8
-
9
- module Utter
10
- class Endpoint < Sinatra::Base
11
- # if cross_origin is required\loaded then make register Sinatra::CrossOrigin
12
- # And
13
- #register Sinatra::CrossOrigin
14
-
15
- #TODO set a flag to disable this in production for security
16
- # this helps testing APIs on localmachines as CORS fucks developers time.
17
- # But not recommended to be set while in production enviroments
18
- before do
19
- response.headers["Access-Control-Allow-Origin"] = "*"
20
- response.headers["Access-Control-Allow-Methods"] = "POST"
21
- p response.headers.inspect
22
- end
23
-
24
- configure { set :server, :puma }
25
-
26
- end
27
- end
data/lib/utter/version.rb DELETED
@@ -1,3 +0,0 @@
1
- module Utter
2
- VERSION = "1.0.6"
3
- end
File without changes