root/db/group.cc

Revision f2c6ab73bbeb02eb513a3952a380305eeeae60ff, 8.0 KB (checked in by ajk <ajk@…>, 16 months ago)

#82: Integrate sub/unsub messages and email confirmation messages

Signed-off-by: ajk <ajk@…>

  • Property mode set to 100644
Line 
1/*  This file is part of Alue, the multiprotocol Internet discussion daemon
2
3    Copyright © 2009, 2010, 2011 Antti-Juhani Kaijanaho
4
5    Alue is free software: you can redistribute it and/or modify it
6    under the terms of the GNU General Public License as published by
7    the Free Software Foundation, either version 3 of the License, or
8    (at your option) any later version.
9
10    Alue is distributed in the hope that it will be useful, but
11    WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13    General Public License for more details.
14
15    You should have received a copy of the GNU General Public License
16    along with Alue.  If not, see <http://www.gnu.org/licenses/>.
17
18 */
19
20#include "db.hh"
21#include "group.hh"
22#include "role.hh"
23#include "user.hh"
24
25#include "../config.hh"
26#include "../msg/entity.hh"
27#include "../msg/multipart.hh"
28#include "../msg/lexutils.hh"
29#include "../msg/text_plain.hh"
30#include "../smtp_client/smtp_client.hh"
31#include "../tlate/data_model.hh"
32#include "../tlate/group_value.hh"
33#include "../tlate/user_value.hh"
34#include "../tlate/tlate.hh"
35
36#include "../assert.hh"
37
38namespace db
39{
40        group::group(std::string name,
41                     boost::shared_ptr<db> dbase,
42                     boost::posix_time::ptime stamp,
43                     bool reading_restricted, std::string descr)
44                : the_name(name), stamp(stamp),
45                  descr(descr),
46                  dbase(dbase),
47                  count(0), displacement(1)
48        {
49                if (!reading_restricted) readers.insert(role::anon());
50                readers.insert(role::authn());
51                posters.insert(role::poster());
52        }
53
54
55        group::number group::file(boost::shared_ptr<msg::msg> m,
56                                  server::conn_cb cb)
57        {
58                msgs.push_back(m);
59                number rv = displacement + msgs.size() - 1;
60                m->xref(shared_from_this(), rv);
61                count++;
62
63                ensure_subscriber_role();
64                const std::set<boost::shared_ptr<user> > &us =
65                        subscriber_role->get_users();
66                std::list<std::string> recv;
67                for (std::set<boost::shared_ptr<user> >::const_iterator it =
68                             us.begin();
69                     it != us.end(); it++)
70                {
71                        user::ptr u = *it;
72                        if (!u->is_delivery_email_verified()) continue;
73                        recv.push_back(u->get_delivery_email());
74                }
75
76                if (recv.empty()) return rv;
77
78                ::msg::multipart::ptr nm =
79                          m->get_entity()->clone_as_multipart();
80                {
81                        std::string subject = nm->get_field("subject", false);
82                        util::strip_crlf(subject);
83                        std::string tag = "["; tag += the_name; tag += "]";
84                        if (subject.find(tag) == std::string::npos)
85                                nm->replace_field("Subject",
86                                                  tag + " " + subject);
87                }
88                nm->replace_field("To",
89                                  name() + "@" +
90                                  config["canonical-name"].as<std::string>());
91                nm->replace_field("List-Id",
92                                  "<" +
93                                  name() + "." +
94                                  config["canonical-name"].as<std::string>() +
95                                  ">");
96
97                tlate::data_model::ptr mam(new tlate::data_model);
98                mam->insert("group", new tlate::group_value(shared_from_this(),
99                                                            user::ptr()));
100
101                boost::shared_ptr<tlate::tlate> tl =
102                        tlate::tlate::parse("sub_footer.txt");
103                std::ostringstream mos;
104                mos << tl->eval(mam);
105                ::msg::text_plain::ptr sub(new ::msg::text_plain
106                                           (mos.str(),
107                                            ::msg::content_type(DEFAULT_CT)));
108                nm->append_part(sub);
109                                 
110                cb.smtpc().send_mail(recv, nm->get_entity());
111
112                return rv;
113        }
114
115        void group::file(boost::shared_ptr<msg::msg> m, number n)
116        {
117                assert(n >= displacement);
118                if (msgs.empty()) displacement = n;
119                size_t n_ = n - displacement;
120                if (n_ >= msgs.size()) msgs.resize(n_+1);
121                msgs[n_] = m;
122                m->xref(shared_from_this(), n);
123                count++;
124        }
125
126        bool group::authz(boost::shared_ptr<const user> u,
127                          const std::set<role::ptr> & rs)
128        {
129                if (!u) return rs.find(role::anon()) != rs.end();
130                const std::set<role::ptr> & urs = u->get_roles();
131                for (std::set<role::ptr>::const_iterator it
132                             = urs.begin();
133                     it != urs.end(); it++)
134                {
135                        if (rs.find(*it) != rs.end()) return true;
136                }
137                return false;
138        }
139        void group::ensure_subscriber_role()
140        {
141                if (subscriber_role) return;
142
143                std::string subrn = role::get_subscriber_role(the_name);
144                subscriber_role = dbase->lookup_role(subrn);
145                if (!subscriber_role)
146                {
147                        subscriber_role = dbase->create_role(subrn, "");
148                }
149        }
150
151        void group::send_submail(user::const_ptr u, const char *tln,
152                                 server::conn_cb cb)
153        {
154                std::string ton = u->get_display_name();
155                std::string to = u->get_delivery_email();
156                std::string from =
157                        config["alue-name"].as<std::string>() +
158                        " <" +
159                        config["operator-email"].as<std::string>() +
160                        ">";
161
162                tlate::data_model::ptr mam(new tlate::data_model);
163                mam->insert("from", from);
164                mam->insert("to",
165                            ::msg::make_phrase(ton) + " <" + to + ">");
166                mam->insert("user", new tlate::user_value(u));
167                mam->insert("group",
168                            new tlate::group_value(shared_from_this(), u));
169
170                boost::shared_ptr<tlate::tlate> tl = tlate::tlate::parse(tln);
171                std::ostringstream mos;
172                mos << tl->eval(mam);
173                       
174                std::list<std::string> recv;
175                recv.push_back(to);
176                               
177                cb.smtpc().send_mail(recv, mos.str());
178        }
179
180        void group::add_subscriber(boost::shared_ptr<user> u,
181                                   server::conn_cb cb,
182                                   boost::asio::ip::address peer)
183        {
184                BOOST_ASSERT(u);
185                ensure_subscriber_role();
186                u->add_role(subscriber_role);
187                if (!u->is_delivery_email_verified())
188                        u->send_delivery_email_cookie
189                                (cb, peer.to_string());
190                else
191                        send_submail(u, "sub.msg", cb);
192        }
193        void group::delete_subscriber(boost::shared_ptr<user> u,
194                                      server::conn_cb cb)
195        {
196                ensure_subscriber_role();
197                u->delete_role(subscriber_role);
198                if (u->is_delivery_email_verified())
199                        send_submail(u, "unsub.msg", cb);
200        }
201        bool group::is_subscriber(boost::shared_ptr<const user> u)
202        {
203                if (!u) return false;
204                ensure_subscriber_role();
205                const std::set<boost::shared_ptr<role> > &rs = u->get_roles();
206                return rs.find(subscriber_role) != rs.end();
207        }
208}
Note: See TracBrowser for help on using the browser.