root/captcha.scm

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
(define-module (hidamari-blue captcha)
  #:use-module (guix packages)
  #:use-module (guix download)
  #:use-module (guix records)
  #:use-module (ice-9 match)
  #:use-module (guix gexp)
  #:use-module (gnu services)
  #:use-module (gnu services shepherd)
  #:use-module (gnu services web)
  #:use-module (gnu system shadow)
  #:use-module (gnu packages admin)
  #:use-module (gnu packages web)
  #:use-module (gnu packages base)
  
  #:use-module (guix build-system gnu)
  #:use-module ((guix licenses) #:prefix license:)
  #:use-module (gnu packages guile)
  #:export (captcha-configuration
	    captcha
	    captcha-service-type
	    captcha-nginx-block))

(define captcha
  (package
   (name "captcha")
   (version "0.2")
   (source (origin
            (method url-fetch)
            (uri (string-append "https://hidamari.blue/git/captcha/release/captcha-" version
                                ".tar.bz2"))
            (sha256
             (base32
              "0wpnpnxvf3469y2c8vi7avg2qckzbbylbddvqqzrg0dw576lgjwj"))))
   (build-system gnu-build-system)
   (arguments
    `(#:phases
      (modify-phases
       %standard-phases
       (delete 'configure)
       ;; TODO build with autotools
       (delete 'build)
       (delete 'check)
       (replace
        'install
        (lambda*
	 (#:key outputs #:allow-other-keys)
	 (define out (string-append (assoc-ref %outputs "out")))

	 (call-with-output-file "run-captcha.sh"
	   (lambda (port)
	     (display
	      (string-append
	       "#!" (which "sh") "\n"
	       "GUILE_LOAD_COMPILED_PATH=" (getenv "GUILE_LOAD_COMPILED_PATH")
	       " GUILE_LOAD_PATH=" (getenv "GUILE_LOAD_PATH")
	       " " (which "guile") "--no-auto-compile -L " out " -e main-fibers"  " -s " out "/main.scm")
	      port)))
	 (chmod "run-captcha.sh" #o555)
		 
          (copy-recursively "." out)
          #t)))))
   (inputs `(("guile" ,guile-2.2)
	     ("guile-fibers" ,guile-fibers)))
   (native-inputs `(("which" ,which)))
   (synopsis "web captcha server")
   (description "captcha with 2hus")
   (home-page "http://captcha.hidamari-blue")
   (license license:agpl3)))


(define-record-type* <captcha-configuration> captcha-configuration
  make-captcha-configuration
  captcha-configuration?
  (captcha captcha-configuration-captcha ;<package>
	   (default captcha))
  (guile   captcha-configuration-guile ;<package>
	   (default guile-2.2)))

(define captcha-shepherd-service
  (match-lambda
   (($ <captcha-configuration> captcha guile)
    ;; TODO get user from config user 
     (let ((user "captcha")
	   (group "captcha"))
       (list (shepherd-service
		      (provision '(captcha))
		      (documentation "Run the captcha web service.")
		      (requirement '(networking))
		      (start #~(make-forkexec-constructor
				'(;; #$(file-append guix "/bin/guix" "environment" "captcha" "--")
				  ;; #$(file-append guile "/bin/guile")
				  ;;   "-L" #$captcha
				  ;;   "-e" "main-fibers"
				  ;;   "-s"
				  ;;   #$(file-append captcha "/main.scm")
				  #$captcha "/run-captcha.sh"
				    )
				#:user #$user #:group #$group))
		      (stop #~(make-kill-destructor))))))))

(define (captcha-accounts _)
  (filter identity
	  (list
	   (user-group
	    (name "captcha")
	    (system? #t))
	   (user-account
	    (name "captcha")
	    (group "captcha")
	    (system? #t)
	    (comment "web captcha user")
	    (home-directory "/var/empty")
	    (shell (file-append shadow "/sbin/nologin"))))))

(define (captcha-nginx-block site-domain)
  ;; TODO custom paths and ssl
  (nginx-server-configuration
   (server-name (list site-domain))
   (root "/var/www/captcha/")
   ;; (http-port #f)
   (ssl-certificate
    "/etc/letsencrypt/live/captcha.hidamari.blue/fullchain.pem")
   (ssl-certificate-key
    "/etc/letsencrypt/live/captcha.hidamari.blue/privkey.pem")
   (server-tokens? #f)
   (locations
    (list
     (nginx-location-configuration
      (uri "/file")
      (body (list "alias /var/www/captcha/file;")))
     (nginx-location-configuration
      (uri "/private")
      (body (list "deny all;")))
     (nginx-location-configuration
      (uri "/")
      (body (list
	     "if ($scheme = http) {"
	     "    return 301 https://$host$request_uri;"
	     "}"
	     "proxy_pass http://127.0.0.1:8084;"
	     "proxy_set_header Host $host;"
	     "proxy_set_header X-Real-IP $remote_addr;"
	     "proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;")))))))

(define captcha-service-type
  (service-type (name 'captcha)
                (extensions
                 (list (service-extension shepherd-root-service-type
                                          captcha-shepherd-service)
		       ;; TODO write init/activation extension for captcha-population
		       (service-extension account-service-type
                                          captcha-accounts)
		       ))
                (default-value (captcha-configuration))))