index.scm 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293
  1. (add-to-load-path (dirname (current-filename)))
  2. (use-modules
  3. (ice-9 textual-ports)
  4. (ice-9 regex)
  5. (html-elements)
  6. ;;(dbi dbi)
  7. (decode)
  8. (web server)
  9. (web request)
  10. (web response)
  11. (web uri)
  12. (oop goops)
  13. (sxml simple)
  14. ;; (srfi srfi-19)
  15. )
  16. (define navbar
  17. '(nav (@ (class "navbar navbar-expand-lg navbar-light bg-light"))
  18. (a (@ (class "navbar-brand")) "Auto Assign")
  19. (button (@ (class "navbar-toggler")
  20. (type "button")
  21. (data-toggle "collapse")
  22. (data-target "#navbarSupportedContent")
  23. (aria-controls "navbarSupportedContent")
  24. (aria-expanded "false")
  25. (aria-label "Toggle navigation"))
  26. (span (@ (class "navbar-toggler-icon"))))
  27. (div (@ (class "collapse navbar-collapse")
  28. (id "navbarSupportedcontent"))
  29. (ul (@ (class ("navbar-nav mr-auto")))
  30. (li (@ (class "nav-item active"))
  31. (a (@ (class "nav-link")
  32. (href "about"))
  33. "About"))
  34. (li (@ (class "nav-item"))
  35. (a (@ (class "nav-link")
  36. (href "login"))
  37. "Log In"))
  38. (li (@ (class "nav-item"))
  39. (a (@ (class "nav-link")
  40. (href "sign-up"))
  41. "Sign Up"))
  42. ))))
  43. (define* (templatize title body
  44. #:key
  45. (js-files #f))
  46. `(html (head (title ,title)
  47. (head
  48. (link (@ (type "text/css") (href "css/style.min.css") (rel "stylesheet")) "")
  49. ,(if js-files
  50. `(script (@ (async) (src ,(string-append "js/" js-files))) " ")
  51. `(link (@ (type "text/css") (href "#")) ""))
  52. )
  53. (body ,navbar ,@body))
  54. (footer (p "@c copyright 2020."))))
  55. (define* (respond #:optional body #:key
  56. (status 200)
  57. (title "My IFT")
  58. (doctype "<!DOCTYPE html>\n")
  59. (content-type-params '((charset . "utf-8")))
  60. (content-type 'text/html)
  61. (extra-headers '())
  62. (js-files #f)
  63. (sxml (and body (if js-files
  64. (templatize title body #:js-files js-files)
  65. (templatize title body)))))
  66. (values (build-response
  67. #:code status
  68. #:headers `((content-type
  69. . (,content-type ,@content-type-params))
  70. ,@extra-headers))
  71. (lambda (port)
  72. (if sxml
  73. (begin
  74. (if doctype (display doctype port))
  75. (sxml->xml sxml port))))))
  76. (define (request-path-components request)
  77. (split-and-decode-uri-path (uri-path (request-uri request))))
  78. ;; Paste this in your REPL
  79. (define (not-found request)
  80. (values (build-response #:code 404)
  81. (string-append "Resource not found: "
  82. (uri->string (request-uri request)))))
  83. (define (main-page)
  84. (respond
  85. `((div (@ (class "container"))
  86. (div (@ (class "row"))
  87. (div (@ (class "col-md-12"))
  88. (h1 "Assign copyright to GNU today!")
  89. (p "AutoAssign lets you digitally assign copyright
  90. to the GNU project! Let's keep free software libre!")
  91. (p "Assigning copyright is as easy as creating an
  92. account, and digitally signing your signature!")))))))
  93. (define (about)
  94. (respond
  95. `((div (@ (class "container"))
  96. (div (@ (class "row"))
  97. (div (@ (class "col-md-12"))
  98. (h3 "What is GNU AutoAssign?")
  99. (p "GNU AutoAssign lets you digitally assign
  100. copyright to the Free Software Foundation (FSF). Developers have an easy
  101. way of assigning copyright, and maintainers of GNU software can easily
  102. verify who has copyright on file.")
  103. (h3 "What is the GNU Project?")
  104. (p "The " (a (@ (href "#")) "GNU Project") " was
  105. started by Richard Stallman in the early 80s to create an ethical
  106. operating system, that preserves your software freedom. The goal of
  107. the GNU project has largely been realized, and further work is
  108. ongoing. Many such distributions "
  109. (a (@ (href "#")) "exist today.")
  110. " You should try one!")
  111. (h3 "What is the Free Software Foundation?")
  112. (p "The " (a (@ (href "#")) "Free Software
  113. Foundation") " (FSF) is the legal entity behind the GNU project. They are
  114. the non-profit that is responsible for running various freedom
  115. software campaigns and occasion legal enforcement of the GNU General
  116. Public License, which is an ethical software license.")
  117. (h3 "Why should I assign copyright to the FSF?")
  118. (p "Because the GNU General Public License is not
  119. magic fairy dust. In order to preserve software freedom, you
  120. occasionally need to legally enforce it. This can only be done by
  121. those who hold the copyright to the source code. The best way to
  122. enforce the GNU GPL, is having one entity that enforces copyright.
  123. The best non-profit to do that has always been and will always be the
  124. Free Software Foundation, which is the legal entity behind the GNU
  125. project.")
  126. (h3 "But I prefer non-copyleft licenses. Like the MIT license.")
  127. (p "You are always free to use non-copyleft
  128. licenses, but non-copyleft licenses always produce some proprietary
  129. software. Take a look at EXAMPLE, EXAMPLE, and EXAMPLE. Since these
  130. programs are \"open source\" and not free software, but there exist
  131. proprietary versions. Only copyleft software liberates user
  132. freedom.")
  133. (h3 "But you can't make money with the GPL!")
  134. (p "Take a look at NextCloud, RedHat, and EXAMPLE.
  135. These businesses all use GPL licensed software. They are successful
  136. businesses.")))))
  137. ))
  138. ;; currently using a cope pen for the signature
  139. ;; https://codepen.io/dus7/pen/qGQbVP
  140. (define (sign-up)
  141. (respond
  142. `((div (@ (class "container"))
  143. (div (@ (class "row"))
  144. (div (@ (class "col-md-12"))
  145. (p "Assign now")
  146. (form (@ (action "sign-up-process") (method "post"))
  147. (ul
  148. ,(form-item "First name")
  149. ,(form-item "Middle Name")
  150. ,(form-item "Last Name")
  151. ,(form-item "email" #:input-type "email")
  152. (fieldset
  153. (legend "Assign to one GNU program.")
  154. ,(form-item "Program to Assign" #:input-type "select" #:options '("Emacs" "Gimp" "Sed")))
  155. (fieldset
  156. (legend "I love GNU! Let me assign all my code to all GNU programs!")
  157. ,(form-item "Assign copyright to all GNU programs" #:input-type "checkbox"))
  158. (fieldset
  159. (legend "Your current employer")
  160. ,(form-item "Are you currently employed?" #:input-type "checkbox")
  161. ,(form-item "Do you work for the software industry?"
  162. #:input-type "checkbox")
  163. ,(form-item "Might your employer claim credit
  164. for the software or documentation you produce?"
  165. #:input-type "checkbox")
  166. (p "The next few questions need to be
  167. answered by your current employeer. You will need to talk to someone
  168. from licensing from your company, or your companies lawyers.")
  169. ;; ,(form-item "Do you consent to waive all copyright claims to the
  170. ;; developer?" #:input-type ("radio"))
  171. )
  172. (li (@ (for "sig-canvas"))
  173. "Signature"
  174. (canvas (@ (id "sig-canvas") (width "850") (height "260")) (span)))
  175. (li (button (@ (type "sumbit") (id "sig-submitBtn")) "Submit"))
  176. (li (button (@ (type "sumbit") (id "sig-clearBtn")) "Clear Signature"))))))))
  177. #:js-files "signature.js"))
  178. (define (login)
  179. (respond
  180. `((div (@ (class "container"))
  181. (div (@ (class "row"))
  182. (div (@ (class "col-md-12"))
  183. (section
  184. (h3 "Login"
  185. (form (@ (action "login-process") (method "post"))
  186. (ul
  187. ,(form-item "email" #:input-type "email" #:placeholder "rodgerpirate@dismail.de")
  188. ,(form-item "password" #:input-type "password" #:placeholder "aVerySecretPassword?")
  189. ,(my-input "honeypot" #:input-type "hidden")
  190. ,(my-input "timestamp" #:input-type "hidden"
  191. #:value (string-append
  192. (number->string (car (gettimeofday)))
  193. " "
  194. (number->string (cdr (gettimeofday)))))
  195. (li (button (@ (type "submit")) "Submit"))))))
  196. ))))))
  197. (define (login-process bv)
  198. (respond
  199. `((div (@ (class "container"))
  200. (div (@ (class "row"))
  201. (div (@ (class "col-md-12"))
  202. ,(let* ([alist (decode bv)]
  203. [form-timestamp-pair
  204. (string-split (car (assoc-ref alist "timestamp")) #\space)]
  205. [form-timestamp-seconds (car form-timestamp-pair)]
  206. [form-timestamp-microseconds (car (cdr form-timestamp-pair))]
  207. [timestamp (gettimeofday)]
  208. [timestamp-seconds (car timestamp)]
  209. [timestamp-microseconds (cdr timestamp)]
  210. [form-completion-time-seconds
  211. (- (current-time) (string->number form-timestamp-seconds))]
  212. [form-completion-time-microseconds
  213. (abs (- timestamp-microseconds
  214. (string->number form-timestamp-microseconds)))]
  215. [honeypot (car (assoc-ref alist "honeypot"))]
  216. )
  217. ;; if this form was completed in under 200000 microseconds, then this may be a computer trying to log in
  218. ;; don't let them log in. OR if the honeypot had any value in it...
  219. (if (or (and (= 0 form-completion-time-seconds)
  220. (> 200000 form-completion-time-microseconds))
  221. (not (string= honeypot "")))
  222. '(p "We're having issues...please try again later.")
  223. `(p ,(string-append
  224. "It took you "
  225. (number->string form-completion-time-seconds)
  226. " seconds and "
  227. (number->string form-completion-time-microseconds)
  228. " microseconds to complete the form.\n")))
  229. )))))))
  230. (define (output-file file-name)
  231. (call-with-input-file file-name
  232. (lambda (port)
  233. (string-append
  234. ""
  235. (let loop ([string (get-line port)])
  236. (if (eof-object? string)
  237. ""
  238. (string-append
  239. string "\n" (loop (get-line port)))))))))
  240. (define (run-page request body)
  241. ;;(display (request-path-components request))
  242. (let ([current-page (request-path-components request)])
  243. (cond [(equal? current-page '())
  244. (main-page)]
  245. [(equal? current-page '("about"))
  246. (about)]
  247. [(equal? current-page '("login"))
  248. (login)]
  249. [(equal? current-page '("login-process"))
  250. (login-process body)]
  251. [(equal? current-page '("sign-up"))
  252. (sign-up)]
  253. [(equal? current-page '("css" "style.min.css"))
  254. (values `((content-type . (text/css)))
  255. (output-file "css/style.min.css"))]
  256. [(equal? current-page '("js" "signature.js"))
  257. (values `((content-type . (text/javascript)))
  258. (output-file "js/signature.js"))]
  259. [(equal? current-page '("hello"))
  260. (values `((content-type . (text/plain))
  261. )
  262. "Hello hacker!")]
  263. [else
  264. (respond `((h1 "Page not found.")
  265. (h1 ,(let loop ([current-page current-page])
  266. (if (null? current-page) ""
  267. (string-append (car current-page) "/"
  268. (loop (cdr current-page))))))
  269. (h2 ,current-page)))])))
  270. (run-server run-page 'http '(#:port 8081))