1
2
3 """
4 This file parses messages using functions defined in in the template's
5 parser.py
6
7 @copyright: 2012-2019 (c) Sahana Software Foundation
8 @license: MIT
9
10 Permission is hereby granted, free of charge, to any person
11 obtaining a copy of this software and associated documentation
12 files (the "Software"), to deal in the Software without
13 restriction, including without limitation the rights to use,
14 copy, modify, merge, publish, distribute, sublicense, and/or sell
15 copies of the Software, and to permit persons to whom the
16 Software is furnished to do so, subject to the following
17 conditions:
18
19 The above copyright notice and this permission notice shall be
20 included in all copies or substantial portions of the Software.
21
22 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
24 OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
25 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
26 HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
27 WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
28 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
29 OTHER DEALINGS IN THE SOFTWARE.
30 """
31
32 __all__ = ("S3Parsing",)
33
34 import sys
35
36 from gluon import current
40 """
41 Core Message Parsing Framework
42 - reusable functions
43 """
44
45
46 @staticmethod
47 - def parser(function_name, message_id, **kwargs):
48 """
49 1st Stage Parser
50 - called by msg.parse()
51
52 Sets the appropriate Authorisation level and then calls the
53 parser function from the template
54 """
55
56 reply = None
57 s3db = current.s3db
58
59
60 table = s3db.msg_message
61 message = current.db(table.message_id == message_id).select(limitby=(0, 1)
62 ).first()
63
64 from_address = message.from_address
65 if "<" in from_address:
66 from_address = from_address.split("<")[1].split(">")[0]
67 email = S3Parsing.is_session_alive(from_address)
68 if email:
69 current.auth.s3_impersonate(email)
70 else:
71 (email, password) = S3Parsing.parse_login(message)
72 if email and password:
73 current.auth.login_bare(email, password)
74 expiration = current.session.auth["expiration"]
75 table = s3db.msg_session
76 table.insert(email = email,
77 expiration_time = expiration,
78 from_address = from_address)
79 reply = "Login succesful"
80
81
82
83
84 template = current.deployment_settings.get_msg_parser()
85 module_name = "applications.%s.modules.templates.%s.parser" \
86 % (current.request.application, template)
87 __import__(module_name)
88 mymodule = sys.modules[module_name]
89 S3Parser = mymodule.S3Parser()
90
91
92 try:
93 fn = getattr(S3Parser, function_name)
94 except:
95 current.log.error("Parser not found: %s" % function_name)
96 return None
97
98 reply = fn(message, **kwargs) or reply
99 if not reply:
100 return None
101
102
103 current.msg.send(from_address, reply)
104
105
106 @staticmethod
108 """
109 Authenticate a login request
110 """
111
112 if not message or not message.body:
113 return None, None
114
115 words = message.body.split(" ")
116 login = False
117 email = None
118 password = None
119
120 if "LOGIN" in [word.upper() for word in words]:
121 login = True
122 if len(words) == 2 and login:
123 password = words[1]
124 elif len(words) == 3 and login:
125 email = words[1]
126 password = words[2]
127 if login:
128 if password and not email:
129 email = message.from_address
130 return email, password
131 else:
132 return None, None
133
134
135 @staticmethod
137 """
138 Check whether there is an alive session from the same sender
139 """
140
141 email = None
142 now = current.request.utcnow
143 stable = current.s3db.msg_session
144 query = (stable.is_expired == False) & \
145 (stable.from_address == from_address)
146 records = current.db(query).select(stable.id,
147 stable.created_datetime,
148 stable.expiration_time,
149 stable.email,
150 )
151 for record in records:
152 time = record.created_datetime
153 time = time - now
154 time = time.total_seconds()
155 if time < record.expiration_time:
156 email = record.email
157 break
158 else:
159 record.update_record(is_expired = True)
160
161 return email
162
163
164 @staticmethod
166 """
167 Lookup a Person from an Email Address
168 """
169
170 s3db = current.s3db
171
172 if "<" in address:
173 address = address.split("<")[1].split(">")[0]
174 ptable = s3db.pr_person
175 ctable = s3db.pr_contact
176 query = (ctable.value == address) & \
177 (ctable.contact_method == "EMAIL") & \
178 (ctable.pe_id == ptable.pe_id) & \
179 (ptable.deleted == False) & \
180 (ctable.deleted == False)
181 possibles = current.db(query).select(ptable.id,
182 limitby=(0, 2))
183 if len(possibles) == 1:
184 return possibles.first().id
185
186 return None
187
188
189 @staticmethod
191 """
192 Lookup a Human Resource from an Email Address
193 """
194
195 db = current.db
196 s3db = current.s3db
197
198 if "<" in address:
199 address = address.split("<")[1].split(">")[0]
200 hrtable = s3db.hrm_human_resource
201 ptable = db.pr_person
202 ctable = s3db.pr_contact
203 query = (ctable.value == address) & \
204 (ctable.contact_method == "EMAIL") & \
205 (ctable.pe_id == ptable.pe_id) & \
206 (ptable.id == hrtable.person_id) & \
207 (ctable.deleted == False) & \
208 (ptable.deleted == False) & \
209 (hrtable.deleted == False)
210 possibles = db(query).select(hrtable.id,
211 limitby=(0, 2))
212 if len(possibles) == 1:
213 return possibles.first().id
214
215 return None
216
217
218