diff --git a/src/auth_handler.cr b/src/auth_handler.cr index 3e2c68b..f026e80 100644 --- a/src/auth_handler.cr +++ b/src/auth_handler.cr @@ -1,15 +1,25 @@ require "kemal" +require "./storage" class AuthHandler < Kemal::Handler exclude ["/login"] + exclude ["/login"], "POST" + + property storage : Storage + + def initialize(@storage) + end + def call(env) return call_next(env) if exclude_match?(env) - my_cookie = HTTP::Cookie.new( - name: "Example", - value: "KemalCR" - ) - env.response.cookies << my_cookie - pp env.request.cookies + env.request.cookies.each do |c| + next if c.name != "token" + if @storage.verify_token c.value + return call_next env + end + end + + env.redirect "/login" end end diff --git a/src/library.cr b/src/library.cr index b4ed5de..a004b6f 100644 --- a/src/library.cr +++ b/src/library.cr @@ -1,4 +1,14 @@ require "zip" +require "mime" + +class Image + property data : Bytes + property mime : String + property filename : String + property size : Int32 + def initialize(@data, @mime, @filename, @size) + end +end class Entry property zip_path : String @@ -10,6 +20,29 @@ class Entry @title = File.basename path, ".zip" @size = (File.size path).humanize_bytes end + def read_page(page_num) + Zip::File.open @zip_path do |file| + page = file.entries + .select { |e| + ["image/jpeg", "image/png"].includes? \ + MIME.from_filename? e.filename + } + .sort { |a, b| a.filename <=> b.filename } + .[page_num] + page.open do |io| + slice = Bytes.new page.uncompressed_size + bytes_read = io.read_fully? slice + unless bytes_read + return nil + end + return Image.new slice, MIME.from_filename(page.filename),\ + page.filename, bytes_read + end + end + end + def get_cover() + read_page 0 + end end class Title @@ -25,6 +58,9 @@ class Title .map { |path| Entry.new File.join dir, path } .sort { |a, b| a.title <=> b.title } end + def get_cover() + @entries[0].get_cover + end end class Library diff --git a/src/mango.cr b/src/mango.cr index d992839..d52a2d2 100644 --- a/src/mango.cr +++ b/src/mango.cr @@ -5,21 +5,47 @@ require "./storage" require "./auth_handler" config = Config.load - library = Library.new config.library_path - storage = Storage.new config.db_path -get "/" do - "Hello World!" + +macro layout(name) + render "src/views/#{{{name}}}.ecr", "src/views/layout.ecr" end -# APIs -get "/api/test" do |env| - "Hello!" +macro send_img(env, img) + send_file env, image.data, image.mime end -add_handler AuthHandler.new + +get "/" do |env| + image = library.titles[0].get_cover + unless image + "Failed to load image" + next + end + send_img env, image +end + +get "/login" do |env| + render "src/views/login.ecr" +end + +post "/login" do |env| + username = env.params.body["username"] + password = env.params.body["password"] + token = storage.verify_user username, password + if token.nil? + env.redirect "/login" + next + end + + cookie = HTTP::Cookie.new "token", token + env.response.cookies << cookie + env.redirect "/" +end + +add_handler AuthHandler.new storage Kemal.config.port = config.port Kemal.run diff --git a/src/views/layout.ecr b/src/views/layout.ecr new file mode 100644 index 0000000..79a9c2f --- /dev/null +++ b/src/views/layout.ecr @@ -0,0 +1,24 @@ + + + + + + Mango + + + + + + + +
+

Hello !

+
+
+ <%= content %> +
+ + + + + diff --git a/src/views/login.ecr b/src/views/login.ecr new file mode 100644 index 0000000..558fe94 --- /dev/null +++ b/src/views/login.ecr @@ -0,0 +1,38 @@ + + + + + + Mango + + + + + + +
+
+
+
+
+
+

Log In

+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ + + +