icfs 0.1.3 → 0.2.0
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 +4 -4
 - data/bin/icfs_demo_fcgi.rb +2 -0
 - data/{bin/icfs_demo_ssl_gen.rb → devel/demo/ssl_gen.rb} +25 -13
 - data/devel/demo/ssl_gen.yml +14 -0
 - data/devel/icfs-wrk/Dockerfile +1 -1
 - data/devel/run/base.rb +92 -0
 - data/devel/run/copy-s3.rb +2 -0
 - data/devel/run/email.rb +36 -0
 - data/devel/run/email_imap.rb +43 -0
 - data/devel/run/email_smime.rb +47 -0
 - data/devel/run/init-icfs.rb +2 -0
 - data/devel/run/webrick.rb +5 -57
 - data/lib/icfs/api.rb +101 -90
 - data/lib/icfs/cache.rb +2 -0
 - data/lib/icfs/cache_elastic.rb +127 -125
 - data/lib/icfs/{web/config.rb → config.rb} +3 -3
 - data/lib/icfs/{web/config_redis.rb → config_redis.rb} +8 -8
 - data/lib/icfs/{web/config_s3.rb → config_s3.rb} +8 -8
 - data/lib/icfs/demo/auth.rb +5 -7
 - data/lib/icfs/demo/static.rb +2 -0
 - data/lib/icfs/elastic.rb +10 -8
 - data/lib/icfs/email/basic.rb +242 -0
 - data/lib/icfs/email/core.rb +293 -0
 - data/lib/icfs/email/from.rb +52 -0
 - data/lib/icfs/email/imap.rb +148 -0
 - data/lib/icfs/email/smime.rb +139 -0
 - data/lib/icfs/items.rb +5 -3
 - data/lib/icfs/store.rb +20 -18
 - data/lib/icfs/store_fs.rb +7 -5
 - data/lib/icfs/store_s3.rb +4 -2
 - data/lib/icfs/users.rb +5 -3
 - data/lib/icfs/users_fs.rb +8 -6
 - data/lib/icfs/users_redis.rb +12 -10
 - data/lib/icfs/users_s3.rb +6 -4
 - data/lib/icfs/utils/backup.rb +30 -29
 - data/lib/icfs/utils/check.rb +36 -34
 - data/lib/icfs/validate.rb +24 -15
 - data/lib/icfs/web/auth_ssl.rb +7 -9
 - data/lib/icfs/web/client.rb +671 -679
 - data/lib/icfs.rb +174 -10
 - metadata +16 -7
 - data/devel/devel-webrick.yml +0 -49
 
    
        checksums.yaml
    CHANGED
    
    | 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            ---
         
     | 
| 
       2 
2 
     | 
    
         
             
            SHA256:
         
     | 
| 
       3 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       4 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 3 
     | 
    
         
            +
              metadata.gz: 28031e9c5c67e30c2cf4778fbf56a7840117d256e4384e6e044e7cc888958d09
         
     | 
| 
      
 4 
     | 
    
         
            +
              data.tar.gz: 3abea632e084b00bd09ac570710eab52e99a152d073c6f96779a04c23dbc1c21
         
     | 
| 
       5 
5 
     | 
    
         
             
            SHA512:
         
     | 
| 
       6 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       7 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 6 
     | 
    
         
            +
              metadata.gz: cd28dc30f59e5bec1b272508d5b64ecb950a3e2b6d26d4318156069d19c338093177302ac09207a4b76b7decfa8272f84a8839f3165eeee28fdb9f15ae5c6ef3
         
     | 
| 
      
 7 
     | 
    
         
            +
              data.tar.gz: '08f19a62a3d3c21cdf46c8120bd0b5846107a57409aba71939587affed4e7daf32c4d0bd805919d884baa4d24b520521527f62e8edf66ed6f886cf2237122b27'
         
     | 
    
        data/bin/icfs_demo_fcgi.rb
    CHANGED
    
    
| 
         @@ -10,15 +10,23 @@ 
     | 
|
| 
       10 
10 
     | 
    
         
             
            # This program is distributed WITHOUT ANY WARRANTY; without even the
         
     | 
| 
       11 
11 
     | 
    
         
             
            # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
         
     | 
| 
       12 
12 
     | 
    
         | 
| 
      
 13 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
       13 
15 
     | 
    
         
             
            require 'openssl'
         
     | 
| 
      
 16 
     | 
    
         
            +
            require 'yaml'
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
            # read the configuration
         
     | 
| 
      
 19 
     | 
    
         
            +
            cfg = YAML.load(File.read(ARGV[0]))
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
       14 
21 
     | 
    
         | 
| 
      
 22 
     | 
    
         
            +
            serial = Time.now.to_i
         
     | 
| 
       15 
23 
     | 
    
         | 
| 
       16 
     | 
    
         
            -
            # make a CA  
     | 
| 
      
 24 
     | 
    
         
            +
            # make a CA cert
         
     | 
| 
       17 
25 
     | 
    
         
             
            ca_key = OpenSSL::PKey::RSA.new 2048
         
     | 
| 
       18 
26 
     | 
    
         
             
            ca_cert = OpenSSL::X509::Certificate.new
         
     | 
| 
       19 
27 
     | 
    
         
             
            ca_cert.version = 2
         
     | 
| 
       20 
     | 
    
         
            -
            ca_cert.serial =  
     | 
| 
       21 
     | 
    
         
            -
            ca_cert.subject = OpenSSL::X509::Name.parse(' 
     | 
| 
      
 28 
     | 
    
         
            +
            ca_cert.serial = serial
         
     | 
| 
      
 29 
     | 
    
         
            +
            ca_cert.subject = OpenSSL::X509::Name.parse(cfg['ca']['cn'])
         
     | 
| 
       22 
30 
     | 
    
         
             
            ca_cert.issuer = ca_cert.subject
         
     | 
| 
       23 
31 
     | 
    
         
             
            ca_cert.public_key = ca_key.public_key
         
     | 
| 
       24 
32 
     | 
    
         
             
            ca_cert.not_before = Time.now
         
     | 
| 
         @@ -36,11 +44,11 @@ ca_cert.sign(ca_key, OpenSSL::Digest::SHA256.new) 
     | 
|
| 
       36 
44 
     | 
    
         
             
            File.open("ca_cert.pem", "wb"){|fi| fi.write ca_cert.to_pem }
         
     | 
| 
       37 
45 
     | 
    
         | 
| 
       38 
46 
     | 
    
         | 
| 
       39 
     | 
    
         
            -
            # make a server key
         
     | 
| 
      
 47 
     | 
    
         
            +
            # make a server cert & key
         
     | 
| 
       40 
48 
     | 
    
         
             
            srv_key = OpenSSL::PKey::RSA.new 2048
         
     | 
| 
       41 
49 
     | 
    
         
             
            srv_cert = OpenSSL::X509::Certificate.new
         
     | 
| 
       42 
50 
     | 
    
         
             
            srv_cert.version = 2
         
     | 
| 
       43 
     | 
    
         
            -
            srv_cert.serial =  
     | 
| 
      
 51 
     | 
    
         
            +
            srv_cert.serial = serial + 1
         
     | 
| 
       44 
52 
     | 
    
         
             
            srv_cert.subject = OpenSSL::X509::Name.parse('/OU=org/OU=example/OU=Test Server/CN=localhost')
         
     | 
| 
       45 
53 
     | 
    
         
             
            srv_cert.issuer = ca_cert.subject
         
     | 
| 
       46 
54 
     | 
    
         
             
            srv_cert.public_key = srv_key.public_key
         
     | 
| 
         @@ -52,19 +60,22 @@ ef.issuer_certificate = ca_cert 
     | 
|
| 
       52 
60 
     | 
    
         
             
            srv_cert.add_extension(ef.create_extension("basicConstraints", "CA:FALSE"))
         
     | 
| 
       53 
61 
     | 
    
         
             
            srv_cert.add_extension(ef.create_extension("keyUsage", "keyEncipherment,dataEncipherment,digitalSignature"))
         
     | 
| 
       54 
62 
     | 
    
         
             
            srv_cert.add_extension(ef.create_extension("subjectKeyIdentifier","hash",false))
         
     | 
| 
      
 63 
     | 
    
         
            +
            srv_cert.add_extension(ef.create_extension("subjectAltName", "email:%s" % cfg['server']['email'], false))
         
     | 
| 
       55 
64 
     | 
    
         
             
            srv_cert.sign(ca_key, OpenSSL::Digest::SHA256.new)
         
     | 
| 
       56 
65 
     | 
    
         | 
| 
       57 
     | 
    
         
            -
            # save server key
         
     | 
| 
      
 66 
     | 
    
         
            +
            # save server cert & key
         
     | 
| 
       58 
67 
     | 
    
         
             
            File.open("srv_cert.pem", "wb"){|fi| fi.write srv_cert.to_pem }
         
     | 
| 
       59 
68 
     | 
    
         
             
            File.open("srv_key.pem", "wb"){|fi| fi.write srv_key.to_pem }
         
     | 
| 
       60 
69 
     | 
    
         | 
| 
       61 
     | 
    
         
            -
            # make client certs
         
     | 
| 
       62 
     | 
    
         
            -
             
     | 
| 
      
 70 
     | 
    
         
            +
            # make client certs with key included
         
     | 
| 
      
 71 
     | 
    
         
            +
            cnt = 0
         
     | 
| 
      
 72 
     | 
    
         
            +
            cfg['clients'].each do |cc|
         
     | 
| 
      
 73 
     | 
    
         
            +
              cnt += 1
         
     | 
| 
       63 
74 
     | 
    
         
             
              clt_key = OpenSSL::PKey::RSA.new 2048
         
     | 
| 
       64 
75 
     | 
    
         
             
              clt_cert = OpenSSL::X509::Certificate.new
         
     | 
| 
       65 
76 
     | 
    
         
             
              clt_cert.version = 2
         
     | 
| 
       66 
     | 
    
         
            -
              clt_cert.serial =  
     | 
| 
       67 
     | 
    
         
            -
              clt_cert.subject = OpenSSL::X509::Name.parse(' 
     | 
| 
      
 77 
     | 
    
         
            +
              clt_cert.serial = serial + 2 + cnt
         
     | 
| 
      
 78 
     | 
    
         
            +
              clt_cert.subject = OpenSSL::X509::Name.parse(cc['cn'])
         
     | 
| 
       68 
79 
     | 
    
         
             
              clt_cert.issuer = ca_cert.subject
         
     | 
| 
       69 
80 
     | 
    
         
             
              clt_cert.public_key = clt_key.public_key
         
     | 
| 
       70 
81 
     | 
    
         
             
              clt_cert.not_before = Time.now
         
     | 
| 
         @@ -74,11 +85,12 @@ File.open("srv_key.pem", "wb"){|fi| fi.write srv_key.to_pem } 
     | 
|
| 
       74 
85 
     | 
    
         
             
              ef.issuer_certificate = ca_cert
         
     | 
| 
       75 
86 
     | 
    
         
             
              clt_cert.add_extension(ef.create_extension("basicConstraints", "CA:FALSE"))
         
     | 
| 
       76 
87 
     | 
    
         
             
              clt_cert.add_extension(ef.create_extension("keyUsage", "keyEncipherment,dataEncipherment,digitalSignature"))
         
     | 
| 
      
 88 
     | 
    
         
            +
              clt_cert.add_extension(ef.create_extension("subjectAltName", "email:%s" % cc['email'], false))
         
     | 
| 
       77 
89 
     | 
    
         
             
              clt_cert.sign(ca_key, OpenSSL::Digest::SHA256.new)
         
     | 
| 
       78 
90 
     | 
    
         | 
| 
       79 
91 
     | 
    
         
             
              # pkcs12
         
     | 
| 
       80 
     | 
    
         
            -
              clt_pkcs12 = OpenSSL::PKCS12.create('demo', 'client-%d' %  
     | 
| 
      
 92 
     | 
    
         
            +
              clt_pkcs12 = OpenSSL::PKCS12.create('demo', 'client-%d' % cnt, clt_key, clt_cert)
         
     | 
| 
       81 
93 
     | 
    
         | 
| 
       82 
     | 
    
         
            -
              # save cert
         
     | 
| 
       83 
     | 
    
         
            -
              File.open('clt_%d.pfx' %  
     | 
| 
      
 94 
     | 
    
         
            +
              # save cert w/key
         
     | 
| 
      
 95 
     | 
    
         
            +
              File.open('clt_%d.pfx' % cnt, 'wb'){|fi| fi.write clt_pkcs12.to_der }
         
     | 
| 
       84 
96 
     | 
    
         
             
            end
         
     | 
| 
         @@ -0,0 +1,14 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
             
     | 
| 
      
 2 
     | 
    
         
            +
            ca:
         
     | 
| 
      
 3 
     | 
    
         
            +
              cn: "/OU=org/OU=example/CN=Test Root CA"
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            server:
         
     | 
| 
      
 6 
     | 
    
         
            +
              cn: "/OU=org/OU=example/OU=Test Server/CN=localhost"
         
     | 
| 
      
 7 
     | 
    
         
            +
              email: "server@example.org"
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
            clients:
         
     | 
| 
      
 10 
     | 
    
         
            +
              - cn: "/OU=org/OU=example/OU=Test Client/CN=client 1"
         
     | 
| 
      
 11 
     | 
    
         
            +
                email: "client1@example.org"
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
              - cn: "/OU=org/OU=example/OU=Test Client/CN=client 2"
         
     | 
| 
      
 14 
     | 
    
         
            +
                email: "client2example.org"
         
     | 
    
        data/devel/icfs-wrk/Dockerfile
    CHANGED
    
    | 
         @@ -16,7 +16,7 @@ RUN apk update && \ 
     | 
|
| 
       16 
16 
     | 
    
         
             
                apk upgrade && \
         
     | 
| 
       17 
17 
     | 
    
         
             
                apk --update add ruby fcgi ruby-json tzdata vim curl git bash && \
         
     | 
| 
       18 
18 
     | 
    
         
             
                apk --update add --virtual build-deps ruby-dev build-base fcgi-dev && \
         
     | 
| 
       19 
     | 
    
         
            -
                gem install -N rack webrick etc faraday yard aws-sdk-s3 redis && \
         
     | 
| 
      
 19 
     | 
    
         
            +
                gem install -N rack webrick etc faraday yard aws-sdk-s3 redis mail && \
         
     | 
| 
       20 
20 
     | 
    
         
             
                apk del build-deps && \
         
     | 
| 
       21 
21 
     | 
    
         
             
                rm -rf /var/cache/apk/*
         
     | 
| 
       22 
22 
     | 
    
         | 
    
        data/devel/run/base.rb
    ADDED
    
    | 
         @@ -0,0 +1,92 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            #!/usr/bin/env ruby
         
     | 
| 
      
 2 
     | 
    
         
            +
            #
         
     | 
| 
      
 3 
     | 
    
         
            +
            # Investigative Case File System
         
     | 
| 
      
 4 
     | 
    
         
            +
            #
         
     | 
| 
      
 5 
     | 
    
         
            +
            # Copyright 2019 by Graham A. Field
         
     | 
| 
      
 6 
     | 
    
         
            +
            #
         
     | 
| 
      
 7 
     | 
    
         
            +
            # This program is free software: you can redistribute it and/or modify
         
     | 
| 
      
 8 
     | 
    
         
            +
            # it under the terms of the GNU General Public License version 3.
         
     | 
| 
      
 9 
     | 
    
         
            +
            #
         
     | 
| 
      
 10 
     | 
    
         
            +
            # This program is distributed WITHOUT ANY WARRANTY; without even the
         
     | 
| 
      
 11 
     | 
    
         
            +
            # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
            require 'faraday'
         
     | 
| 
      
 16 
     | 
    
         
            +
            require 'aws-sdk-s3'
         
     | 
| 
      
 17 
     | 
    
         
            +
            require 'redis'
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
            require_relative '../../lib/icfs'
         
     | 
| 
      
 20 
     | 
    
         
            +
            require_relative '../../lib/icfs/cache_elastic'
         
     | 
| 
      
 21 
     | 
    
         
            +
            require_relative '../../lib/icfs/store_s3'
         
     | 
| 
      
 22 
     | 
    
         
            +
            require_relative '../../lib/icfs/users_s3'
         
     | 
| 
      
 23 
     | 
    
         
            +
            require_relative '../../lib/icfs/users_redis'
         
     | 
| 
      
 24 
     | 
    
         
            +
            require_relative '../../lib/icfs/config_s3'
         
     | 
| 
      
 25 
     | 
    
         
            +
            require_relative '../../lib/icfs/config_redis'
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
            #################################################
         
     | 
| 
      
 28 
     | 
    
         
            +
            # Get the API
         
     | 
| 
      
 29 
     | 
    
         
            +
            #
         
     | 
| 
      
 30 
     | 
    
         
            +
            def get_base
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
              # the log
         
     | 
| 
      
 33 
     | 
    
         
            +
              log = Logger.new(STDERR)
         
     | 
| 
      
 34 
     | 
    
         
            +
              log.level = Logger::INFO
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
              # S3
         
     | 
| 
      
 37 
     | 
    
         
            +
              s3 = Aws::S3::Client.new(
         
     | 
| 
      
 38 
     | 
    
         
            +
                endpoint: 'http://minio:9000',
         
     | 
| 
      
 39 
     | 
    
         
            +
                access_key_id: 'minio_key',
         
     | 
| 
      
 40 
     | 
    
         
            +
                secret_access_key: 'minio_secret',
         
     | 
| 
      
 41 
     | 
    
         
            +
                force_path_style: true,
         
     | 
| 
      
 42 
     | 
    
         
            +
                region: 'us-east-1'
         
     | 
| 
      
 43 
     | 
    
         
            +
              )
         
     | 
| 
      
 44 
     | 
    
         
            +
             
     | 
| 
      
 45 
     | 
    
         
            +
              # redis
         
     | 
| 
      
 46 
     | 
    
         
            +
              redis = Redis.new(host: 'redis')
         
     | 
| 
      
 47 
     | 
    
         
            +
             
     | 
| 
      
 48 
     | 
    
         
            +
              # elasic
         
     | 
| 
      
 49 
     | 
    
         
            +
              es = Faraday.new('http://elastic:9200')
         
     | 
| 
      
 50 
     | 
    
         
            +
             
     | 
| 
      
 51 
     | 
    
         
            +
              # default mapping
         
     | 
| 
      
 52 
     | 
    
         
            +
              map = {
         
     | 
| 
      
 53 
     | 
    
         
            +
                entry: 'entry',
         
     | 
| 
      
 54 
     | 
    
         
            +
                case: 'case',
         
     | 
| 
      
 55 
     | 
    
         
            +
                action: 'action',
         
     | 
| 
      
 56 
     | 
    
         
            +
                index: 'index',
         
     | 
| 
      
 57 
     | 
    
         
            +
                log: 'log',
         
     | 
| 
      
 58 
     | 
    
         
            +
                lock: 'lock',
         
     | 
| 
      
 59 
     | 
    
         
            +
                current: 'current',
         
     | 
| 
      
 60 
     | 
    
         
            +
              }.freeze
         
     | 
| 
      
 61 
     | 
    
         
            +
             
     | 
| 
      
 62 
     | 
    
         
            +
              # default config
         
     | 
| 
      
 63 
     | 
    
         
            +
              defaults = {
         
     | 
| 
      
 64 
     | 
    
         
            +
                'tz' => '-04:00'
         
     | 
| 
      
 65 
     | 
    
         
            +
              }
         
     | 
| 
      
 66 
     | 
    
         
            +
             
     | 
| 
      
 67 
     | 
    
         
            +
              # base objects
         
     | 
| 
      
 68 
     | 
    
         
            +
              cache = ICFS::CacheElastic.new(map, es)
         
     | 
| 
      
 69 
     | 
    
         
            +
              store = ICFS::StoreS3.new(s3, 'icfs', 'case/')
         
     | 
| 
      
 70 
     | 
    
         
            +
              users_base = ICFS::UsersS3.new(s3, 'icfs', 'users/')
         
     | 
| 
      
 71 
     | 
    
         
            +
              users = ICFS::UsersRedis.new(redis, users_base, {
         
     | 
| 
      
 72 
     | 
    
         
            +
                  prefix: 'users/',
         
     | 
| 
      
 73 
     | 
    
         
            +
                  expires: 60, # one minute cache for testing
         
     | 
| 
      
 74 
     | 
    
         
            +
                  log: log,
         
     | 
| 
      
 75 
     | 
    
         
            +
                })
         
     | 
| 
      
 76 
     | 
    
         
            +
              config_base = ICFS::ConfigS3.new(defaults, s3, 'icfs', 'config/')
         
     | 
| 
      
 77 
     | 
    
         
            +
              config = ICFS::ConfigRedis.new(redis, config_base, {
         
     | 
| 
      
 78 
     | 
    
         
            +
                  prefix: 'config/',
         
     | 
| 
      
 79 
     | 
    
         
            +
                  expires: 60,  # debug, only cache for one minute
         
     | 
| 
      
 80 
     | 
    
         
            +
                })
         
     | 
| 
      
 81 
     | 
    
         
            +
              api = ICFS::Api.new([], users, cache, store, config)
         
     | 
| 
      
 82 
     | 
    
         
            +
             
     | 
| 
      
 83 
     | 
    
         
            +
              return {
         
     | 
| 
      
 84 
     | 
    
         
            +
                cache: cache,
         
     | 
| 
      
 85 
     | 
    
         
            +
                store: store,
         
     | 
| 
      
 86 
     | 
    
         
            +
                users: users,
         
     | 
| 
      
 87 
     | 
    
         
            +
                config: config,
         
     | 
| 
      
 88 
     | 
    
         
            +
                api: api,
         
     | 
| 
      
 89 
     | 
    
         
            +
                log: log,
         
     | 
| 
      
 90 
     | 
    
         
            +
              }
         
     | 
| 
      
 91 
     | 
    
         
            +
             
     | 
| 
      
 92 
     | 
    
         
            +
            end # def base
         
     | 
    
        data/devel/run/copy-s3.rb
    CHANGED
    
    
    
        data/devel/run/email.rb
    ADDED
    
    | 
         @@ -0,0 +1,36 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            #!/usr/bin/env ruby
         
     | 
| 
      
 2 
     | 
    
         
            +
            #
         
     | 
| 
      
 3 
     | 
    
         
            +
            # Investigative Case File System
         
     | 
| 
      
 4 
     | 
    
         
            +
            #
         
     | 
| 
      
 5 
     | 
    
         
            +
            # Copyright 2019 by Graham A. Field
         
     | 
| 
      
 6 
     | 
    
         
            +
            #
         
     | 
| 
      
 7 
     | 
    
         
            +
            # This program is free software: you can redistribute it and/or modify
         
     | 
| 
      
 8 
     | 
    
         
            +
            # it under the terms of the GNU General Public License version 3.
         
     | 
| 
      
 9 
     | 
    
         
            +
            #
         
     | 
| 
      
 10 
     | 
    
         
            +
            # This program is distributed WITHOUT ANY WARRANTY; without even the
         
     | 
| 
      
 11 
     | 
    
         
            +
            # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
            require_relative 'base'
         
     | 
| 
      
 16 
     | 
    
         
            +
            require_relative '../../lib/icfs/email/from'
         
     | 
| 
      
 17 
     | 
    
         
            +
            require_relative '../../lib/icfs/email/basic'
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
            # api
         
     | 
| 
      
 20 
     | 
    
         
            +
            base = get_base
         
     | 
| 
      
 21 
     | 
    
         
            +
            api = base[:api]
         
     | 
| 
      
 22 
     | 
    
         
            +
            log = base[:log]
         
     | 
| 
      
 23 
     | 
    
         
            +
            log.level = Logger::DEBUG
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
            # load the email map
         
     | 
| 
      
 26 
     | 
    
         
            +
            map_email = JSON.parse(File.read(ARGV[0]))
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
      
 28 
     | 
    
         
            +
            # email gateway
         
     | 
| 
      
 29 
     | 
    
         
            +
            email_basic = ICFS::Email::Basic.new
         
     | 
| 
      
 30 
     | 
    
         
            +
            email_from = ICFS::Email::From.new(map_email)
         
     | 
| 
      
 31 
     | 
    
         
            +
            email = ICFS::Email::Core.new(api, log, [email_from, email_basic])
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
      
 33 
     | 
    
         
            +
            txt = STDIN.read
         
     | 
| 
      
 34 
     | 
    
         
            +
            res = email.receive(txt)
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
            p res
         
     | 
| 
         @@ -0,0 +1,43 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            #!/usr/bin/env ruby
         
     | 
| 
      
 2 
     | 
    
         
            +
            #
         
     | 
| 
      
 3 
     | 
    
         
            +
            # Investigative Case File System
         
     | 
| 
      
 4 
     | 
    
         
            +
            #
         
     | 
| 
      
 5 
     | 
    
         
            +
            # Copyright 2019 by Graham A. Field
         
     | 
| 
      
 6 
     | 
    
         
            +
            #
         
     | 
| 
      
 7 
     | 
    
         
            +
            # This program is free software: you can redistribute it and/or modify
         
     | 
| 
      
 8 
     | 
    
         
            +
            # it under the terms of the GNU General Public License version 3.
         
     | 
| 
      
 9 
     | 
    
         
            +
            #
         
     | 
| 
      
 10 
     | 
    
         
            +
            # This program is distributed WITHOUT ANY WARRANTY; without even the
         
     | 
| 
      
 11 
     | 
    
         
            +
            # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
            # <app> <email_map.json> <config.json>
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
            require_relative 'base'
         
     | 
| 
      
 18 
     | 
    
         
            +
            require_relative '../../lib/icfs/email/from'
         
     | 
| 
      
 19 
     | 
    
         
            +
            require_relative '../../lib/icfs/email/basic'
         
     | 
| 
      
 20 
     | 
    
         
            +
            require_relative '../../lib/icfs/email/imap'
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
            # api
         
     | 
| 
      
 23 
     | 
    
         
            +
            base = get_base
         
     | 
| 
      
 24 
     | 
    
         
            +
            api = base[:api]
         
     | 
| 
      
 25 
     | 
    
         
            +
            log = base[:log]
         
     | 
| 
      
 26 
     | 
    
         
            +
            log.level = Logger::DEBUG
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
      
 28 
     | 
    
         
            +
            # load the email map
         
     | 
| 
      
 29 
     | 
    
         
            +
            map_email = JSON.parse(File.read(ARGV[0]))
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
            # load the IMAP config
         
     | 
| 
      
 32 
     | 
    
         
            +
            cfg_raw = JSON.parse(File.read(ARGV[1]))
         
     | 
| 
      
 33 
     | 
    
         
            +
            cfg = {}
         
     | 
| 
      
 34 
     | 
    
         
            +
            cfg_raw.each{|key, val| cfg[key.to_sym] = val}
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
            # email gateway
         
     | 
| 
      
 37 
     | 
    
         
            +
            email_basic = ICFS::Email::Basic.new
         
     | 
| 
      
 38 
     | 
    
         
            +
            email_from = ICFS::Email::From.new(map_email)
         
     | 
| 
      
 39 
     | 
    
         
            +
            email = ICFS::Email::Core.new(api, log, [email_from, email_basic])
         
     | 
| 
      
 40 
     | 
    
         
            +
            imap = ICFS::Email::Imap.new(email, log, cfg)
         
     | 
| 
      
 41 
     | 
    
         
            +
             
     | 
| 
      
 42 
     | 
    
         
            +
            # and fetch
         
     | 
| 
      
 43 
     | 
    
         
            +
            imap.reconnect
         
     | 
| 
         @@ -0,0 +1,47 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            #!/usr/bin/env ruby
         
     | 
| 
      
 2 
     | 
    
         
            +
            #
         
     | 
| 
      
 3 
     | 
    
         
            +
            # Investigative Case File System
         
     | 
| 
      
 4 
     | 
    
         
            +
            #
         
     | 
| 
      
 5 
     | 
    
         
            +
            # Copyright 2019 by Graham A. Field
         
     | 
| 
      
 6 
     | 
    
         
            +
            #
         
     | 
| 
      
 7 
     | 
    
         
            +
            # This program is free software: you can redistribute it and/or modify
         
     | 
| 
      
 8 
     | 
    
         
            +
            # it under the terms of the GNU General Public License version 3.
         
     | 
| 
      
 9 
     | 
    
         
            +
            #
         
     | 
| 
      
 10 
     | 
    
         
            +
            # This program is distributed WITHOUT ANY WARRANTY; without even the
         
     | 
| 
      
 11 
     | 
    
         
            +
            # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
            # <app> <srv_cert.pem> <srv_key.pem> <ca.pem> < <email.eml>
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
            require_relative 'base'
         
     | 
| 
      
 18 
     | 
    
         
            +
            require_relative '../../lib/icfs/email/smime'
         
     | 
| 
      
 19 
     | 
    
         
            +
            require_relative '../../lib/icfs/email/basic'
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
            # api
         
     | 
| 
      
 22 
     | 
    
         
            +
            base = get_base
         
     | 
| 
      
 23 
     | 
    
         
            +
            api = base[:api]
         
     | 
| 
      
 24 
     | 
    
         
            +
            log = base[:log]
         
     | 
| 
      
 25 
     | 
    
         
            +
            log.level = Logger::DEBUG
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
            # load the email map
         
     | 
| 
      
 28 
     | 
    
         
            +
            cert = ::OpenSSL::X509::Certificate.new(File.read(ARGV[0]))
         
     | 
| 
      
 29 
     | 
    
         
            +
            key = ::OpenSSL::PKey.read(File.read(ARGV[1]))
         
     | 
| 
      
 30 
     | 
    
         
            +
            ca = ::OpenSSL::X509::Store.new
         
     | 
| 
      
 31 
     | 
    
         
            +
            ca.add_file(ARGV[2])
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
      
 33 
     | 
    
         
            +
            map_cn = {
         
     | 
| 
      
 34 
     | 
    
         
            +
              'CN=client 1,OU=Test Client,OU=example,OU=org' => 'user1',
         
     | 
| 
      
 35 
     | 
    
         
            +
              'CN=client 2,OU=Test Client,OU=example,OU=org' => 'user2',
         
     | 
| 
      
 36 
     | 
    
         
            +
              'CN=client 3,OU=Test Client,OU=example,OU=org' => 'user3',
         
     | 
| 
      
 37 
     | 
    
         
            +
            }
         
     | 
| 
      
 38 
     | 
    
         
            +
             
     | 
| 
      
 39 
     | 
    
         
            +
            # email gateway
         
     | 
| 
      
 40 
     | 
    
         
            +
            email_basic = ICFS::Email::Basic.new
         
     | 
| 
      
 41 
     | 
    
         
            +
            email_smime = ICFS::Email::Smime.new(key, cert, ca, map_cn)
         
     | 
| 
      
 42 
     | 
    
         
            +
            email = ICFS::Email::Core.new(api, log, [email_smime, email_basic])
         
     | 
| 
      
 43 
     | 
    
         
            +
             
     | 
| 
      
 44 
     | 
    
         
            +
            txt = STDIN.read
         
     | 
| 
      
 45 
     | 
    
         
            +
            res = email.receive(txt)
         
     | 
| 
      
 46 
     | 
    
         
            +
             
     | 
| 
      
 47 
     | 
    
         
            +
            p res
         
     | 
    
        data/devel/run/init-icfs.rb
    CHANGED
    
    
    
        data/devel/run/webrick.rb
    CHANGED
    
    | 
         @@ -10,68 +10,16 @@ 
     | 
|
| 
       10 
10 
     | 
    
         
             
            # This program is distributed WITHOUT ANY WARRANTY; without even the
         
     | 
| 
       11 
11 
     | 
    
         
             
            # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
         
     | 
| 
       12 
12 
     | 
    
         | 
| 
       13 
     | 
    
         
            -
             
     | 
| 
       14 
     | 
    
         
            -
            require 'aws-sdk-s3'
         
     | 
| 
       15 
     | 
    
         
            -
            require 'redis'
         
     | 
| 
      
 13 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
       16 
14 
     | 
    
         | 
| 
       17 
     | 
    
         
            -
            require_relative ' 
     | 
| 
       18 
     | 
    
         
            -
            require_relative '../../lib/icfs/cache_elastic'
         
     | 
| 
       19 
     | 
    
         
            -
            require_relative '../../lib/icfs/store_s3'
         
     | 
| 
       20 
     | 
    
         
            -
            require_relative '../../lib/icfs/users_s3'
         
     | 
| 
       21 
     | 
    
         
            -
            require_relative '../../lib/icfs/users_redis'
         
     | 
| 
      
 15 
     | 
    
         
            +
            require_relative 'base'
         
     | 
| 
       22 
16 
     | 
    
         
             
            require_relative '../../lib/icfs/web/client'
         
     | 
| 
       23 
     | 
    
         
            -
            require_relative '../../lib/icfs/web/config_s3'
         
     | 
| 
       24 
     | 
    
         
            -
            require_relative '../../lib/icfs/web/config_redis'
         
     | 
| 
       25 
17 
     | 
    
         
             
            require_relative '../../lib/icfs/demo/auth'
         
     | 
| 
       26 
18 
     | 
    
         
             
            require_relative '../../lib/icfs/demo/static'
         
     | 
| 
       27 
19 
     | 
    
         | 
| 
       28 
     | 
    
         
            -
             
     | 
| 
       29 
     | 
    
         
            -
             
     | 
| 
       30 
     | 
    
         
            -
              endpoint: 'http://minio:9000',
         
     | 
| 
       31 
     | 
    
         
            -
              access_key_id: 'minio_key',
         
     | 
| 
       32 
     | 
    
         
            -
              secret_access_key: 'minio_secret',
         
     | 
| 
       33 
     | 
    
         
            -
              force_path_style: true,
         
     | 
| 
       34 
     | 
    
         
            -
              region: 'us-east-1'
         
     | 
| 
       35 
     | 
    
         
            -
            )
         
     | 
| 
      
 20 
     | 
    
         
            +
            base = get_base()
         
     | 
| 
      
 21 
     | 
    
         
            +
            api = base[:api]
         
     | 
| 
       36 
22 
     | 
    
         | 
| 
       37 
     | 
    
         
            -
            # default mapping
         
     | 
| 
       38 
     | 
    
         
            -
            map = {
         
     | 
| 
       39 
     | 
    
         
            -
              entry: 'entry',
         
     | 
| 
       40 
     | 
    
         
            -
              case: 'case',
         
     | 
| 
       41 
     | 
    
         
            -
              action: 'action',
         
     | 
| 
       42 
     | 
    
         
            -
              index: 'index',
         
     | 
| 
       43 
     | 
    
         
            -
              log: 'log',
         
     | 
| 
       44 
     | 
    
         
            -
              lock: 'lock',
         
     | 
| 
       45 
     | 
    
         
            -
              current: 'current',
         
     | 
| 
       46 
     | 
    
         
            -
            }.freeze
         
     | 
| 
       47 
     | 
    
         
            -
             
     | 
| 
       48 
     | 
    
         
            -
            # default config
         
     | 
| 
       49 
     | 
    
         
            -
            defaults = {
         
     | 
| 
       50 
     | 
    
         
            -
              'tz' => '-04:00'
         
     | 
| 
       51 
     | 
    
         
            -
            }
         
     | 
| 
       52 
     | 
    
         
            -
             
     | 
| 
       53 
     | 
    
         
            -
            # the log
         
     | 
| 
       54 
     | 
    
         
            -
            log = Logger.new(STDERR)
         
     | 
| 
       55 
     | 
    
         
            -
            log.level = Logger::INFO
         
     | 
| 
       56 
     | 
    
         
            -
             
     | 
| 
       57 
     | 
    
         
            -
            # base items
         
     | 
| 
       58 
     | 
    
         
            -
            s3 = Aws::S3::Client.new
         
     | 
| 
       59 
     | 
    
         
            -
            redis = Redis.new(host: 'redis')
         
     | 
| 
       60 
     | 
    
         
            -
            es = Faraday.new('http://elastic:9200')
         
     | 
| 
       61 
     | 
    
         
            -
            cache = ICFS::CacheElastic.new(map, es)
         
     | 
| 
       62 
     | 
    
         
            -
            store = ICFS::StoreS3.new(s3, 'icfs'.freeze, 'case/'.freeze)
         
     | 
| 
       63 
     | 
    
         
            -
            users_base = ICFS::UsersS3.new(s3, 'icfs'.freeze, 'users/'.freeze)
         
     | 
| 
       64 
     | 
    
         
            -
            users = ICFS::UsersRedis.new(redis, users_base, {
         
     | 
| 
       65 
     | 
    
         
            -
                prefix: 'users/'.freeze,
         
     | 
| 
       66 
     | 
    
         
            -
                expires: 60, # one minute cache for testing
         
     | 
| 
       67 
     | 
    
         
            -
                log: log,
         
     | 
| 
       68 
     | 
    
         
            -
              })
         
     | 
| 
       69 
     | 
    
         
            -
            api = ICFS::Api.new([], users, cache, store)
         
     | 
| 
       70 
     | 
    
         
            -
            config_base = ICFS::Web::ConfigS3.new(defaults, s3, 'icfs', 'config/')
         
     | 
| 
       71 
     | 
    
         
            -
            config = ICFS::Web::ConfigRedis.new(redis, config_base, {
         
     | 
| 
       72 
     | 
    
         
            -
                prefix: 'config/',
         
     | 
| 
       73 
     | 
    
         
            -
                expires: 60,  # debug, only cache for one minute
         
     | 
| 
       74 
     | 
    
         
            -
              })
         
     | 
| 
       75 
23 
     | 
    
         
             
            web = ICFS::Web::Client.new('/static/icfs.css', '/static/icfs.js')
         
     | 
| 
       76 
24 
     | 
    
         | 
| 
       77 
25 
     | 
    
         
             
            # static files
         
     | 
| 
         @@ -87,7 +35,7 @@ static = { 
     | 
|
| 
       87 
35 
     | 
    
         
             
            }
         
     | 
| 
       88 
36 
     | 
    
         | 
| 
       89 
37 
     | 
    
         
             
            app = Rack::Builder.new do
         
     | 
| 
       90 
     | 
    
         
            -
              use(ICFS::Demo::Auth, api 
     | 
| 
      
 38 
     | 
    
         
            +
              use(ICFS::Demo::Auth, api)
         
     | 
| 
       91 
39 
     | 
    
         
             
              use(ICFS::Demo::Static, static)
         
     | 
| 
       92 
40 
     | 
    
         
             
              run web
         
     | 
| 
       93 
41 
     | 
    
         
             
            end
         
     |