midb 1.0.5 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,98 +1,108 @@
1
- require 'midb/server_controller'
2
1
  module MIDB
3
- class ServerView
4
- def self.success()
5
- puts "Ayyy great"
6
- end
2
+ module Interface
3
+ # View that handles everything from the server
4
+ class Server
7
5
 
8
- # Method: json_error
9
- # Return a JSON error response
10
- def self.json_error(errno, msg)
11
- return {"error" => {"errno" => errno, "msg" => msg}}
12
- end
6
+ def self.success()
7
+ puts "Success!"
8
+ end
13
9
 
14
- # Method: show_serving
15
- # Shows the files being served
16
- def self.show_serving()
17
- puts "The follow JSON files are being served as APIs:"
18
- MIDB::ServerController.config["serves"].each do |serv|
19
- puts "- #{serv}"
10
+ # Return a JSON error response
11
+ #
12
+ # @param errno [Fixnum] Error number.
13
+ # @param msg [String] Error message.
14
+ def self.json_error(errno, msg)
15
+ return {"error" => {"errno" => errno, "msg" => msg}}
20
16
  end
21
- end
22
17
 
23
- # Method: server_stopped
24
- # Notice that the server has been stopped.
25
- def self.server_stopped()
26
- puts "The server has been successfully stopped!"
27
- end
18
+ # Shows the files being served
19
+ #
20
+ # @param cnf [Array<String>] The configuration from the server.
21
+ def self.show_serving(cnf)
22
+ puts "The follow JSON files are being served as APIs:"
23
+ cnf["serves"].each do |serv|
24
+ puts "- #{serv}"
25
+ end
26
+ end
28
27
 
29
- # Method: info
30
- # Send some info
31
- def self.info(what, info=nil)
32
- msg = case what
33
- when :start then "Server started on port #{info}. Listening for connections..."
34
- when :incoming_request then "> Incoming request from #{info}."
35
- when :request then ">> Request method: #{info[0]}\n>>> Endpoint: #{info[1]}"
36
- when :match_json then ">> The request matched a JSON file: #{info}.json\n>> Creating response..."
37
- when :response then ">> Sending JSON response (RAW):\n#{info}"
38
- when :success then "> Successfully managed this request!"
39
- when :not_found then "> Invalid endpoint - sending a 404 error."
40
- when :auth_required then ">> Authentication required. Checking for the HTTP header..."
41
- when :no_auth then ">> No authentication header - sending a 401 error."
42
- when :auth_success then ">> Successfully authenticated the request."
43
- when :bootstrap then "> Successfully bootstraped!"
44
- end
45
- puts msg
46
- end
28
+ # Notice that the server has been stopped.
29
+ def self.server_stopped()
30
+ puts "The server has been successfully stopped!"
31
+ end
47
32
 
48
- # Method: out_config
49
- # Output some config
50
- def self.out_config(what)
51
- msg = case what
52
- when :dbengine then "Database engine: #{MIDB::ServerController.config['dbengine']}."
53
- when :dbhost then "Database server host: #{MIDB::ServerController.config['dbhost']}."
54
- when :dbport then "Database server port: #{MIDB::ServerController.config['dbport']}."
55
- when :dbuser then "Database server user: #{MIDB::ServerController.config['dbuser']}."
56
- when :dbpassword then "Database server password: #{MIDB::ServerController.config['dbpassword']}."
57
- when :apikey then "Private API key: #{MIDB::ServerController.config['apikey']}"
58
- else "Error??"
59
- end
60
- puts msg
61
- end
33
+ # Send some info
34
+ #
35
+ # @param what [Symbol] What to show the information for.
36
+ # @param info [Array<String>] Extra information needed for the message.
37
+ def self.info(what, info=nil)
38
+ msg = case what
39
+ when :start then "Server started on port #{info}. Listening for connections..."
40
+ when :incoming_request then "> Incoming request from #{info}."
41
+ when :request then ">> Request method: #{info[0]}\n>>> Endpoint: #{info[1]}"
42
+ when :match_json then ">> The request matched a JSON file: #{info}.json\n>> Creating response..."
43
+ when :response then ">> Sending JSON response (RAW):\n#{info}"
44
+ when :success then "> Successfully managed this request!"
45
+ when :not_found then "> Invalid endpoint - sending a 404 error."
46
+ when :auth_required then ">> Authentication required. Checking for the HTTP header..."
47
+ when :no_auth then ">> No authentication header - sending a 401 error."
48
+ when :auth_success then ">> Successfully authenticated the request."
49
+ when :bootstrap then "> Successfully bootstraped!"
50
+ end
51
+ puts msg
52
+ end
53
+
54
+ # Output some config
55
+ #
56
+ # @param what [Symbol] What to show the config for.
57
+ # @param cnf [Array<String>] The array for the config.
58
+ def self.out_config(what, cnf)
59
+ msg = case what
60
+ when :dbengine then "Database engine: #{cnf['dbengine']}."
61
+ when :dbhost then "Database server host: #{cnf['dbhost']}."
62
+ when :dbport then "Database server port: #{cnf['dbport']}."
63
+ when :dbuser then "Database server user: #{cnf['dbuser']}."
64
+ when :dbpassword then "Database server password: #{cnf['dbpassword']}."
65
+ when :apikey then "Private API key: #{cnf['apikey']}"
66
+ else "Error??"
67
+ end
68
+ puts msg
69
+ end
62
70
 
63
- # Method: help
64
- # Shows the help
65
- def self.help(what)
66
- case what
67
- when :list
68
- puts "midb has several commands that you can use. For detailed information, see `midb help command`."
69
- puts " "
70
- puts "bootstrap\tCreate the basic files and directories that midb needs to be ran in a folder."
71
- puts "set\tModify this project's settings. See the detailed help for a list of options."
72
- puts "serve\tServes a JSON file - creates an API endpoint."
73
- puts "unserve\tStops serving a JSON file - the endpoint is no longer valid."
74
- puts "start\tStarts an API server. See detailed help for more."
75
- when :bootstrap
76
- puts "This command creates the `.midb.yaml` config file, and the `db` and `json` directories if they don't exist."
77
- puts "You must bootstrap before running any other commands."
78
- when :set
79
- puts "Sets config options. If no value is given, it shows the current value."
80
- puts "db:host\tHost name of the database (for MySQL)"
81
- puts "db:user\tUsername for the database (for MySQL)"
82
- puts "db:password\tPassword for the database (for MySQL)"
83
- puts "db:engine\t(sqlite3, mysql) Changes the database engine."
84
- puts "api:key\tChanges the private API key, used for authentication over HTTP."
85
- when :serve
86
- puts "This command will create an API endpoint pointing to a JSON file in the json/ directory."
87
- puts "It will support GET, POST, PUT and DELETE requests."
88
- puts "For detailed information on how to format your file, see the GitHub README and/or wiki."
89
- when :unserve
90
- puts "Stops serving a JSON file under the json/ directory."
91
- when :start
92
- puts "Starts the server. You must run the serve/unserve commands beforehand, so to set some endpoints."
93
- puts "Options:"
94
- puts "db:DATABASE\tSets DATABASE as the database where to get the data. Mandatory."
95
- puts "port:PORT\tSets PORT as the port where the server will listen to. Default: 8081."
71
+ # Shows the help
72
+ #
73
+ # @param what [Symbol] What to show the help for.
74
+ def self.help(what)
75
+ case what
76
+ when :list
77
+ puts "midb has several commands that you can use. For detailed information, see `midb help command`."
78
+ puts " "
79
+ puts "bootstrap\tCreate the basic files and directories that midb needs to be ran in a folder."
80
+ puts "set\tModify this project's settings. See the detailed help for a list of options."
81
+ puts "serve\tServes a JSON file - creates an API endpoint."
82
+ puts "unserve\tStops serving a JSON file - the endpoint is no longer valid."
83
+ puts "start\tStarts an API server. See detailed help for more."
84
+ when :bootstrap
85
+ puts "This command creates the `.midb.yaml` config file, and the `db` and `json` directories if they don't exist."
86
+ puts "You must bootstrap before running any other commands."
87
+ when :set
88
+ puts "Sets config options. If no value is given, it shows the current value."
89
+ puts "db:host\tHost name of the database (for MySQL)"
90
+ puts "db:user\tUsername for the database (for MySQL)"
91
+ puts "db:password\tPassword for the database (for MySQL)"
92
+ puts "db:engine\t(sqlite3, mysql) Changes the database engine."
93
+ puts "api:key\tChanges the private API key, used for authentication over HTTP."
94
+ when :serve
95
+ puts "This command will create an API endpoint pointing to a JSON file in the json/ directory."
96
+ puts "It will support GET, POST, PUT and DELETE requests."
97
+ puts "For detailed information on how to format your file, see the GitHub README and/or wiki."
98
+ when :unserve
99
+ puts "Stops serving a JSON file under the json/ directory."
100
+ when :start
101
+ puts "Starts the server. You must run the serve/unserve commands beforehand, so to set some endpoints."
102
+ puts "Options:"
103
+ puts "db:DATABASE\tSets DATABASE as the database where to get the data. Mandatory."
104
+ puts "port:PORT\tSets PORT as the port where the server will listen to. Default: 8081."
105
+ end
96
106
  end
97
107
  end
98
108
  end
@@ -11,11 +11,11 @@ require 'json'
11
11
  require 'sqlite3'
12
12
 
13
13
  module MIDB
14
- # @author unrar
15
- # This class handles runs the server engine using sockets and a loop.
16
- class ServerEngineController
17
- # Attribute declaration here
18
- class << self
14
+ module API
15
+ # @author unrar
16
+ # This class handles runs the server engine using sockets and a loop.
17
+ class Engine
18
+ # Attribute declaration here
19
19
  # @!attribute config
20
20
  # @return [Hash] Contains the project's configuration, saved in .midb.yaml
21
21
  # @!attribute db
@@ -23,127 +23,135 @@ module MIDB
23
23
  # @!attribute http_status
24
24
  # @return [String] HTTP status code and string representation for the header
25
25
  attr_accessor :config, :db, :http_status
26
- end
27
26
 
27
+ # Constructor
28
+ #
29
+ # @param db [String] Database to which the server will bind.
30
+ # @param stat [Fixnum] HTTP Status
31
+ # @param cnf [Hash] Config from the server controller.
32
+ def initialize(db, stat, cnf)
33
+ @config = cnf
34
+ @db = db
35
+ @http_status = stat
36
+ end
28
37
 
29
- # Starts the server on a given port (default: 8081)
30
- #
31
- # @param port [Fixnum] Port to which the server will listen.
32
- def self.start(port=8081)
33
- # Copy these values from the server controller
34
- @http_status = MIDB::ServerController.http_status
35
- @config = MIDB::ServerController.config
36
- @db = MIDB::ServerController.db
37
- serv = TCPServer.new("localhost", port)
38
- MIDB::ServerView.info(:start, port)
39
-
40
- # Manage the requests
41
- loop do
42
- socket = serv.accept
43
- MIDB::ServerView.info(:incoming_request, socket.addr[3])
44
-
45
- request = self.parse_request(socket.gets)
46
-
47
- # Get a hash with the headers
48
- headers = {}
49
- while line = socket.gets.split(' ', 2)
50
- break if line[0] == ""
51
- headers[line[0].chop] = line[1].strip
52
- end
53
- data = socket.read(headers["Content-Length"].to_i)
38
+ # Starts the server on a given port (default: 8081)
39
+ #
40
+ # @param port [Fixnum] Port to which the server will listen.
41
+ def start(port=8081)
42
+ serv = TCPServer.new("localhost", port)
43
+ MIDB::Interface::Server.info(:start, port)
44
+
45
+ # Manage the requests
46
+ loop do
47
+ socket = serv.accept
48
+ MIDB::Interface::Server.info(:incoming_request, socket.addr[3])
49
+
50
+ request = self.parse_request(socket.gets)
51
+
52
+ # Get a hash with the headers
53
+ headers = {}
54
+ while line = socket.gets.split(' ', 2)
55
+ break if line[0] == ""
56
+ headers[line[0].chop] = line[1].strip
57
+ end
58
+ data = socket.read(headers["Content-Length"].to_i)
54
59
 
55
60
 
56
- MIDB::ServerView.info(:request, request)
57
- response_json = Hash.new()
61
+ MIDB::Interface::Server.info(:request, request)
62
+ response_json = Hash.new()
58
63
 
59
- # Endpoint syntax: ["", FILE, ID, (ACTION)]
60
- endpoint = request[1].split("/")
61
- ep_file = endpoint[1]
64
+ # Endpoint syntax: ["", FILE, ID, (ACTION)]
65
+ endpoint = request[1].split("/")
66
+ ep_file = endpoint[1]
62
67
 
63
- method = request[0]
64
- endpoints = [] # Valid endpoints
68
+ method = request[0]
69
+ endpoints = [] # Valid endpoints
65
70
 
66
- # Load the JSON served files
67
- @config["serves"].each do |js|
68
- # The filename is a valid endpoint
69
- endpoints.push File.basename(js, ".*")
70
- end
71
+ # Load the JSON served files
72
+ @config["serves"].each do |js|
73
+ # The filename is a valid endpoint
74
+ endpoints.push File.basename(js, ".*")
75
+ end
71
76
 
72
- # Load the endpoints
73
- found = false
74
- endpoints.each do |ep|
75
- if ep_file == ep
76
- found = true
77
- MIDB::ServerView.info(:match_json, ep)
78
- # Analyze the request and pass it to the model
79
- if method == "GET"
80
- case endpoint.length
81
- when 2
82
- # No ID has been specified. Return all the entries
83
- # Pass it to the model and get the JSON
84
- response_json = MIDB::ServerModel.get_all_entries(@db, ep).to_json
85
- when 3
86
- # An ID has been specified. Should it exist, return all of its entries.
87
- response_json = MIDB::ServerModel.get_entries(@db, ep, endpoint[2]).to_json
88
- end
89
- else
90
- # An action has been specified. We're going to need HTTP authentification here.
91
- MIDB::ServerView.info(:auth_required)
77
+ # Load the endpoints
78
+ found = false
79
+ endpoints.each do |ep|
80
+ if ep_file == ep
81
+ found = true
82
+ MIDB::Interface::Server.info(:match_json, ep)
83
+ # Create the model
84
+ dbop = MIDB::API::Model.new(ep, @db, self)
85
+ # Analyze the request and pass it to the model
86
+ if method == "GET"
87
+ case endpoint.length
88
+ when 2
89
+ # No ID has been specified. Return all the entries
90
+ # Pass it to the model and get the JSON
91
+ response_json = dbop.get_all_entries().to_json
92
+ when 3
93
+ # An ID has been specified. Should it exist, return all of its entries.
94
+ response_json = dbop.get_entries(endpoint[2]).to_json
95
+ end
96
+ else
97
+ # An action has been specified. We're going to need HTTP authentification here.
98
+ MIDB::Interface::Server.info(:auth_required)
92
99
 
93
- if (not headers.has_key? "Authentication") ||
94
- (not MIDB::SecurityController.check?(headers["Authentication"], data, @config["apikey"]))
95
- @http_status = "401 Unauthorized"
96
- response_json = MIDB::ServerView.json_error(401, "Unauthorized").to_json
97
- MIDB::ServerView.info(:no_auth)
100
+ if (not headers.has_key? "Authentication") ||
101
+ (not MIDB::API::Security.check?(headers["Authentication"], data, @config["apikey"]))
102
+ @http_status = "401 Unauthorized"
103
+ response_json = MIDB::Interface::Server.json_error(401, "Unauthorized").to_json
104
+ MIDB::Interface::Server.info(:no_auth)
98
105
 
99
- else
100
- MIDB::ServerView.info(:auth_success)
101
- if method == "POST"
102
- response_json = MIDB::ServerModel.post(@db, ep, data).to_json
103
106
  else
104
- if endpoint.length >= 3
105
- if method == "DELETE"
106
- response_json = MIDB::ServerModel.delete(@db, ep, endpoint[2]).to_json
107
- elsif method == "PUT"
108
- response_json = MIDB::ServerModel.put(@db, ep, endpoint[2], data).to_json
109
- end
107
+ MIDB::Interface::Server.info(:auth_success)
108
+ if method == "POST"
109
+ response_json = dbop.post(data).to_json
110
110
  else
111
- @http_status = "404 Not Found"
112
- response_json = MIDB::ServerView.json_error(404, "Must specify an ID.").to_json
111
+ if endpoint.length >= 3
112
+ if method == "DELETE"
113
+ response_json = dbop.delete(endpoint[2]).to_json
114
+ elsif method == "PUT"
115
+ response_json = dbop.put(endpoint[2], data).to_json
116
+ end
117
+ else
118
+ @http_status = "404 Not Found"
119
+ response_json = MIDB::Interface::Server.json_error(404, "Must specify an ID.").to_json
120
+ end
113
121
  end
114
122
  end
115
123
  end
124
+ MIDB::Interface::Server.info(:response, response_json)
125
+ # Return the results via HTTP
126
+ socket.print "HTTP/1.1 #{@http_status}\r\n" +
127
+ "Content-Type: text/json\r\n" +
128
+ "Content-Length: #{response_json.size}\r\n" +
129
+ "Connection: close\r\n"
130
+ socket.print "\r\n"
131
+ socket.print response_json
132
+ socket.print "\r\n"
133
+ MIDB::Interface::Server.info(:success)
116
134
  end
117
- MIDB::ServerView.info(:response, response_json)
118
- # Return the results via HTTP
119
- socket.print "HTTP/1.1 #{@http_status}\r\n" +
120
- "Content-Type: text/json\r\n" +
121
- "Content-Length: #{response_json.size}\r\n" +
122
- "Connection: close\r\n"
123
- socket.print "\r\n"
124
- socket.print response_json
135
+ end
136
+ unless found
137
+ MIDB::Interface::Server.info(:not_found)
138
+ response = MIDB::Interface::Server.json_error(404, "Invalid API endpoint.").to_json
139
+
140
+ socket.print "HTTP/1.1 404 Not Found\r\n" +
141
+ "Content-Type: text/json\r\n" +
142
+ "Content-Length: #{response.size}\r\n" +
143
+ "Connection: close\r\n"
125
144
  socket.print "\r\n"
126
- MIDB::ServerView.info(:success)
145
+ socket.print response
127
146
  end
128
147
  end
129
- unless found
130
- MIDB::ServerView.info(:not_found)
131
- response = MIDB::ServerView.json_error(404, "Invalid API endpoint.").to_json
132
-
133
- socket.print "HTTP/1.1 404 Not Found\r\n" +
134
- "Content-Type: text/json\r\n" +
135
- "Content-Length: #{response.size}\r\n" +
136
- "Connection: close\r\n"
137
- socket.print "\r\n"
138
- socket.print response
139
- end
140
148
  end
141
- end
142
149
 
143
- # Method: parse_request
144
- # Parses an HTTP requests and returns an array [method, uri]
145
- def self.parse_request(req)
146
- [req.split(" ")[0], req.split(" ")[1]]
150
+ # Method: parse_request
151
+ # Parses an HTTP requests and returns an array [method, uri]
152
+ def parse_request(req)
153
+ [req.split(" ")[0], req.split(" ")[1]]
154
+ end
147
155
  end
148
156
  end
149
157
  end
data/lib/midb.rb CHANGED
@@ -4,4 +4,5 @@ require 'midb/security_controller'
4
4
  require 'midb/server_controller'
5
5
  require 'midb/server_model'
6
6
  require 'midb/server_view'
7
- require 'midb/serverengine_controller'
7
+ require 'midb/serverengine_controller'
8
+ require 'midb/hooks'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: midb
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.5
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - unrar
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-11-07 00:00:00.000000000 Z
11
+ date: 2015-11-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: mysql2
@@ -102,6 +102,7 @@ files:
102
102
  - lib/midb.rb
103
103
  - lib/midb/dbengine_model.rb
104
104
  - lib/midb/errors_view.rb
105
+ - lib/midb/hooks.rb
105
106
  - lib/midb/security_controller.rb
106
107
  - lib/midb/server_controller.rb
107
108
  - lib/midb/server_model.rb