sugoi-mail 0.0.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 (182) hide show
  1. data/README +35 -0
  2. data/Rakefile +10 -0
  3. data/app/apis/mailservice_api.rb +178 -0
  4. data/app/controllers/.sugoi_admin_controller.rb.swp +0 -0
  5. data/app/controllers/account_controller.rb +39 -0
  6. data/app/controllers/address_controller.rb +49 -0
  7. data/app/controllers/application.rb +4 -0
  8. data/app/controllers/commandline_controller.rb +15 -0
  9. data/app/controllers/domain_controller.rb +37 -0
  10. data/app/controllers/mailinglist_controller.rb +51 -0
  11. data/app/controllers/mailservice_controller.rb +497 -0
  12. data/app/controllers/sugoi_admin_controller.rb +93 -0
  13. data/app/helpers/account_helper.rb +2 -0
  14. data/app/helpers/address_helper.rb +2 -0
  15. data/app/helpers/application_helper.rb +3 -0
  16. data/app/helpers/domain_helper.rb +2 -0
  17. data/app/helpers/mailservice_helper.rb +2 -0
  18. data/app/helpers/sugoi_admin_helper.rb +2 -0
  19. data/app/models/address.rb +110 -0
  20. data/app/models/admin_message.rb +45 -0
  21. data/app/models/confirmationcode.rb +59 -0
  22. data/app/models/domain.rb +76 -0
  23. data/app/models/mailinglist.rb +336 -0
  24. data/app/models/mailinglist_class.rb +39 -0
  25. data/app/models/message.rb +293 -0
  26. data/app/models/proxy_link.rb +25 -0
  27. data/app/models/user.rb +150 -0
  28. data/app/views/account/login.rhtml +22 -0
  29. data/app/views/account/logout.rhtml +10 -0
  30. data/app/views/account/signup.rhtml +17 -0
  31. data/app/views/account/welcome.rhtml +13 -0
  32. data/app/views/address/_form.rhtml +7 -0
  33. data/app/views/address/edit.rhtml +10 -0
  34. data/app/views/address/list.rhtml +27 -0
  35. data/app/views/address/new.rhtml +8 -0
  36. data/app/views/address/show.rhtml +8 -0
  37. data/app/views/domain/login.rhtml +22 -0
  38. data/app/views/domain/logout.rhtml +10 -0
  39. data/app/views/domain/signup.rhtml +17 -0
  40. data/app/views/domain/welcome.rhtml +13 -0
  41. data/app/views/layouts/address.rhtml +13 -0
  42. data/app/views/layouts/scaffold.rhtml +13 -0
  43. data/app/views/mailinglist/_form.rhtml +28 -0
  44. data/app/views/mailinglist/edit.rhtml +10 -0
  45. data/app/views/mailinglist/list.rhtml +27 -0
  46. data/app/views/mailinglist/new.rhtml +8 -0
  47. data/app/views/mailinglist/show.rhtml +16 -0
  48. data/app/views/sugoi_admin/create_domain.rhtml +1 -0
  49. data/app/views/sugoi_admin/list_addresses.rhtml +1 -0
  50. data/app/views/sugoi_admin/list_domains.rhtml +2 -0
  51. data/app/views/sugoi_admin/list_mailinglists.rhtml +1 -0
  52. data/bin/mailc +32 -0
  53. data/bin/maild +133 -0
  54. data/bin/sugoi-admin +21 -0
  55. data/bin/sugoi-mail +20 -0
  56. data/config/boot.rb +44 -0
  57. data/config/environment.rb +54 -0
  58. data/config/environments/bench.rb +21 -0
  59. data/config/environments/coverage.rb +21 -0
  60. data/config/environments/development.rb +21 -0
  61. data/config/environments/production.rb +18 -0
  62. data/config/environments/test.rb +19 -0
  63. data/config/lighttpd.conf +46 -0
  64. data/config/routes.rb +29 -0
  65. data/db/migrate/001_mailproxy.rb +7 -0
  66. data/db/migrate/002_create_users.rb +13 -0
  67. data/db/migrate/003_create_mailinglists.rb +13 -0
  68. data/db/migrate/004_create_addresses.rb +12 -0
  69. data/db/migrate/005_create_addresses_mailinglists.rb +13 -0
  70. data/db/migrate/006_alter_mailinglists.rb +9 -0
  71. data/db/migrate/007_create_messages.rb +25 -0
  72. data/db/migrate/008_add_mailinglistid_to_users.rb +14 -0
  73. data/db/migrate/009_add_domainadmin_to_users.rb +9 -0
  74. data/db/migrate/010_add_domain_to_users.rb +16 -0
  75. data/db/migrate/011_add_active_to_addresses.rb +14 -0
  76. data/db/migrate/012_create_confirmationcodes.rb +14 -0
  77. data/db/migrate/013_add_description_to_mailinglists.rb +9 -0
  78. data/db/migrate/014_create_admin_messages.rb +69 -0
  79. data/db/migrate/015_add_messages_to_mailinglists.rb +26 -0
  80. data/db/migrate/016_add_mailinglist_admin_to_users.rb +9 -0
  81. data/db/migrate/017_add_mailinglist_types.rb +94 -0
  82. data/db/migrate/018_add_bounciness_to_addresses.rb +20 -0
  83. data/db/migrate/019_add_archived_to_mailinglist_classes.rb +25 -0
  84. data/db/migrate/020_add_envelope_data_to_messages.rb +11 -0
  85. data/db/migrate/021_add_addresses_users.rb +14 -0
  86. data/db/migrate/022_add_virtual_to_users.rb +14 -0
  87. data/db/migrate/023_drop_openposting_from_mailinglists.rb +9 -0
  88. data/db/migrate/024_add_proxy_links.rb +21 -0
  89. data/db/migrate/025_add_proxify_to_mailinglist_classes.rb +25 -0
  90. data/db/schema.mysql.sql +104 -0
  91. data/db/schema.postgresql.sql +104 -0
  92. data/db/schema.rb +85 -0
  93. data/db/schema.sqlite.sql +104 -0
  94. data/db/schema.sqlserver.sql +113 -0
  95. data/db/schema_version +1 -0
  96. data/doc/README_FOR_APP +179 -0
  97. data/doc/mailinglist_classes description.txt +28 -0
  98. data/installer/rails_installer_defaults.yml +5 -0
  99. data/lib/daemonize.rb +56 -0
  100. data/lib/domain_system.rb +87 -0
  101. data/lib/gurgitate-rules.rb +69 -0
  102. data/lib/limitedfork.rb +66 -0
  103. data/lib/login_system.rb +87 -0
  104. data/public/.htaccess +40 -0
  105. data/public/404.html +8 -0
  106. data/public/500.html +8 -0
  107. data/public/dispatch.cgi +10 -0
  108. data/public/dispatch.fcgi +24 -0
  109. data/public/dispatch.rb +10 -0
  110. data/public/favicon.ico +0 -0
  111. data/public/images/rails.png +0 -0
  112. data/public/javascripts/application.js +2 -0
  113. data/public/javascripts/controls.js +815 -0
  114. data/public/javascripts/dragdrop.js +913 -0
  115. data/public/javascripts/effects.js +958 -0
  116. data/public/javascripts/prototype.js +2006 -0
  117. data/public/robots.txt +1 -0
  118. data/public/stylesheets/scaffold.css +74 -0
  119. data/public/stylesheets/trestle.css +74 -0
  120. data/script/about +3 -0
  121. data/script/breakpointer +3 -0
  122. data/script/console +3 -0
  123. data/script/destroy +3 -0
  124. data/script/fakedeliver +19 -0
  125. data/script/generate +3 -0
  126. data/script/performance/benchmarker +3 -0
  127. data/script/performance/profiler +3 -0
  128. data/script/plugin +3 -0
  129. data/script/process/reaper +3 -0
  130. data/script/process/spawner +3 -0
  131. data/script/runner +3 -0
  132. data/script/server +3 -0
  133. data/sugoi-mail.gemspec +36 -0
  134. data/test/fixtures/addresses.yml +70 -0
  135. data/test/fixtures/addresses_mailinglists.yml +20 -0
  136. data/test/fixtures/admin_messages.yml +65 -0
  137. data/test/fixtures/confirmationcodes.yml +13 -0
  138. data/test/fixtures/domains.yml +9 -0
  139. data/test/fixtures/mailinglist_classes.yml +45 -0
  140. data/test/fixtures/mailinglists.yml +80 -0
  141. data/test/fixtures/messages.yml +154 -0
  142. data/test/fixtures/proxy_links.yml +5 -0
  143. data/test/fixtures/users.yml +50 -0
  144. data/test/functional/domain_controller_test.rb +74 -0
  145. data/test/functional/mailservice_controller_test.rb +546 -0
  146. data/test/integration/test_soap.rb +413 -0
  147. data/test/integration/test_xmlrpc.rb +198 -0
  148. data/test/mocks/test/net-smtp-stub.rb +24 -0
  149. data/test/test_helper.rb +28 -0
  150. data/test/unit/address_test.rb +44 -0
  151. data/test/unit/admin_message_test.rb +41 -0
  152. data/test/unit/confirmationcode_test.rb +64 -0
  153. data/test/unit/domain_test.rb +128 -0
  154. data/test/unit/mailinglist_class_test.rb +82 -0
  155. data/test/unit/mailinglist_test.rb +145 -0
  156. data/test/unit/message_test.rb +151 -0
  157. data/test/unit/user_test.rb +126 -0
  158. data/test/units.rb +4 -0
  159. data/vendor/plugins/active_command/init.rb +1 -0
  160. data/vendor/plugins/active_command/lib/active_command/request.rb +137 -0
  161. data/vendor/plugins/active_command/lib/active_command/response.rb +132 -0
  162. data/vendor/plugins/active_command/lib/active_command.rb +2 -0
  163. data/vendor/plugins/ar_fixtures/CHANGELOG +10 -0
  164. data/vendor/plugins/ar_fixtures/MIT-LICENSE +20 -0
  165. data/vendor/plugins/ar_fixtures/README +19 -0
  166. data/vendor/plugins/ar_fixtures/Rakefile +54 -0
  167. data/vendor/plugins/ar_fixtures/about.yml +7 -0
  168. data/vendor/plugins/ar_fixtures/init.rb +1 -0
  169. data/vendor/plugins/ar_fixtures/lib/ar_fixtures.rb +102 -0
  170. data/vendor/plugins/ar_fixtures/tasks/ar_fixtures.rake +39 -0
  171. data/vendor/plugins/ar_fixtures/test/ar_fixtures_test.rb +53 -0
  172. data/vendor/plugins/ar_fixtures/test/database.yml +18 -0
  173. data/vendor/plugins/ar_fixtures/test/fixtures/beer.rb +5 -0
  174. data/vendor/plugins/ar_fixtures/test/fixtures/beers.yml +9 -0
  175. data/vendor/plugins/ar_fixtures/test/fixtures/beers_drunkards.yml +8 -0
  176. data/vendor/plugins/ar_fixtures/test/fixtures/drunkard.rb +6 -0
  177. data/vendor/plugins/ar_fixtures/test/fixtures/drunkards.yml +8 -0
  178. data/vendor/plugins/ar_fixtures/test/fixtures/glass.rb +2 -0
  179. data/vendor/plugins/ar_fixtures/test/fixtures/glasses.yml +9 -0
  180. data/vendor/plugins/ar_fixtures/test/schema.rb +21 -0
  181. data/vendor/plugins/ar_fixtures/test/test_helper.rb +37 -0
  182. metadata +320 -0
@@ -0,0 +1,104 @@
1
+ -- This file is autogenerated by the Rail schema generator, using
2
+ -- the schema defined in db/migration/*.rb
3
+ --
4
+ -- Do not edit this file. Instead, add a new migration using
5
+ -- ./script/generate migration <name>, and then run
6
+ -- ./script/generate schema
7
+
8
+ -- tables
9
+
10
+ CREATE TABLE addresses (
11
+ "id" serial primary key,
12
+ "address" text,
13
+ "active" boolean DEFAULT 't',
14
+ "delivery_attempts" integer DEFAULT 0,
15
+ "bounces" integer DEFAULT 0
16
+ );
17
+
18
+ CREATE TABLE addresses_mailinglists (
19
+ "address_id" integer,
20
+ "mailinglist_id" integer
21
+ );
22
+
23
+ CREATE TABLE admin_messages (
24
+ "id" serial primary key,
25
+ "message" text NOT NULL
26
+ );
27
+
28
+ CREATE TABLE confirmationcodes (
29
+ "id" serial primary key,
30
+ "mailinglist_id" integer,
31
+ "address_id" integer,
32
+ "code" text NOT NULL,
33
+ "confirmed" boolean DEFAULT 'f'
34
+ );
35
+
36
+ CREATE TABLE domains (
37
+ "id" serial primary key,
38
+ "name" character varying(255) NOT NULL,
39
+ "password" text NOT NULL
40
+ );
41
+
42
+ CREATE TABLE mailinglist_classes (
43
+ "id" serial primary key,
44
+ "name" text NOT NULL,
45
+ "description" text,
46
+ "public" boolean DEFAULT 'f' NOT NULL,
47
+ "closed" boolean DEFAULT 'f' NOT NULL,
48
+ "moderated" boolean DEFAULT 'f' NOT NULL,
49
+ "confirmation" boolean DEFAULT 't' NOT NULL,
50
+ "joinable" boolean DEFAULT 't' NOT NULL,
51
+ "archived" boolean DEFAULT 'f',
52
+ "proxify" boolean DEFAULT 'f'
53
+ );
54
+
55
+ CREATE TABLE mailinglists (
56
+ "id" serial primary key,
57
+ "user_id" integer,
58
+ "name" text NOT NULL,
59
+ "description" text,
60
+ "welcome_admin_message_id" integer DEFAULT 1,
61
+ "confirmed_admin_message_id" integer DEFAULT 2,
62
+ "sayonara_admin_message_id" integer DEFAULT 3,
63
+ "mailinglist_class_id" integer
64
+ );
65
+
66
+ CREATE TABLE messages (
67
+ "id" serial primary key,
68
+ "mailinglist_id" integer,
69
+ "address_id" integer,
70
+ "parent_id" integer,
71
+ "subject" character varying(255),
72
+ "messageid" character varying(255),
73
+ "timestamp" timestamp,
74
+ "headers" text,
75
+ "body" text,
76
+ "envelope_from" text,
77
+ "envelope_to" text
78
+ );
79
+
80
+ CREATE TABLE proxy_links (
81
+ "id" serial primary key,
82
+ "mailinglist_id" integer NOT NULL,
83
+ "address_id" integer NOT NULL
84
+ );
85
+
86
+ CREATE TABLE users (
87
+ "id" serial primary key,
88
+ "login" text NOT NULL,
89
+ "password" text NOT NULL,
90
+ "mailinglist_id" integer,
91
+ "domainadmin" boolean DEFAULT 'f',
92
+ "domain_id" integer,
93
+ "mailinglistadmin" boolean DEFAULT 'f',
94
+ "virtual" boolean DEFAULT 'f'
95
+ );
96
+
97
+
98
+ -- schema version meta-info
99
+
100
+ CREATE TABLE schema_info (
101
+ "version" integer
102
+ );
103
+
104
+ insert into schema_info (version) values (25);
data/db/schema.rb ADDED
@@ -0,0 +1,85 @@
1
+ # This file is autogenerated. Instead of editing this file, please use the
2
+ # migrations feature of ActiveRecord to incrementally modify your database, and
3
+ # then regenerate this schema definition.
4
+
5
+ ActiveRecord::Schema.define(:version => 25) do
6
+
7
+ create_table "addresses", :force => true do |t|
8
+ t.column "address", :text
9
+ t.column "active", :boolean, :default => true
10
+ t.column "delivery_attempts", :integer, :default => 0
11
+ t.column "bounces", :integer, :default => 0
12
+ end
13
+
14
+ create_table "addresses_mailinglists", :id => false, :force => true do |t|
15
+ t.column "address_id", :integer
16
+ t.column "mailinglist_id", :integer
17
+ end
18
+
19
+ create_table "admin_messages", :force => true do |t|
20
+ t.column "message", :text, :null => false
21
+ end
22
+
23
+ create_table "confirmationcodes", :force => true do |t|
24
+ t.column "mailinglist_id", :integer
25
+ t.column "address_id", :integer
26
+ t.column "code", :text, :null => false
27
+ t.column "confirmed", :boolean, :default => false
28
+ end
29
+
30
+ create_table "domains", :force => true do |t|
31
+ t.column "name", :string, :null => false
32
+ t.column "password", :text, :null => false
33
+ end
34
+
35
+ create_table "mailinglist_classes", :force => true do |t|
36
+ t.column "name", :text, :null => false
37
+ t.column "description", :text
38
+ t.column "public", :boolean, :default => false, :null => false
39
+ t.column "closed", :boolean, :default => false, :null => false
40
+ t.column "moderated", :boolean, :default => false, :null => false
41
+ t.column "confirmation", :boolean, :default => true, :null => false
42
+ t.column "joinable", :boolean, :default => true, :null => false
43
+ t.column "archived", :boolean, :default => false, :null => false
44
+ t.column "proxify", :boolean, :default => false
45
+ end
46
+
47
+ create_table "mailinglists", :force => true do |t|
48
+ t.column "user_id", :integer
49
+ t.column "name", :text, :null => false
50
+ t.column "description", :text
51
+ t.column "welcome_admin_message_id", :integer, :default => 1
52
+ t.column "confirmed_admin_message_id", :integer, :default => 2
53
+ t.column "sayonara_admin_message_id", :integer, :default => 3
54
+ t.column "mailinglist_class_id", :integer
55
+ end
56
+
57
+ create_table "messages", :force => true do |t|
58
+ t.column "mailinglist_id", :integer
59
+ t.column "address_id", :integer
60
+ t.column "parent_id", :integer
61
+ t.column "subject", :string
62
+ t.column "messageid", :string
63
+ t.column "timestamp", :datetime
64
+ t.column "headers", :text
65
+ t.column "body", :text
66
+ t.column "envelope_from", :text
67
+ t.column "envelope_to", :text
68
+ end
69
+
70
+ create_table "proxy_links", :force => true do |t|
71
+ t.column "mailinglist_id", :integer, :null => false
72
+ t.column "address_id", :integer, :null => false
73
+ end
74
+
75
+ create_table "users", :force => true do |t|
76
+ t.column "login", :text, :null => false
77
+ t.column "password", :text, :null => false
78
+ t.column "mailinglist_id", :integer
79
+ t.column "domainadmin", :boolean, :default => false
80
+ t.column "domain_id", :integer
81
+ t.column "mailinglistadmin", :boolean, :default => false
82
+ t.column "virtual", :boolean, :default => false
83
+ end
84
+
85
+ end
@@ -0,0 +1,104 @@
1
+ -- This file is autogenerated by the Rail schema generator, using
2
+ -- the schema defined in db/migration/*.rb
3
+ --
4
+ -- Do not edit this file. Instead, add a new migration using
5
+ -- ./script/generate migration <name>, and then run
6
+ -- ./script/generate schema
7
+
8
+ -- tables
9
+
10
+ CREATE TABLE addresses (
11
+ "id" INTEGER PRIMARY KEY NOT NULL,
12
+ "address" text,
13
+ "active" boolean DEFAULT 't',
14
+ "delivery_attempts" integer DEFAULT 0,
15
+ "bounces" integer DEFAULT 0
16
+ );
17
+
18
+ CREATE TABLE addresses_mailinglists (
19
+ "address_id" integer,
20
+ "mailinglist_id" integer
21
+ );
22
+
23
+ CREATE TABLE admin_messages (
24
+ "id" INTEGER PRIMARY KEY NOT NULL,
25
+ "message" text NOT NULL
26
+ );
27
+
28
+ CREATE TABLE confirmationcodes (
29
+ "id" INTEGER PRIMARY KEY NOT NULL,
30
+ "mailinglist_id" integer,
31
+ "address_id" integer,
32
+ "code" text NOT NULL,
33
+ "confirmed" boolean DEFAULT 'f'
34
+ );
35
+
36
+ CREATE TABLE domains (
37
+ "id" INTEGER PRIMARY KEY NOT NULL,
38
+ "name" varchar(255) NOT NULL,
39
+ "password" text NOT NULL
40
+ );
41
+
42
+ CREATE TABLE mailinglist_classes (
43
+ "id" INTEGER PRIMARY KEY NOT NULL,
44
+ "name" text NOT NULL,
45
+ "description" text,
46
+ "public" boolean DEFAULT 'f' NOT NULL,
47
+ "closed" boolean DEFAULT 'f' NOT NULL,
48
+ "moderated" boolean DEFAULT 'f' NOT NULL,
49
+ "confirmation" boolean DEFAULT 't' NOT NULL,
50
+ "joinable" boolean DEFAULT 't' NOT NULL,
51
+ "archived" boolean DEFAULT 'f',
52
+ "proxify" boolean DEFAULT 'f'
53
+ );
54
+
55
+ CREATE TABLE mailinglists (
56
+ "id" INTEGER PRIMARY KEY NOT NULL,
57
+ "user_id" integer,
58
+ "name" text NOT NULL,
59
+ "description" text,
60
+ "welcome_admin_message_id" integer DEFAULT 1,
61
+ "confirmed_admin_message_id" integer DEFAULT 2,
62
+ "sayonara_admin_message_id" integer DEFAULT 3,
63
+ "mailinglist_class_id" integer
64
+ );
65
+
66
+ CREATE TABLE messages (
67
+ "id" INTEGER PRIMARY KEY NOT NULL,
68
+ "mailinglist_id" integer,
69
+ "address_id" integer,
70
+ "parent_id" integer,
71
+ "subject" varchar(255),
72
+ "messageid" varchar(255),
73
+ "timestamp" datetime,
74
+ "headers" text,
75
+ "body" text,
76
+ "envelope_from" text,
77
+ "envelope_to" text
78
+ );
79
+
80
+ CREATE TABLE proxy_links (
81
+ "id" INTEGER PRIMARY KEY NOT NULL,
82
+ "mailinglist_id" integer NOT NULL,
83
+ "address_id" integer NOT NULL
84
+ );
85
+
86
+ CREATE TABLE users (
87
+ "id" INTEGER PRIMARY KEY NOT NULL,
88
+ "login" text NOT NULL,
89
+ "password" text NOT NULL,
90
+ "mailinglist_id" integer,
91
+ "domainadmin" boolean DEFAULT 'f',
92
+ "domain_id" integer,
93
+ "mailinglistadmin" boolean DEFAULT 'f',
94
+ "virtual" boolean DEFAULT 'f'
95
+ );
96
+
97
+
98
+ -- schema version meta-info
99
+
100
+ CREATE TABLE schema_info (
101
+ "version" integer
102
+ );
103
+
104
+ insert into schema_info (version) values (25);
@@ -0,0 +1,113 @@
1
+ -- This file is autogenerated by the Rail schema generator, using
2
+ -- the schema defined in db/migration/*.rb
3
+ --
4
+ -- Do not edit this file. Instead, add a new migration using
5
+ -- ./script/generate migration <name>, and then run
6
+ -- ./script/generate schema
7
+
8
+ -- tables
9
+
10
+ CREATE TABLE addresses (
11
+ [id] int NOT NULL IDENTITY(1,
12
+ 1) PRIMARY KEY,
13
+ [address] text,
14
+ [active] bit DEFAULT 1,
15
+ [delivery_attempts] int DEFAULT 0,
16
+ [bounces] int DEFAULT 0
17
+ );
18
+
19
+ CREATE TABLE addresses_mailinglists (
20
+ [address_id] int,
21
+ [mailinglist_id] int
22
+ );
23
+
24
+ CREATE TABLE admin_messages (
25
+ [id] int NOT NULL IDENTITY(1,
26
+ 1) PRIMARY KEY,
27
+ [message] text NOT NULL
28
+ );
29
+
30
+ CREATE TABLE confirmationcodes (
31
+ [id] int NOT NULL IDENTITY(1,
32
+ 1) PRIMARY KEY,
33
+ [mailinglist_id] int,
34
+ [address_id] int,
35
+ [code] text NOT NULL,
36
+ [confirmed] bit DEFAULT 0
37
+ );
38
+
39
+ CREATE TABLE domains (
40
+ [id] int NOT NULL IDENTITY(1,
41
+ 1) PRIMARY KEY,
42
+ [name] varchar(255) NOT NULL,
43
+ [password] text NOT NULL
44
+ );
45
+
46
+ CREATE TABLE mailinglist_classes (
47
+ [id] int NOT NULL IDENTITY(1,
48
+ 1) PRIMARY KEY,
49
+ [name] text NOT NULL,
50
+ [description] text,
51
+ [public] bit DEFAULT 0 NOT NULL,
52
+ [closed] bit DEFAULT 0 NOT NULL,
53
+ [moderated] bit DEFAULT 0 NOT NULL,
54
+ [confirmation] bit DEFAULT 1 NOT NULL,
55
+ [joinable] bit DEFAULT 1 NOT NULL,
56
+ [archived] bit DEFAULT 0,
57
+ [proxify] bit DEFAULT 0
58
+ );
59
+
60
+ CREATE TABLE mailinglists (
61
+ [id] int NOT NULL IDENTITY(1,
62
+ 1) PRIMARY KEY,
63
+ [user_id] int,
64
+ [name] text NOT NULL,
65
+ [description] text,
66
+ [welcome_admin_message_id] int DEFAULT 1,
67
+ [confirmed_admin_message_id] int DEFAULT 2,
68
+ [sayonara_admin_message_id] int DEFAULT 3,
69
+ [mailinglist_class_id] int
70
+ );
71
+
72
+ CREATE TABLE messages (
73
+ [id] int NOT NULL IDENTITY(1,
74
+ 1) PRIMARY KEY,
75
+ [mailinglist_id] int,
76
+ [address_id] int,
77
+ [parent_id] int,
78
+ [subject] varchar(255),
79
+ [messageid] varchar(255),
80
+ [timestamp] datetime,
81
+ [headers] text,
82
+ [body] text,
83
+ [envelope_from] text,
84
+ [envelope_to] text
85
+ );
86
+
87
+ CREATE TABLE proxy_links (
88
+ [id] int NOT NULL IDENTITY(1,
89
+ 1) PRIMARY KEY,
90
+ [mailinglist_id] int NOT NULL,
91
+ [address_id] int NOT NULL
92
+ );
93
+
94
+ CREATE TABLE users (
95
+ [id] int NOT NULL IDENTITY(1,
96
+ 1) PRIMARY KEY,
97
+ [login] text NOT NULL,
98
+ [password] text NOT NULL,
99
+ [mailinglist_id] int,
100
+ [domainadmin] bit DEFAULT 0,
101
+ [domain_id] int,
102
+ [mailinglistadmin] bit DEFAULT 0,
103
+ [virtual] bit DEFAULT 0
104
+ );
105
+
106
+
107
+ -- schema version meta-info
108
+
109
+ CREATE TABLE schema_info (
110
+ [version] int
111
+ );
112
+
113
+ insert into schema_info (version) values (25);
data/db/schema_version ADDED
@@ -0,0 +1 @@
1
+ 25
@@ -0,0 +1,179 @@
1
+ = Welcome to Sugoi-Mail: an introduction to mailing lists and the mail proxy
2
+
3
+ Sugoi-Mail is a new kind of mailing list manager, which combines a
4
+ whole class of different email distribution schemes into one
5
+ common thing.
6
+
7
+ = Mailing Lists
8
+
9
+ == First things first: what's a mailing list?
10
+
11
+ A mailing list is, at its most basic, a single email address that
12
+ redirects email sent to it to multiple email addresses.
13
+
14
+ Exactly how it does this can happen in a number of different ways.
15
+ There are different kinds of behaviours regarding whether it
16
+ accepts mail for delivery or not. Have a look at the
17
+ MailinglistClass class for some examples of different kinds of
18
+ behaviour.
19
+
20
+ == A couple of basic mailing list types
21
+
22
+ Let's have a look at a couple of basic kinds of mailing lists, to
23
+ illustrate.
24
+
25
+ _List type name_:: Description
26
+ Distribution list:: A personal list of addresses that one
27
+ person can send mail to.
28
+ Discussion list:: A collection of addresses where people on the
29
+ list can send email to the list address and
30
+ it's broadcast to all of them.
31
+
32
+ Those are both almost the same thing, where the only difference is
33
+ in who's allowed to send email to the list. Expressed as
34
+ MailinglistClass classes, a distribution list looks like this:
35
+
36
+ MailinglistClass.new do |distrib|
37
+ # Identification details
38
+ distrib.name = "Distribution List"
39
+ distrib.description = 'Personal distribution list'
40
+
41
+ # Mailing details
42
+ distrib.public = false
43
+ distrib.closed = true
44
+ distrib.moderated = false
45
+ distrib.archived = false
46
+
47
+ # Modification details
48
+ distrib.joinable = false
49
+ distrib.confirmation = false
50
+ end
51
+
52
+ This is a private, closed, unmoderated, non-joinable,
53
+ non-confirmation mailing list.
54
+
55
+ The key detail is "closed" here--in a closed mailing list, only
56
+ the owner is permitted to send mail to it.
57
+
58
+ Let's compare that to a discussion list, whose class may be
59
+ defined as follows:
60
+
61
+ MailinglistClass.new do |discussion|
62
+ distrib.name = "Discussion List"
63
+ distrib.description = "An unmoderated discussion list"
64
+
65
+ distrib.public = false
66
+ distrib.closed = false
67
+ distrib.moderated = false
68
+ distrib.archive = true
69
+
70
+ distrib.joinable = true
71
+ distrib.confirmation = true
72
+ end
73
+
74
+ The difference in delivery details is that where a distribution
75
+ list is closed, a discussion list is _open_--anyone on the mailing
76
+ list can send email to the mailing list's email address and it
77
+ will be delivered to everyone.
78
+
79
+ The other difference is in modification details--where a
80
+ distribution list can only be modified by the owner, the
81
+ discussion list is _joinable_. This means that people can send
82
+ email to the mailing list's "request" address asking the system to
83
+ automatically subscribe them to the mailing list.
84
+
85
+ Also, the "confirmation" parameter is set to true to prevent
86
+ abuse. When a subscription request is received, an email message
87
+ is sent to the address the subscription request was made for with
88
+ a confirmation code in it, asking the person at that email address
89
+ to verify that it's a genuine email address and that a request
90
+ really was made.
91
+
92
+ You may know of services with names like "pobox.com", which allow
93
+ you to keep a single email address which forwards your email to
94
+ whatever email address your ISP's given you this week. Anyone
95
+ who's had their ISP be bought out from underneath them and then
96
+ had their email address change from myname@smallisp.boulder.co.us to
97
+ myname27@hugeisp.com will understand how this could be handy.
98
+
99
+ == More interesting mailing list classes 1: Mail Proxy
100
+
101
+ Okay, suppose that you want to set up a service like this up? How
102
+ would you do the email forwarding? It's a kind of mailing list,
103
+ of course!
104
+
105
+ MailinglistClass.new do |forward|
106
+ forward.name = 'LTMA'
107
+ forward.description = 'Lifetime Mail Address'
108
+
109
+ forward.public = true
110
+ forward.closed = false
111
+ forward.moderated = false
112
+ forward.archive = false
113
+
114
+ forward.joinable = false
115
+ forward.confirmation = true
116
+ end
117
+
118
+ Indeed, it was for this very reason that Sugoi-Mail originally had
119
+ a User class in the first place, so be sure to check that out.
120
+ You'll notice that every User has a Mailinglist which has the same
121
+ name as the User--that's their forwarding address.
122
+
123
+ == More interesting mailing list classes 2: Web Bulletin Board
124
+
125
+ You see that +archive+ parameter in all those mailing list class
126
+ declarations? Those say whether the the mail system should save
127
+ messages that are sent to the mailing list or not. In the case of
128
+ a forwarding address, it doesn't make very much sense to archive
129
+ all messages coming through (although one could very easily set up
130
+ a webmail system simply by not letting users add any email
131
+ addresses to their mailing list--see the User section below--and
132
+ letting them access their email messages via the web).
133
+
134
+ If you have a mailing list with no subscribers, that people are
135
+ allowed to send messages to via some sort of a web interface--what
136
+ you have is a web bulletin board!
137
+
138
+ And if you add email subscribers to the bulletin board, you also
139
+ gain the ability for people to participate via email. I, for one
140
+ don't much like posting messages to the Internet via web forms (I
141
+ even update my blog offline), so the ability to participate by
142
+ email would be a nice feature. By the same token, others find
143
+ that email is a big pain to configure and get working correctly,
144
+ so they prefer to participate in online communities through a web
145
+ interface. Well, with Sugoi-Mail, you can have both at the same
146
+ time! (On my TODO list, in the distant future, is an NNTP
147
+ interface, to support people who prefer USENET clients.)
148
+
149
+ = Users
150
+
151
+ Now that we have the introduction to mailing lists out of the way,
152
+ I should talk about users. Users are the reason that this entire
153
+ project was started in the first place--I wanted to make some sort
154
+ of a replacement for pobox.com that didn't depend on a really busy
155
+ sysadmin.
156
+
157
+ This meant letting users be able to manage their own email
158
+ aliases, and if possible, their own mailing lists. Quite a lot of
159
+ the code you'll find in this project grew directly out of
160
+ real-world requirements. (Any limitations in the existing system
161
+ are most likely a direct result of the feature being outside the
162
+ scope of the problems I was trying to solve. If I overlooked
163
+ something, please contact me!)
164
+
165
+ So Users are pretty central to the whole Sugoi-Mail system--they
166
+ caused it to happen. Make sure you have a look at the
167
+ documentation for the User class, otherwise you might be confused
168
+ by the next bit.
169
+
170
+ == Proxy address
171
+
172
+ Every User has a proxy address, which is actually the name of
173
+ their Mailinglist. (A user could potentially change their
174
+ Sugoi-Mail email address without changing their userid.) If you
175
+ look at the code for User, you'll notice that the user's address
176
+ comes straight from the User's Mailinglist, and is completely
177
+ separate from his login credentials. Likewise, when you add
178
+ addresses to a User, you're actually modifying that user's
179
+ Mailinglist.
@@ -0,0 +1,28 @@
1
+ MAILING LIST CLASSES
2
+
3
+ There are a bunch of flags that are used to describe the different attributes
4
+ of mailing lists. Since these flags are by necessity rather short (a flag
5
+ called anyone_can_send_to_the_mailing_list would certainly be clearer, but I
6
+ feel it'd clutter up the code unnecessarily), here's a list of them and what
7
+ they're for.
8
+
9
+
10
+ FLAG MEANING
11
+ public: true -> anyone can post to it (spammy!)
12
+ false -> only members can post to it <-- DEFAULT
13
+
14
+ closed: true -> only the owner can post to it
15
+ false -> other people can post to it <-- DEFAULT
16
+
17
+ moderated: true -> posted messages go to the owner first
18
+ false -> posted messages are broadcast <-- DEFAULT
19
+
20
+ confirmation: true -> subscriptions have to be confirmed <-- DEFAULT
21
+ false -> subscriptions happen automatically
22
+
23
+ joinable: true -> people can subscribe to the list at will <- DEFAULT
24
+ false -> only the owner can subscribe or unsubscribe people
25
+
26
+ archived: true -> all email sent to this address is stored
27
+ false -> all email sent to this address is discarded after being
28
+ processed
@@ -0,0 +1,5 @@
1
+ ---
2
+ rails-environment: production
3
+ database: postgres
4
+ web-server: mongrel
5
+ threads: 2
data/lib/daemonize.rb ADDED
@@ -0,0 +1,56 @@
1
+ module Daemonize
2
+ VERSION = "0.1.2"
3
+
4
+ # Try to fork if at all possible retrying every 5 sec if the
5
+ # maximum process limit for the system has been reached
6
+ def safefork
7
+ tryagain = true
8
+
9
+ while tryagain
10
+ tryagain = false
11
+ begin
12
+ if pid = fork
13
+ return pid
14
+ end
15
+ rescue Errno::EWOULDBLOCK
16
+ sleep 5
17
+ tryagain = true
18
+ end
19
+ end
20
+ end
21
+
22
+ # This method causes the current running process to become a daemon
23
+ # If closefd is true, all existing file descriptors are closed
24
+ def daemonize(oldmode=0, closefd=false)
25
+ srand # Split rand streams between spawning and daemonized process
26
+ safefork and exit # Fork and exit from the parent
27
+
28
+ # Detach from the controlling terminal
29
+ unless sess_id = Process.setsid
30
+ raise 'Cannot detach from controlled terminal'
31
+ end
32
+
33
+ # Prevent the possibility of acquiring a controlling terminal
34
+ if oldmode.zero?
35
+ trap 'SIGHUP', 'IGNORE'
36
+ exit if pid = safefork
37
+ end
38
+
39
+ Dir.chdir "/" # Release old working directory
40
+ File.umask 0000 # Insure sensible umask
41
+
42
+ if closefd
43
+ # Make sure all file descriptors are closed
44
+ ObjectSpace.each_object(IO) do |io|
45
+ unless [STDIN, STDOUT, STDERR].include?(io)
46
+ io.close rescue nil
47
+ end
48
+ end
49
+ end
50
+
51
+ STDIN.reopen "/dev/null" # Free file descriptors and
52
+ STDOUT.reopen "/dev/null", "a" # point them somewhere sensible
53
+ STDERR.reopen STDOUT # STDOUT/STDERR should go to a logfile
54
+ return oldmode ? sess_id : 0 # Return value is mostly irrelevant
55
+ end
56
+ end