icfs 0.1.3 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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