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.
Files changed (42) hide show
  1. checksums.yaml +4 -4
  2. data/bin/icfs_demo_fcgi.rb +2 -0
  3. data/{bin/icfs_demo_ssl_gen.rb → devel/demo/ssl_gen.rb} +25 -13
  4. data/devel/demo/ssl_gen.yml +14 -0
  5. data/devel/icfs-wrk/Dockerfile +1 -1
  6. data/devel/run/base.rb +92 -0
  7. data/devel/run/copy-s3.rb +2 -0
  8. data/devel/run/email.rb +36 -0
  9. data/devel/run/email_imap.rb +43 -0
  10. data/devel/run/email_smime.rb +47 -0
  11. data/devel/run/init-icfs.rb +2 -0
  12. data/devel/run/webrick.rb +5 -57
  13. data/lib/icfs/api.rb +101 -90
  14. data/lib/icfs/cache.rb +2 -0
  15. data/lib/icfs/cache_elastic.rb +127 -125
  16. data/lib/icfs/{web/config.rb → config.rb} +3 -3
  17. data/lib/icfs/{web/config_redis.rb → config_redis.rb} +8 -8
  18. data/lib/icfs/{web/config_s3.rb → config_s3.rb} +8 -8
  19. data/lib/icfs/demo/auth.rb +5 -7
  20. data/lib/icfs/demo/static.rb +2 -0
  21. data/lib/icfs/elastic.rb +10 -8
  22. data/lib/icfs/email/basic.rb +242 -0
  23. data/lib/icfs/email/core.rb +293 -0
  24. data/lib/icfs/email/from.rb +52 -0
  25. data/lib/icfs/email/imap.rb +148 -0
  26. data/lib/icfs/email/smime.rb +139 -0
  27. data/lib/icfs/items.rb +5 -3
  28. data/lib/icfs/store.rb +20 -18
  29. data/lib/icfs/store_fs.rb +7 -5
  30. data/lib/icfs/store_s3.rb +4 -2
  31. data/lib/icfs/users.rb +5 -3
  32. data/lib/icfs/users_fs.rb +8 -6
  33. data/lib/icfs/users_redis.rb +12 -10
  34. data/lib/icfs/users_s3.rb +6 -4
  35. data/lib/icfs/utils/backup.rb +30 -29
  36. data/lib/icfs/utils/check.rb +36 -34
  37. data/lib/icfs/validate.rb +24 -15
  38. data/lib/icfs/web/auth_ssl.rb +7 -9
  39. data/lib/icfs/web/client.rb +671 -679
  40. data/lib/icfs.rb +174 -10
  41. metadata +16 -7
  42. data/devel/devel-webrick.yml +0 -49
data/lib/icfs.rb CHANGED
@@ -9,7 +9,10 @@
9
9
  # This program is distributed WITHOUT ANY WARRANTY; without even the
10
10
  # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11
11
 
12
+ # frozen_string_literal: true
13
+
12
14
  require 'digest/sha2'
15
+ require 'date'
13
16
 
14
17
  require_relative 'icfs/validate'
15
18
 
@@ -18,38 +21,49 @@ require_relative 'icfs/validate'
18
21
  #
19
22
  module ICFS
20
23
 
24
+ # version: major, minor, patch
25
+ Version = [0, 2, 0].freeze
26
+
27
+ # version pre-release
28
+ VersionPre = nil
29
+
30
+ # version string
31
+ VersionString = (
32
+ '%d.%d.%d' % Version +
33
+ (VersionPre ? ('-' + VersionPre) : '')
34
+ ).freeze
21
35
 
22
36
  # no tags
23
- TagNone = '[none]'.freeze
37
+ TagNone = '[none]'
24
38
 
25
39
  # edits an action
26
- TagAction = '[action]'.freeze
40
+ TagAction = '[action]'
27
41
 
28
42
  # edits an index
29
- TagIndex = '[index]'.freeze
43
+ TagIndex = '[index]'
30
44
 
31
45
  # edits the case
32
- TagCase = '[case]'.freeze
46
+ TagCase = '[case]'
33
47
 
34
48
 
35
49
  # permission to read case
36
- PermRead = '[read]'.freeze
50
+ PermRead = '[read]'
37
51
 
38
52
  # permission to write case
39
- PermWrite = '[write]'.freeze
53
+ PermWrite = '[write]'
40
54
 
41
55
  # permission to manage case
42
- PermManage = '[manage]'.freeze
56
+ PermManage = '[manage]'
43
57
 
44
58
  # permission to manage actions
45
- PermAction = '[action]'.freeze
59
+ PermAction = '[action]'
46
60
 
47
61
  # global permission to search
48
- PermSearch = '{[search]}'.freeze
62
+ PermSearch = '{[search]}'
49
63
 
50
64
 
51
65
  # user group
52
- UserCase = '[case]'.freeze
66
+ UserCase = '[case]'
53
67
 
54
68
 
55
69
  ###############################################
@@ -67,6 +81,156 @@ module ICFS
67
81
  end
68
82
 
69
83
 
84
+ ###############################################
85
+ # Pull a time type
86
+ #
87
+ # @api private
88
+ #
89
+ def self._time_type(str)
90
+ case str.downcase
91
+ when 'y', 'yr', 'yrs', 'year', 'years'
92
+ return :year
93
+ when 'm', 'mon', 'mons', 'month', 'months'
94
+ return :month
95
+ when 'w', 'wk', 'wks', 'week', 'weeks'
96
+ return :week
97
+ when 'd', 'day', 'days'
98
+ return :day
99
+ when 'h', 'hr', 'hrs', 'hour', 'hours'
100
+ return :hour
101
+ when 'min', 'mins', 'minute', 'minutes'
102
+ return :minute
103
+ when 's', 'sec', 'secs', 'second', 'seconds'
104
+ return :second
105
+ else
106
+ return nil
107
+ end
108
+ end # self._time_type()
109
+
110
+
111
+ ###############################################
112
+ # Adjust the time
113
+ #
114
+ # @api private
115
+ #
116
+ def self._time_adjust(num, type)
117
+ case type
118
+ when :year
119
+ ary = Time.now.utc.to_a
120
+ dte = Date.new(ary[5], ary[4], ary[3])
121
+ dte = dte << (-12 * num)
122
+ return Time.utc(dte.year, dte.month, dte.day,
123
+ ary[2], ary[1], ary[0]).to_i
124
+ when :month
125
+ ary = Time.now.utc.to_a
126
+ dte = Date.new(ary[5], ary[4], ary[3])
127
+ dte = dte << (-1 * num)
128
+ return Time.utc(dte.year, dte.month, dte.day,
129
+ ary[2], ary[1], ary[0]).to_i
130
+ when :week
131
+ return (Time.now + num * 7*24*60*60).to_i
132
+ when :day
133
+ return (Time.now + num * 24*60*60).to_i
134
+ when :hour
135
+ return (Time.now + num * 60*60).to_i
136
+ when :minute
137
+ return (Time.now + num * 60).to_i
138
+ when :second
139
+ return (Time.now + num).to_i
140
+ else
141
+ return nil
142
+ end
143
+ end
144
+
145
+
146
+ ###############################################
147
+ # A time delta spec
148
+ TimeDelta = /^[[:space:]]*([Nn][Oo][Ww])?[[:space:]]*([+\-])[[:space:]]*(\d+)[[:space:]]*([^[space]]+)[[:space]]*$/.freeze
149
+
150
+
151
+ ###############################################
152
+ # a relative spec
153
+ TimeRel = /^[[:space:]]*([Nn][Ee][Xx][Tt]|[Pp][Rr][Ee][Vv]|[Ll][Aa][Ss][Tt])[[:space:]]+([^[:space:]]+)[[:space:]]*$/.freeze
154
+
155
+
156
+ ###############################################
157
+ # future time spec
158
+ TimeFuture = /^[[:space:]]*[Ii][Nn][[:space:]]+(\d+)[[:space:]]*([^[space]]+)[[:space]]*$/.freeze
159
+
160
+
161
+ ###############################################
162
+ # historic time spec
163
+ TimeHistory = /^[[:space:]]*(\d+)[[:space:]]*([^[:space:]]+)[[:space:]]*[Aa][Gg][Oo][[:space:]]*$/.freeze
164
+
165
+
166
+ ###############################################
167
+ # empty time spec
168
+ TimeEmpty = /^[[:space:]]*([Nn][Oo][Ww])?[[:space:]]*$/.freeze
169
+
170
+
171
+ ###############################################
172
+ # A timezone spec
173
+ TimeZone = /[+\-]\d{2}:\d{2}[[:space:]]*$/.freeze
174
+
175
+
176
+ ###############################################
177
+ # Parse a time string
178
+ #
179
+ # @param str [String] the time string
180
+ # @param cfg [Config] the config
181
+ #
182
+ # Handles:
183
+ # * blank or now
184
+ # * \[now\] +\\- <num> <type>
185
+ # * next\\prev <type>
186
+ # * in <num> <type>
187
+ # * <num> <type> ago
188
+ # * a specifc parseable time
189
+ #
190
+ def self.time_parse(str, cfg)
191
+ return nil if( !str || !str.is_a?(String) )
192
+
193
+ # empty
194
+ if ma = TimeEmpty.match(str)
195
+ return Time.now.to_i
196
+
197
+ # delta
198
+ elsif ma = TimeDelta.match(str)
199
+ num = ma[3].to_i
200
+ num = num * -1 if ma[2] == '-'
201
+ type = ICFS._time_type(ma[4])
202
+ return ICFS._time_adjust(num, type)
203
+
204
+ # relative
205
+ elsif ma = TimeRel.match(str)
206
+ num = (ma[1].downcase == 'next') ? 1 : -1
207
+ type = ICFS._time_type(ma[2])
208
+ return ICFS._time_adjust(num, type)
209
+
210
+ # future
211
+ elsif ma = TimeFuture.match(str)
212
+ num = ma[1].to_i
213
+ type = ICFS._time_type(ma[2])
214
+ return ICFS._time_adjust(num, type)
215
+
216
+ # history
217
+ elsif ma = TimeHistory.match(str)
218
+ p ma
219
+ num = -1 * ma[1].to_i
220
+ type = ICFS._time_type(ma[2])
221
+ return ICFS._time_adjust(num, type)
222
+
223
+ # parse a time spec
224
+ else
225
+ ma = TimeZone.match(str)
226
+ tstr = ma ? str : str + cfg.get('tz')
227
+ return Time.parse(tstr).to_i
228
+
229
+ end
230
+
231
+ rescue ArgumentError
232
+ return nil
233
+ end # def self.time_parse()
70
234
 
71
235
 
72
236
  ##########################################################################
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: icfs
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.3
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Graham A. Field
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-06-11 00:00:00.000000000 Z
11
+ date: 2019-06-29 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: |2-
14
14
 
@@ -25,23 +25,35 @@ extra_rdoc_files: []
25
25
  files:
26
26
  - LICENSE.txt
27
27
  - bin/icfs_demo_fcgi.rb
28
- - bin/icfs_demo_ssl_gen.rb
29
28
  - data/icfs.css
30
29
  - data/icfs.js
31
- - devel/devel-webrick.yml
30
+ - devel/demo/ssl_gen.rb
31
+ - devel/demo/ssl_gen.yml
32
32
  - devel/docker-compose.yml
33
33
  - devel/icfs
34
34
  - devel/icfs-wrk/Dockerfile
35
+ - devel/run/base.rb
35
36
  - devel/run/copy-s3.rb
37
+ - devel/run/email.rb
38
+ - devel/run/email_imap.rb
39
+ - devel/run/email_smime.rb
36
40
  - devel/run/init-icfs.rb
37
41
  - devel/run/webrick.rb
38
42
  - lib/icfs.rb
39
43
  - lib/icfs/api.rb
40
44
  - lib/icfs/cache.rb
41
45
  - lib/icfs/cache_elastic.rb
46
+ - lib/icfs/config.rb
47
+ - lib/icfs/config_redis.rb
48
+ - lib/icfs/config_s3.rb
42
49
  - lib/icfs/demo/auth.rb
43
50
  - lib/icfs/demo/static.rb
44
51
  - lib/icfs/elastic.rb
52
+ - lib/icfs/email/basic.rb
53
+ - lib/icfs/email/core.rb
54
+ - lib/icfs/email/from.rb
55
+ - lib/icfs/email/imap.rb
56
+ - lib/icfs/email/smime.rb
45
57
  - lib/icfs/items.rb
46
58
  - lib/icfs/store.rb
47
59
  - lib/icfs/store_fs.rb
@@ -55,9 +67,6 @@ files:
55
67
  - lib/icfs/validate.rb
56
68
  - lib/icfs/web/auth_ssl.rb
57
69
  - lib/icfs/web/client.rb
58
- - lib/icfs/web/config.rb
59
- - lib/icfs/web/config_redis.rb
60
- - lib/icfs/web/config_s3.rb
61
70
  homepage: https://github.com/g4field/icfs
62
71
  licenses:
63
72
  - GPL-3.0
@@ -1,49 +0,0 @@
1
- #
2
- # Investigative Case File System
3
- #
4
- # Copyright 2019 by Graham A. Field
5
- #
6
- # This program is free software: you can redistribute it and/or modify
7
- # it under the terms of the GNU General Public License version 3.
8
- #
9
- # This program is distributed WITHOUT ANY WARRANTY; without even the
10
- # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11
-
12
- version: '3'
13
-
14
- services:
15
-
16
- # Elasticsearch instance
17
- elastic:
18
- image: docker.elastic.co/elasticsearch/elasticsearch:6.7.2
19
- environment:
20
- discovery-type: single-node
21
- volume:
22
- - elastic:/usr/share/elasticsearch/data
23
- ports:
24
- - "127.0.0.1:9200:9200"
25
-
26
- # Minio S3-compatible object store
27
- minio:
28
- image: minio/minio
29
- environment:
30
- MINIO_ACCESS_KEY: minio_key
31
- MINIO_SECRET_KEY: minio_secret
32
- volume:
33
- - minio:/data
34
- command: ["server", "/data"]
35
-
36
- # Redis cache
37
- redis:
38
- image: redis:alpine
39
-
40
- # the app
41
- app:
42
- image: icfs-wrk
43
- ports:
44
- - "127.0.0.1:80:8080"
45
-
46
-
47
- volumes:
48
- - elastic
49
- - minio