Statistics
| Branch: | Tag: | Revision:

root / snf-astakos-app / astakos / im / functions.py @ a989b48e

History | View | Annotate | Download (28.5 kB)

1 abd8467c Giorgos Korfiatis
# Copyright 2011, 2012, 2013 GRNET S.A. All rights reserved.
2 5ce3ce4f Sofia Papagiannaki
#
3 f36af44a Antony Chazapis
# Redistribution and use in source and binary forms, with or
4 f36af44a Antony Chazapis
# without modification, are permitted provided that the following
5 f36af44a Antony Chazapis
# conditions are met:
6 5ce3ce4f Sofia Papagiannaki
#
7 f36af44a Antony Chazapis
#   1. Redistributions of source code must retain the above
8 f36af44a Antony Chazapis
#      copyright notice, this list of conditions and the following
9 f36af44a Antony Chazapis
#      disclaimer.
10 5ce3ce4f Sofia Papagiannaki
#
11 f36af44a Antony Chazapis
#   2. Redistributions in binary form must reproduce the above
12 f36af44a Antony Chazapis
#      copyright notice, this list of conditions and the following
13 f36af44a Antony Chazapis
#      disclaimer in the documentation and/or other materials
14 f36af44a Antony Chazapis
#      provided with the distribution.
15 5ce3ce4f Sofia Papagiannaki
#
16 f36af44a Antony Chazapis
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17 f36af44a Antony Chazapis
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 f36af44a Antony Chazapis
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 f36af44a Antony Chazapis
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20 f36af44a Antony Chazapis
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 f36af44a Antony Chazapis
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 f36af44a Antony Chazapis
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23 f36af44a Antony Chazapis
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24 f36af44a Antony Chazapis
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 f36af44a Antony Chazapis
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26 f36af44a Antony Chazapis
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 f36af44a Antony Chazapis
# POSSIBILITY OF SUCH DAMAGE.
28 5ce3ce4f Sofia Papagiannaki
#
29 f36af44a Antony Chazapis
# The views and conclusions contained in the software and
30 f36af44a Antony Chazapis
# documentation are those of the authors and should not be
31 f36af44a Antony Chazapis
# interpreted as representing official policies, either expressed
32 f36af44a Antony Chazapis
# or implied, of GRNET S.A.
33 f36af44a Antony Chazapis
34 f36af44a Antony Chazapis
import logging
35 8f5a3a06 Sofia Papagiannaki
import socket
36 f36af44a Antony Chazapis
37 f36af44a Antony Chazapis
from django.utils.translation import ugettext as _
38 f36af44a Antony Chazapis
from django.template.loader import render_to_string
39 f9224cc0 Sofia Papagiannaki
from django.core.mail import send_mail, get_connection
40 f36af44a Antony Chazapis
from django.core.urlresolvers import reverse
41 49790d9d Sofia Papagiannaki
from django.template import Context, loader
42 bf0c6de5 Sofia Papagiannaki
from django.contrib.auth import (
43 bf0c6de5 Sofia Papagiannaki
    login as auth_login,
44 73fbaec4 Sofia Papagiannaki
    logout as auth_logout)
45 1cbce16f Sofia Papagiannaki
from django.conf import settings
46 9a06d96f Olga Brani
from django.contrib.auth.models import AnonymousUser
47 73fbaec4 Sofia Papagiannaki
from django.core.exceptions import PermissionDenied
48 974ee6a6 Sofia Papagiannaki
from django.db import IntegrityError
49 ff67242a Giorgos Korfiatis
from django.http import Http404
50 27e26a41 Sofia Papagiannaki
51 683cf244 Sofia Papagiannaki
from urllib import quote
52 f36af44a Antony Chazapis
from urlparse import urljoin
53 8f5a3a06 Sofia Papagiannaki
from smtplib import SMTPException
54 751d24cf Sofia Papagiannaki
from datetime import datetime
55 111f3da6 Sofia Papagiannaki
from functools import wraps
56 f36af44a Antony Chazapis
57 c7c0ec58 Giorgos Korfiatis
import astakos.im.settings as astakos_settings
58 bf0c6de5 Sofia Papagiannaki
from astakos.im.settings import (
59 c0b26605 Sofia Papagiannaki
    DEFAULT_CONTACT_EMAIL, SITENAME, BASEURL, LOGGING_LEVEL,
60 c0b26605 Sofia Papagiannaki
    VERIFICATION_EMAIL_SUBJECT, ACCOUNT_CREATION_SUBJECT,
61 c0b26605 Sofia Papagiannaki
    GROUP_CREATION_SUBJECT, HELPDESK_NOTIFICATION_EMAIL_SUBJECT,
62 c0b26605 Sofia Papagiannaki
    INVITATION_EMAIL_SUBJECT, GREETING_EMAIL_SUBJECT, FEEDBACK_EMAIL_SUBJECT,
63 73fbaec4 Sofia Papagiannaki
    EMAIL_CHANGE_EMAIL_SUBJECT,
64 73fbaec4 Sofia Papagiannaki
    PROJECT_CREATION_SUBJECT, PROJECT_APPROVED_SUBJECT,
65 73fbaec4 Sofia Papagiannaki
    PROJECT_TERMINATION_SUBJECT, PROJECT_SUSPENSION_SUBJECT,
66 272cf735 Sofia Papagiannaki
    PROJECT_MEMBERSHIP_CHANGE_SUBJECT,
67 272cf735 Sofia Papagiannaki
    PROJECT_MEMBER_JOIN_POLICIES, PROJECT_MEMBER_LEAVE_POLICIES)
68 73fbaec4 Sofia Papagiannaki
from astakos.im.notifications import build_notification, NotificationError
69 73fbaec4 Sofia Papagiannaki
from astakos.im.models import (
70 e30537f1 Sofia Papagiannaki
    AstakosUser, Invitation, ProjectMembership, ProjectApplication, Project,
71 c7c0ec58 Giorgos Korfiatis
    UserSetting,
72 a989b48e Giorgos Korfiatis
    PendingMembershipError, get_resource_names, new_chain,
73 a989b48e Giorgos Korfiatis
    users_quotas)
74 a3eb3a95 Giorgos Korfiatis
from astakos.im.project_notif import (
75 466cc12c Giorgos Korfiatis
    membership_change_notify, membership_enroll_notify,
76 bb6a4465 Giorgos Korfiatis
    membership_request_notify, membership_leave_request_notify,
77 a3eb3a95 Giorgos Korfiatis
    application_submit_notify, application_approve_notify,
78 19eb3ee6 Giorgos Korfiatis
    application_deny_notify,
79 a3eb3a95 Giorgos Korfiatis
    project_termination_notify, project_suspension_notify)
80 a989b48e Giorgos Korfiatis
from astakos.im.endpoints.qh import (
81 a989b48e Giorgos Korfiatis
    register_users, register_quotas, qh_get_quota)
82 73fbaec4 Sofia Papagiannaki
83 ae497612 Olga Brani
import astakos.im.messages as astakos_messages
84 f36af44a Antony Chazapis
85 f36af44a Antony Chazapis
logger = logging.getLogger(__name__)
86 f36af44a Antony Chazapis
87 5ce3ce4f Sofia Papagiannaki
88 111f3da6 Sofia Papagiannaki
def logged(func, msg):
89 111f3da6 Sofia Papagiannaki
    @wraps(func)
90 111f3da6 Sofia Papagiannaki
    def with_logging(*args, **kwargs):
91 111f3da6 Sofia Papagiannaki
        email = ''
92 111f3da6 Sofia Papagiannaki
        user = None
93 9a06d96f Olga Brani
        try:
94 111f3da6 Sofia Papagiannaki
            request = args[0]
95 9a06d96f Olga Brani
            email = request.user.email
96 9a06d96f Olga Brani
        except (KeyError, AttributeError), e:
97 9a06d96f Olga Brani
            email = ''
98 111f3da6 Sofia Papagiannaki
        r = func(*args, **kwargs)
99 c9e378c7 Sofia Papagiannaki
        if LOGGING_LEVEL:
100 aab4d540 Sofia Papagiannaki
            logger.log(LOGGING_LEVEL, msg % email)
101 111f3da6 Sofia Papagiannaki
        return r
102 111f3da6 Sofia Papagiannaki
    return with_logging
103 111f3da6 Sofia Papagiannaki
104 bf0c6de5 Sofia Papagiannaki
105 bf0c6de5 Sofia Papagiannaki
def login(request, user):
106 bf0c6de5 Sofia Papagiannaki
    auth_login(request, user)
107 c3c2212a Sofia Papagiannaki
    from astakos.im.models import SessionCatalog
108 c3c2212a Sofia Papagiannaki
    SessionCatalog(
109 c0b26605 Sofia Papagiannaki
        session_key=request.session.session_key,
110 c3c2212a Sofia Papagiannaki
        user=user
111 c3c2212a Sofia Papagiannaki
    ).save()
112 bf0c6de5 Sofia Papagiannaki
113 bf0c6de5 Sofia Papagiannaki
login = logged(login, '%s logged in.')
114 111f3da6 Sofia Papagiannaki
logout = logged(auth_logout, '%s logged out.')
115 111f3da6 Sofia Papagiannaki
116 5ce3ce4f Sofia Papagiannaki
117 683cf244 Sofia Papagiannaki
def send_verification(user, template_name='im/activation_email.txt'):
118 f36af44a Antony Chazapis
    """
119 683cf244 Sofia Papagiannaki
    Send email to user to verify his/her email and activate his/her account.
120 5ce3ce4f Sofia Papagiannaki

121 8f5a3a06 Sofia Papagiannaki
    Raises SendVerificationError
122 f36af44a Antony Chazapis
    """
123 6ff7a7ca Sofia Papagiannaki
    url = '%s?auth=%s&next=%s' % (urljoin(BASEURL, reverse('activate')),
124 5ce3ce4f Sofia Papagiannaki
                                  quote(user.auth_token),
125 5ce3ce4f Sofia Papagiannaki
                                  quote(urljoin(BASEURL, reverse('index'))))
126 683cf244 Sofia Papagiannaki
    message = render_to_string(template_name, {
127 5ce3ce4f Sofia Papagiannaki
                               'user': user,
128 5ce3ce4f Sofia Papagiannaki
                               'url': url,
129 5ce3ce4f Sofia Papagiannaki
                               'baseurl': BASEURL,
130 5ce3ce4f Sofia Papagiannaki
                               'site_name': SITENAME,
131 5ce3ce4f Sofia Papagiannaki
                               'support': DEFAULT_CONTACT_EMAIL})
132 1cbce16f Sofia Papagiannaki
    sender = settings.SERVER_EMAIL
133 8f5a3a06 Sofia Papagiannaki
    try:
134 f9224cc0 Sofia Papagiannaki
        send_mail(_(VERIFICATION_EMAIL_SUBJECT), message, sender, [user.email],
135 f9224cc0 Sofia Papagiannaki
                  connection=get_connection())
136 f9224cc0 Sofia Papagiannaki
137 8f5a3a06 Sofia Papagiannaki
    except (SMTPException, socket.error) as e:
138 8f5a3a06 Sofia Papagiannaki
        logger.exception(e)
139 8f5a3a06 Sofia Papagiannaki
        raise SendVerificationError()
140 8f5a3a06 Sofia Papagiannaki
    else:
141 111f3da6 Sofia Papagiannaki
        msg = 'Sent activation %s' % user.email
142 aab4d540 Sofia Papagiannaki
        logger.log(LOGGING_LEVEL, msg)
143 683cf244 Sofia Papagiannaki
144 5ce3ce4f Sofia Papagiannaki
145 751d24cf Sofia Papagiannaki
def send_activation(user, template_name='im/activation_email.txt'):
146 751d24cf Sofia Papagiannaki
    send_verification(user, template_name)
147 751d24cf Sofia Papagiannaki
    user.activation_sent = datetime.now()
148 751d24cf Sofia Papagiannaki
    user.save()
149 683cf244 Sofia Papagiannaki
150 5ce3ce4f Sofia Papagiannaki
151 9a06d96f Olga Brani
def _send_admin_notification(template_name,
152 9a06d96f Olga Brani
                             dictionary=None,
153 9a06d96f Olga Brani
                             subject='alpha2 testing notification',):
154 683cf244 Sofia Papagiannaki
    """
155 1cbce16f Sofia Papagiannaki
    Send notification email to settings.ADMINS.
156 5ce3ce4f Sofia Papagiannaki

157 8f5a3a06 Sofia Papagiannaki
    Raises SendNotificationError
158 683cf244 Sofia Papagiannaki
    """
159 1cbce16f Sofia Papagiannaki
    if not settings.ADMINS:
160 683cf244 Sofia Papagiannaki
        return
161 aab4d540 Sofia Papagiannaki
    dictionary = dictionary or {}
162 3abf6c78 Sofia Papagiannaki
    message = render_to_string(template_name, dictionary)
163 1cbce16f Sofia Papagiannaki
    sender = settings.SERVER_EMAIL
164 8f5a3a06 Sofia Papagiannaki
    try:
165 f9224cc0 Sofia Papagiannaki
        send_mail(subject, message, sender, [i[1] for i in settings.ADMINS],
166 f9224cc0 Sofia Papagiannaki
                  connection=get_connection())
167 8f5a3a06 Sofia Papagiannaki
    except (SMTPException, socket.error) as e:
168 8f5a3a06 Sofia Papagiannaki
        logger.exception(e)
169 8f5a3a06 Sofia Papagiannaki
        raise SendNotificationError()
170 8f5a3a06 Sofia Papagiannaki
    else:
171 4327c8fc Kostas Papadimitriou
        msg = 'Sent admin notification for user %s' % dictionary.get('email',
172 4327c8fc Kostas Papadimitriou
                                                                     None)
173 aab4d540 Sofia Papagiannaki
        logger.log(LOGGING_LEVEL, msg)
174 683cf244 Sofia Papagiannaki
175 5ce3ce4f Sofia Papagiannaki
176 9a06d96f Olga Brani
def send_account_creation_notification(template_name, dictionary=None):
177 9a06d96f Olga Brani
    user = dictionary.get('user', AnonymousUser())
178 29b87e7c Sofia Papagiannaki
    subject = _(ACCOUNT_CREATION_SUBJECT) % {'user':user.get('email', '')}
179 9a06d96f Olga Brani
    return _send_admin_notification(template_name, dictionary, subject=subject)
180 9a06d96f Olga Brani
181 9a06d96f Olga Brani
182 f9aea9c8 Sofia Papagiannaki
def send_helpdesk_notification(user, template_name='im/helpdesk_notification.txt'):
183 a0be6a0c Sofia Papagiannaki
    """
184 a0be6a0c Sofia Papagiannaki
    Send email to DEFAULT_CONTACT_EMAIL to notify for a new user activation.
185 5ce3ce4f Sofia Papagiannaki

186 a0be6a0c Sofia Papagiannaki
    Raises SendNotificationError
187 a0be6a0c Sofia Papagiannaki
    """
188 a0be6a0c Sofia Papagiannaki
    if not DEFAULT_CONTACT_EMAIL:
189 a0be6a0c Sofia Papagiannaki
        return
190 3abf6c78 Sofia Papagiannaki
    message = render_to_string(
191 3abf6c78 Sofia Papagiannaki
        template_name,
192 3abf6c78 Sofia Papagiannaki
        {'user': user}
193 3abf6c78 Sofia Papagiannaki
    )
194 1cbce16f Sofia Papagiannaki
    sender = settings.SERVER_EMAIL
195 a0be6a0c Sofia Papagiannaki
    try:
196 f9224cc0 Sofia Papagiannaki
        send_mail(_(HELPDESK_NOTIFICATION_EMAIL_SUBJECT) % {'user': user.email},
197 f9224cc0 Sofia Papagiannaki
                  message, sender, [DEFAULT_CONTACT_EMAIL],
198 f9224cc0 Sofia Papagiannaki
                  connection=get_connection())
199 a0be6a0c Sofia Papagiannaki
    except (SMTPException, socket.error) as e:
200 a0be6a0c Sofia Papagiannaki
        logger.exception(e)
201 a0be6a0c Sofia Papagiannaki
        raise SendNotificationError()
202 a0be6a0c Sofia Papagiannaki
    else:
203 3abf6c78 Sofia Papagiannaki
        msg = 'Sent helpdesk admin notification for %s' % user.email
204 aab4d540 Sofia Papagiannaki
        logger.log(LOGGING_LEVEL, msg)
205 a0be6a0c Sofia Papagiannaki
206 5ce3ce4f Sofia Papagiannaki
207 683cf244 Sofia Papagiannaki
def send_invitation(invitation, template_name='im/invitation.txt'):
208 683cf244 Sofia Papagiannaki
    """
209 683cf244 Sofia Papagiannaki
    Send invitation email.
210 5ce3ce4f Sofia Papagiannaki

211 8f5a3a06 Sofia Papagiannaki
    Raises SendInvitationError
212 683cf244 Sofia Papagiannaki
    """
213 1fcf4a99 Kostas Papadimitriou
    subject = _(INVITATION_EMAIL_SUBJECT)
214 6ff7a7ca Sofia Papagiannaki
    url = '%s?code=%d' % (urljoin(BASEURL, reverse('index')), invitation.code)
215 aab4d540 Sofia Papagiannaki
    message = render_to_string(template_name, {
216 5ce3ce4f Sofia Papagiannaki
                               'invitation': invitation,
217 5ce3ce4f Sofia Papagiannaki
                               'url': url,
218 5ce3ce4f Sofia Papagiannaki
                               'baseurl': BASEURL,
219 5ce3ce4f Sofia Papagiannaki
                               'site_name': SITENAME,
220 5ce3ce4f Sofia Papagiannaki
                               'support': DEFAULT_CONTACT_EMAIL})
221 1cbce16f Sofia Papagiannaki
    sender = settings.SERVER_EMAIL
222 8f5a3a06 Sofia Papagiannaki
    try:
223 f9224cc0 Sofia Papagiannaki
        send_mail(subject, message, sender, [invitation.username],
224 f9224cc0 Sofia Papagiannaki
                  connection=get_connection())
225 8f5a3a06 Sofia Papagiannaki
    except (SMTPException, socket.error) as e:
226 8f5a3a06 Sofia Papagiannaki
        logger.exception(e)
227 8f5a3a06 Sofia Papagiannaki
        raise SendInvitationError()
228 8f5a3a06 Sofia Papagiannaki
    else:
229 111f3da6 Sofia Papagiannaki
        msg = 'Sent invitation %s' % invitation
230 aab4d540 Sofia Papagiannaki
        logger.log(LOGGING_LEVEL, msg)
231 f9224cc0 Sofia Papagiannaki
        inviter_invitations = invitation.inviter.invitations
232 f9224cc0 Sofia Papagiannaki
        invitation.inviter.invitations = max(0, inviter_invitations - 1)
233 9a06d96f Olga Brani
        invitation.inviter.save()
234 683cf244 Sofia Papagiannaki
235 5ce3ce4f Sofia Papagiannaki
236 683cf244 Sofia Papagiannaki
def send_greeting(user, email_template_name='im/welcome_email.txt'):
237 683cf244 Sofia Papagiannaki
    """
238 683cf244 Sofia Papagiannaki
    Send welcome email.
239 5ce3ce4f Sofia Papagiannaki

240 f36af44a Antony Chazapis
    Raises SMTPException, socket.error
241 f36af44a Antony Chazapis
    """
242 4f78c22c Sofia Papagiannaki
    subject = _(GREETING_EMAIL_SUBJECT)
243 f36af44a Antony Chazapis
    message = render_to_string(email_template_name, {
244 5ce3ce4f Sofia Papagiannaki
                               'user': user,
245 5ce3ce4f Sofia Papagiannaki
                               'url': urljoin(BASEURL, reverse('index')),
246 5ce3ce4f Sofia Papagiannaki
                               'baseurl': BASEURL,
247 5ce3ce4f Sofia Papagiannaki
                               'site_name': SITENAME,
248 5ce3ce4f Sofia Papagiannaki
                               'support': DEFAULT_CONTACT_EMAIL})
249 1cbce16f Sofia Papagiannaki
    sender = settings.SERVER_EMAIL
250 8f5a3a06 Sofia Papagiannaki
    try:
251 f9224cc0 Sofia Papagiannaki
        send_mail(subject, message, sender, [user.email],
252 f9224cc0 Sofia Papagiannaki
                  connection=get_connection())
253 8f5a3a06 Sofia Papagiannaki
    except (SMTPException, socket.error) as e:
254 8f5a3a06 Sofia Papagiannaki
        logger.exception(e)
255 8f5a3a06 Sofia Papagiannaki
        raise SendGreetingError()
256 8f5a3a06 Sofia Papagiannaki
    else:
257 111f3da6 Sofia Papagiannaki
        msg = 'Sent greeting %s' % user.email
258 aab4d540 Sofia Papagiannaki
        logger.log(LOGGING_LEVEL, msg)
259 8f5a3a06 Sofia Papagiannaki
260 5ce3ce4f Sofia Papagiannaki
261 8f5a3a06 Sofia Papagiannaki
def send_feedback(msg, data, user, email_template_name='im/feedback_mail.txt'):
262 4f78c22c Sofia Papagiannaki
    subject = _(FEEDBACK_EMAIL_SUBJECT)
263 7d145e78 Sofia Papagiannaki
    from_email = settings.SERVER_EMAIL
264 8f5a3a06 Sofia Papagiannaki
    recipient_list = [DEFAULT_CONTACT_EMAIL]
265 8f5a3a06 Sofia Papagiannaki
    content = render_to_string(email_template_name, {
266 8f5a3a06 Sofia Papagiannaki
        'message': msg,
267 8f5a3a06 Sofia Papagiannaki
        'data': data,
268 8f5a3a06 Sofia Papagiannaki
        'user': user})
269 8f5a3a06 Sofia Papagiannaki
    try:
270 f9224cc0 Sofia Papagiannaki
        send_mail(subject, content, from_email, recipient_list,
271 f9224cc0 Sofia Papagiannaki
                  connection=get_connection())
272 8f5a3a06 Sofia Papagiannaki
    except (SMTPException, socket.error) as e:
273 8f5a3a06 Sofia Papagiannaki
        logger.exception(e)
274 8f5a3a06 Sofia Papagiannaki
        raise SendFeedbackError()
275 8f5a3a06 Sofia Papagiannaki
    else:
276 111f3da6 Sofia Papagiannaki
        msg = 'Sent feedback from %s' % user.email
277 aab4d540 Sofia Papagiannaki
        logger.log(LOGGING_LEVEL, msg)
278 f36af44a Antony Chazapis
279 5ce3ce4f Sofia Papagiannaki
280 73fbaec4 Sofia Papagiannaki
def send_change_email(
281 73fbaec4 Sofia Papagiannaki
    ec, request, email_template_name='registration/email_change_email.txt'):
282 49790d9d Sofia Papagiannaki
    try:
283 34a76cdb Kostas Papadimitriou
        url = ec.get_url()
284 49790d9d Sofia Papagiannaki
        url = request.build_absolute_uri(url)
285 49790d9d Sofia Papagiannaki
        t = loader.get_template(email_template_name)
286 9301c7f9 Sofia Papagiannaki
        c = {'url': url, 'site_name': SITENAME,
287 c9b3d7b0 Kostas Papadimitriou
             'support': DEFAULT_CONTACT_EMAIL, 'ec': ec}
288 1cbce16f Sofia Papagiannaki
        from_email = settings.SERVER_EMAIL
289 f9224cc0 Sofia Papagiannaki
        send_mail(_(EMAIL_CHANGE_EMAIL_SUBJECT), t.render(Context(c)),
290 f9224cc0 Sofia Papagiannaki
                  from_email, [ec.new_email_address],
291 f9224cc0 Sofia Papagiannaki
                  connection=get_connection())
292 49790d9d Sofia Papagiannaki
    except (SMTPException, socket.error) as e:
293 49790d9d Sofia Papagiannaki
        logger.exception(e)
294 49790d9d Sofia Papagiannaki
        raise ChangeEmailError()
295 49790d9d Sofia Papagiannaki
    else:
296 111f3da6 Sofia Papagiannaki
        msg = 'Sent change email for %s' % ec.user.email
297 aab4d540 Sofia Papagiannaki
        logger.log(LOGGING_LEVEL, msg)
298 f36af44a Antony Chazapis
299 5ce3ce4f Sofia Papagiannaki
300 f9aea9c8 Sofia Papagiannaki
def activate(
301 f9aea9c8 Sofia Papagiannaki
    user,
302 f9aea9c8 Sofia Papagiannaki
    email_template_name='im/welcome_email.txt',
303 f9aea9c8 Sofia Papagiannaki
    helpdesk_email_template_name='im/helpdesk_notification.txt',
304 73fbaec4 Sofia Papagiannaki
    verify_email=False):
305 683cf244 Sofia Papagiannaki
    """
306 683cf244 Sofia Papagiannaki
    Activates the specific user and sends email.
307 5ce3ce4f Sofia Papagiannaki

308 27e26a41 Sofia Papagiannaki
    Raises SendGreetingError, ValidationError
309 683cf244 Sofia Papagiannaki
    """
310 683cf244 Sofia Papagiannaki
    user.is_active = True
311 4bdd7e3d Kostas Papadimitriou
    user.email_verified = True
312 f1ab6639 Kostas Papadimitriou
    if not user.activation_sent:
313 f1ab6639 Kostas Papadimitriou
        user.activation_sent = datetime.now()
314 683cf244 Sofia Papagiannaki
    user.save()
315 a989b48e Giorgos Korfiatis
    register_user_with_quotas(user)
316 23b9b72f Sofia Papagiannaki
    send_helpdesk_notification(user, helpdesk_email_template_name)
317 683cf244 Sofia Papagiannaki
    send_greeting(user, email_template_name)
318 683cf244 Sofia Papagiannaki
319 21e0fdad Giorgos Korfiatis
def deactivate(user):
320 21e0fdad Giorgos Korfiatis
    user.is_active = False
321 21e0fdad Giorgos Korfiatis
    user.save()
322 21e0fdad Giorgos Korfiatis
323 73fbaec4 Sofia Papagiannaki
def invite(inviter, email, realname):
324 73fbaec4 Sofia Papagiannaki
    inv = Invitation(inviter=inviter, username=email, realname=realname)
325 73fbaec4 Sofia Papagiannaki
    inv.save()
326 73fbaec4 Sofia Papagiannaki
    send_invitation(inv)
327 e30537f1 Sofia Papagiannaki
    inviter.invitations = max(0, inviter.invitations - 1)
328 73fbaec4 Sofia Papagiannaki
    inviter.save()
329 5ce3ce4f Sofia Papagiannaki
330 9a06d96f Olga Brani
def switch_account_to_shibboleth(user, local_user,
331 9a06d96f Olga Brani
                                 greeting_template_name='im/welcome_email.txt'):
332 9a06d96f Olga Brani
    try:
333 9a06d96f Olga Brani
        provider = user.provider
334 9a06d96f Olga Brani
    except AttributeError:
335 23b9b72f Sofia Papagiannaki
        return
336 9a06d96f Olga Brani
    else:
337 9a06d96f Olga Brani
        if not provider == 'shibboleth':
338 9a06d96f Olga Brani
            return
339 9a06d96f Olga Brani
        user.delete()
340 9a06d96f Olga Brani
        local_user.provider = 'shibboleth'
341 9a06d96f Olga Brani
        local_user.third_party_identifier = user.third_party_identifier
342 9a06d96f Olga Brani
        local_user.save()
343 9a06d96f Olga Brani
        send_greeting(local_user, greeting_template_name)
344 9a06d96f Olga Brani
        return local_user
345 59f598f1 Sofia Papagiannaki
346 5ce3ce4f Sofia Papagiannaki
347 8f5a3a06 Sofia Papagiannaki
class SendMailError(Exception):
348 18ffbee1 Sofia Papagiannaki
    pass
349 8f5a3a06 Sofia Papagiannaki
350 5ce3ce4f Sofia Papagiannaki
351 8f5a3a06 Sofia Papagiannaki
class SendAdminNotificationError(SendMailError):
352 8f5a3a06 Sofia Papagiannaki
    def __init__(self):
353 ae497612 Olga Brani
        self.message = _(astakos_messages.ADMIN_NOTIFICATION_SEND_ERR)
354 18ffbee1 Sofia Papagiannaki
        super(SendAdminNotificationError, self).__init__()
355 8f5a3a06 Sofia Papagiannaki
356 5ce3ce4f Sofia Papagiannaki
357 18ffbee1 Sofia Papagiannaki
class SendVerificationError(SendMailError):
358 8f5a3a06 Sofia Papagiannaki
    def __init__(self):
359 ae497612 Olga Brani
        self.message = _(astakos_messages.VERIFICATION_SEND_ERR)
360 18ffbee1 Sofia Papagiannaki
        super(SendVerificationError, self).__init__()
361 8f5a3a06 Sofia Papagiannaki
362 5ce3ce4f Sofia Papagiannaki
363 18ffbee1 Sofia Papagiannaki
class SendInvitationError(SendMailError):
364 8f5a3a06 Sofia Papagiannaki
    def __init__(self):
365 ae497612 Olga Brani
        self.message = _(astakos_messages.INVITATION_SEND_ERR)
366 18ffbee1 Sofia Papagiannaki
        super(SendInvitationError, self).__init__()
367 8f5a3a06 Sofia Papagiannaki
368 5ce3ce4f Sofia Papagiannaki
369 18ffbee1 Sofia Papagiannaki
class SendGreetingError(SendMailError):
370 8f5a3a06 Sofia Papagiannaki
    def __init__(self):
371 ae497612 Olga Brani
        self.message = _(astakos_messages.GREETING_SEND_ERR)
372 18ffbee1 Sofia Papagiannaki
        super(SendGreetingError, self).__init__()
373 8f5a3a06 Sofia Papagiannaki
374 5ce3ce4f Sofia Papagiannaki
375 18ffbee1 Sofia Papagiannaki
class SendFeedbackError(SendMailError):
376 8f5a3a06 Sofia Papagiannaki
    def __init__(self):
377 ae497612 Olga Brani
        self.message = _(astakos_messages.FEEDBACK_SEND_ERR)
378 49790d9d Sofia Papagiannaki
        super(SendFeedbackError, self).__init__()
379 49790d9d Sofia Papagiannaki
380 5ce3ce4f Sofia Papagiannaki
381 49790d9d Sofia Papagiannaki
class ChangeEmailError(SendMailError):
382 49790d9d Sofia Papagiannaki
    def __init__(self):
383 ccab6eb5 Sofia Papagiannaki
        self.message = _(astakos_messages.CHANGE_EMAIL_SEND_ERR)
384 35f8ccf1 Sofia Papagiannaki
        super(ChangeEmailError, self).__init__()
385 a0be6a0c Sofia Papagiannaki
386 5ce3ce4f Sofia Papagiannaki
387 a0be6a0c Sofia Papagiannaki
class SendNotificationError(SendMailError):
388 a0be6a0c Sofia Papagiannaki
    def __init__(self):
389 ae497612 Olga Brani
        self.message = _(astakos_messages.NOTIFICATION_SEND_ERR)
390 a0be6a0c Sofia Papagiannaki
        super(SendNotificationError, self).__init__()
391 73fbaec4 Sofia Papagiannaki
392 73fbaec4 Sofia Papagiannaki
393 a989b48e Giorgos Korfiatis
def register_user_with_quotas(user):
394 a989b48e Giorgos Korfiatis
    rejected = register_users([user])
395 a989b48e Giorgos Korfiatis
    if not rejected:
396 a989b48e Giorgos Korfiatis
        quotas = users_quotas([user])
397 a989b48e Giorgos Korfiatis
        register_quotas(quotas)
398 a989b48e Giorgos Korfiatis
399 a989b48e Giorgos Korfiatis
400 84a3f701 Giorgos Korfiatis
def get_quota(users):
401 0514bcc7 Giorgos Korfiatis
    resources = get_resource_names()
402 84a3f701 Giorgos Korfiatis
    return qh_get_quota(users, resources)
403 0514bcc7 Giorgos Korfiatis
404 0514bcc7 Giorgos Korfiatis
405 73fbaec4 Sofia Papagiannaki
### PROJECT VIEWS ###
406 fcc1e93f Sofia Papagiannaki
407 b0686c16 Giorgos Korfiatis
AUTO_ACCEPT_POLICY = 1
408 b0686c16 Giorgos Korfiatis
MODERATED_POLICY   = 2
409 b0686c16 Giorgos Korfiatis
CLOSED_POLICY      = 3
410 b0686c16 Giorgos Korfiatis
411 b0686c16 Giorgos Korfiatis
POLICIES = [ AUTO_ACCEPT_POLICY, MODERATED_POLICY, CLOSED_POLICY ]
412 73fbaec4 Sofia Papagiannaki
413 73fbaec4 Sofia Papagiannaki
def get_project_by_application_id(project_application_id):
414 73fbaec4 Sofia Papagiannaki
    try:
415 73fbaec4 Sofia Papagiannaki
        return Project.objects.get(application__id=project_application_id)
416 73fbaec4 Sofia Papagiannaki
    except Project.DoesNotExist:
417 73fbaec4 Sofia Papagiannaki
        raise IOError(
418 73fbaec4 Sofia Papagiannaki
            _(astakos_messages.UNKNOWN_PROJECT_APPLICATION_ID) % project_application_id)
419 73fbaec4 Sofia Papagiannaki
420 a75dbd7b Giorgos Korfiatis
def get_related_project_id(application_id):
421 a75dbd7b Giorgos Korfiatis
    try:
422 a75dbd7b Giorgos Korfiatis
        app = ProjectApplication.objects.get(id=application_id)
423 a75dbd7b Giorgos Korfiatis
        chain = app.chain
424 a75dbd7b Giorgos Korfiatis
        project = Project.objects.get(id=chain)
425 a75dbd7b Giorgos Korfiatis
        return chain
426 a75dbd7b Giorgos Korfiatis
    except:
427 a75dbd7b Giorgos Korfiatis
        return None
428 a75dbd7b Giorgos Korfiatis
429 0932ac43 Giorgos Korfiatis
def get_chain_of_application_id(application_id):
430 0932ac43 Giorgos Korfiatis
    try:
431 0932ac43 Giorgos Korfiatis
        app = ProjectApplication.objects.get(id=application_id)
432 0932ac43 Giorgos Korfiatis
        chain = app.chain
433 0932ac43 Giorgos Korfiatis
        return chain.chain
434 0932ac43 Giorgos Korfiatis
    except:
435 0932ac43 Giorgos Korfiatis
        return None
436 0932ac43 Giorgos Korfiatis
437 eb9ff37a Sofia Papagiannaki
def get_project_by_id(project_id):
438 eb9ff37a Sofia Papagiannaki
    try:
439 eb9ff37a Sofia Papagiannaki
        return Project.objects.get(id=project_id)
440 eb9ff37a Sofia Papagiannaki
    except Project.DoesNotExist:
441 eb9ff37a Sofia Papagiannaki
        raise IOError(
442 eb9ff37a Sofia Papagiannaki
            _(astakos_messages.UNKNOWN_PROJECT_ID) % project_id)
443 eb9ff37a Sofia Papagiannaki
444 c10f1cf5 Giorgos Korfiatis
def get_project_by_name(name):
445 c10f1cf5 Giorgos Korfiatis
    try:
446 c10f1cf5 Giorgos Korfiatis
        return Project.objects.get(name=name)
447 c10f1cf5 Giorgos Korfiatis
    except Project.DoesNotExist:
448 c10f1cf5 Giorgos Korfiatis
        raise IOError(
449 e30537f1 Sofia Papagiannaki
            _(astakos_messages.UNKNOWN_PROJECT_ID) % name)
450 c10f1cf5 Giorgos Korfiatis
451 c10f1cf5 Giorgos Korfiatis
452 8dcaa6ac Giorgos Korfiatis
def get_project_for_update(project_id):
453 8dcaa6ac Giorgos Korfiatis
    try:
454 ea1e5d9f Giorgos Korfiatis
        return Project.objects.get_for_update(id=project_id)
455 8dcaa6ac Giorgos Korfiatis
    except Project.DoesNotExist:
456 8dcaa6ac Giorgos Korfiatis
        raise IOError(
457 8dcaa6ac Giorgos Korfiatis
            _(astakos_messages.UNKNOWN_PROJECT_ID) % project_id)
458 8dcaa6ac Giorgos Korfiatis
459 19eb3ee6 Giorgos Korfiatis
def get_application_for_update(application_id):
460 19eb3ee6 Giorgos Korfiatis
    try:
461 ea1e5d9f Giorgos Korfiatis
        return ProjectApplication.objects.get_for_update(id=application_id)
462 19eb3ee6 Giorgos Korfiatis
    except ProjectApplication.DoesNotExist:
463 19eb3ee6 Giorgos Korfiatis
        m = _(astakos_messages.UNKNOWN_PROJECT_APPLICATION_ID) % application_id
464 19eb3ee6 Giorgos Korfiatis
        raise IOError(m)
465 19eb3ee6 Giorgos Korfiatis
466 73fbaec4 Sofia Papagiannaki
def get_user_by_id(user_id):
467 73fbaec4 Sofia Papagiannaki
    try:
468 974ee6a6 Sofia Papagiannaki
        return AstakosUser.objects.get(id=user_id)
469 73fbaec4 Sofia Papagiannaki
    except AstakosUser.DoesNotExist:
470 73fbaec4 Sofia Papagiannaki
        raise IOError(_(astakos_messages.UNKNOWN_USER_ID) % user_id)
471 73fbaec4 Sofia Papagiannaki
472 3c049f6d Giorgos Korfiatis
def get_user_by_uuid(uuid):
473 3c049f6d Giorgos Korfiatis
    try:
474 3c049f6d Giorgos Korfiatis
        return AstakosUser.objects.get(uuid=uuid)
475 3c049f6d Giorgos Korfiatis
    except AstakosUser.DoesNotExist:
476 e30537f1 Sofia Papagiannaki
        raise IOError(_(astakos_messages.UNKNOWN_USER_ID) % uuid)
477 3c049f6d Giorgos Korfiatis
478 7dd3047d Sofia Papagiannaki
def create_membership(project, user):
479 8c7229a8 Giorgos Korfiatis
    if isinstance(user, (int, long)):
480 7dd3047d Sofia Papagiannaki
        user = get_user_by_id(user)
481 97e93991 Kostas Papadimitriou
482 d9907a5e Giorgos Korfiatis
    if not user.is_active:
483 d9907a5e Giorgos Korfiatis
        m = _(astakos_messages.ACCOUNT_NOT_ACTIVE)
484 d9907a5e Giorgos Korfiatis
        raise PermissionDenied(m)
485 d9907a5e Giorgos Korfiatis
486 abd8467c Giorgos Korfiatis
    m, created = ProjectMembership.objects.get_or_create(
487 7dd3047d Sofia Papagiannaki
        project=project,
488 abd8467c Giorgos Korfiatis
        person=user)
489 abd8467c Giorgos Korfiatis
490 abd8467c Giorgos Korfiatis
    if created:
491 fc61dfb7 Sofia Papagiannaki
        return m
492 abd8467c Giorgos Korfiatis
    else:
493 abd8467c Giorgos Korfiatis
        msg = _(astakos_messages.MEMBERSHIP_REQUEST_EXISTS)
494 abd8467c Giorgos Korfiatis
        raise PermissionDenied(msg)
495 abd8467c Giorgos Korfiatis
496 73fbaec4 Sofia Papagiannaki
497 8dcaa6ac Giorgos Korfiatis
def get_membership_for_update(project, user):
498 8c7229a8 Giorgos Korfiatis
    if isinstance(user, (int, long)):
499 73fbaec4 Sofia Papagiannaki
        user = get_user_by_id(user)
500 73fbaec4 Sofia Papagiannaki
    try:
501 ea1e5d9f Giorgos Korfiatis
        objs = ProjectMembership.objects
502 ea1e5d9f Giorgos Korfiatis
        m = objs.get_for_update(project=project, person=user)
503 b6fe8bb8 Giorgos Korfiatis
        if m.is_pending:
504 b6fe8bb8 Giorgos Korfiatis
            raise PendingMembershipError()
505 b6fe8bb8 Giorgos Korfiatis
        return m
506 73fbaec4 Sofia Papagiannaki
    except ProjectMembership.DoesNotExist:
507 73fbaec4 Sofia Papagiannaki
        raise IOError(_(astakos_messages.NOT_MEMBERSHIP_REQUEST))
508 73fbaec4 Sofia Papagiannaki
509 3c638f72 Giorgos Korfiatis
def checkAllowed(entity, request_user):
510 3c638f72 Giorgos Korfiatis
    if isinstance(entity, Project):
511 3c638f72 Giorgos Korfiatis
        application = entity.application
512 3c638f72 Giorgos Korfiatis
    elif isinstance(entity, ProjectApplication):
513 3c638f72 Giorgos Korfiatis
        application = entity
514 3c638f72 Giorgos Korfiatis
    else:
515 3c638f72 Giorgos Korfiatis
        m = "%s not a Project nor a ProjectApplication" % (entity,)
516 3c638f72 Giorgos Korfiatis
        raise ValueError(m)
517 3c638f72 Giorgos Korfiatis
518 907f15db Giorgos Korfiatis
    if request_user and \
519 3c638f72 Giorgos Korfiatis
        (not application.owner == request_user and \
520 907f15db Giorgos Korfiatis
            not request_user.is_superuser):
521 907f15db Giorgos Korfiatis
        raise PermissionDenied(_(astakos_messages.NOT_ALLOWED))
522 907f15db Giorgos Korfiatis
523 907f15db Giorgos Korfiatis
def checkAlive(project):
524 907f15db Giorgos Korfiatis
    if not project.is_alive:
525 907f15db Giorgos Korfiatis
        raise PermissionDenied(
526 907f15db Giorgos Korfiatis
            _(astakos_messages.NOT_ALIVE_PROJECT) % project.__dict__)
527 907f15db Giorgos Korfiatis
528 ff67242a Giorgos Korfiatis
def accept_membership_checks(project, request_user):
529 907f15db Giorgos Korfiatis
    checkAllowed(project, request_user)
530 907f15db Giorgos Korfiatis
    checkAlive(project)
531 b0686c16 Giorgos Korfiatis
532 b0686c16 Giorgos Korfiatis
    join_policy = project.application.member_join_policy
533 b0686c16 Giorgos Korfiatis
    if join_policy == CLOSED_POLICY:
534 b0686c16 Giorgos Korfiatis
        raise PermissionDenied(_(astakos_messages.MEMBER_JOIN_POLICY_CLOSED))
535 b0686c16 Giorgos Korfiatis
536 8dcaa6ac Giorgos Korfiatis
    if project.violates_members_limit(adding=1):
537 73fbaec4 Sofia Papagiannaki
        raise PermissionDenied(_(astakos_messages.MEMBER_NUMBER_LIMIT_REACHED))
538 73fbaec4 Sofia Papagiannaki
539 ff67242a Giorgos Korfiatis
def accept_membership(project_id, user, request_user=None):
540 e47fb17a Sofia Papagiannaki
    project = get_project_for_update(project_id)
541 ff67242a Giorgos Korfiatis
    accept_membership_checks(project, request_user)
542 14f7f6a5 Giorgos Korfiatis
543 8dcaa6ac Giorgos Korfiatis
    membership = get_membership_for_update(project, user)
544 14f7f6a5 Giorgos Korfiatis
    if not membership.can_accept():
545 14f7f6a5 Giorgos Korfiatis
        m = _(astakos_messages.NOT_MEMBERSHIP_REQUEST)
546 14f7f6a5 Giorgos Korfiatis
        raise PermissionDenied(m)
547 d4fc6292 Giorgos Korfiatis
548 73fbaec4 Sofia Papagiannaki
    membership.accept()
549 73fbaec4 Sofia Papagiannaki
550 a3eb3a95 Giorgos Korfiatis
    membership_change_notify(project, membership.person, 'accepted')
551 a3eb3a95 Giorgos Korfiatis
552 73fbaec4 Sofia Papagiannaki
    return membership
553 73fbaec4 Sofia Papagiannaki
554 ff67242a Giorgos Korfiatis
def reject_membership_checks(project, request_user):
555 907f15db Giorgos Korfiatis
    checkAllowed(project, request_user)
556 907f15db Giorgos Korfiatis
    checkAlive(project)
557 e47fb17a Sofia Papagiannaki
558 ff67242a Giorgos Korfiatis
def reject_membership(project_id, user, request_user=None):
559 e47fb17a Sofia Papagiannaki
    project = get_project_for_update(project_id)
560 ff67242a Giorgos Korfiatis
    reject_membership_checks(project, request_user)
561 8dcaa6ac Giorgos Korfiatis
    membership = get_membership_for_update(project, user)
562 14f7f6a5 Giorgos Korfiatis
    if not membership.can_reject():
563 14f7f6a5 Giorgos Korfiatis
        m = _(astakos_messages.NOT_MEMBERSHIP_REQUEST)
564 14f7f6a5 Giorgos Korfiatis
        raise PermissionDenied(m)
565 d4fc6292 Giorgos Korfiatis
566 73fbaec4 Sofia Papagiannaki
    membership.reject()
567 73fbaec4 Sofia Papagiannaki
568 a3eb3a95 Giorgos Korfiatis
    membership_change_notify(project, membership.person, 'rejected')
569 a3eb3a95 Giorgos Korfiatis
570 73fbaec4 Sofia Papagiannaki
    return membership
571 73fbaec4 Sofia Papagiannaki
572 aad0e329 Giorgos Korfiatis
def cancel_membership_checks(project):
573 aad0e329 Giorgos Korfiatis
    checkAlive(project)
574 aad0e329 Giorgos Korfiatis
575 aad0e329 Giorgos Korfiatis
def cancel_membership(project_id, user_id):
576 aad0e329 Giorgos Korfiatis
    project = get_project_for_update(project_id)
577 aad0e329 Giorgos Korfiatis
    cancel_membership_checks(project)
578 aad0e329 Giorgos Korfiatis
    membership = get_membership_for_update(project, user_id)
579 aad0e329 Giorgos Korfiatis
    if not membership.can_cancel():
580 aad0e329 Giorgos Korfiatis
        m = _(astakos_messages.NOT_MEMBERSHIP_REQUEST)
581 aad0e329 Giorgos Korfiatis
        raise PermissionDenied(m)
582 aad0e329 Giorgos Korfiatis
583 aad0e329 Giorgos Korfiatis
    membership.cancel()
584 aad0e329 Giorgos Korfiatis
585 ff67242a Giorgos Korfiatis
def remove_membership_checks(project, request_user=None):
586 907f15db Giorgos Korfiatis
    checkAllowed(project, request_user)
587 907f15db Giorgos Korfiatis
    checkAlive(project)
588 73fbaec4 Sofia Papagiannaki
589 b0686c16 Giorgos Korfiatis
    leave_policy = project.application.member_leave_policy
590 b0686c16 Giorgos Korfiatis
    if leave_policy == CLOSED_POLICY:
591 b0686c16 Giorgos Korfiatis
        raise PermissionDenied(_(astakos_messages.MEMBER_LEAVE_POLICY_CLOSED))
592 b0686c16 Giorgos Korfiatis
593 ff67242a Giorgos Korfiatis
def remove_membership(project_id, user, request_user=None):
594 907f15db Giorgos Korfiatis
    project = get_project_for_update(project_id)
595 ff67242a Giorgos Korfiatis
    remove_membership_checks(project, request_user)
596 8dcaa6ac Giorgos Korfiatis
    membership = get_membership_for_update(project, user)
597 14f7f6a5 Giorgos Korfiatis
    if not membership.can_remove():
598 14f7f6a5 Giorgos Korfiatis
        m = _(astakos_messages.NOT_ACCEPTED_MEMBERSHIP)
599 14f7f6a5 Giorgos Korfiatis
        raise PermissionDenied(m)
600 d4fc6292 Giorgos Korfiatis
601 73fbaec4 Sofia Papagiannaki
    membership.remove()
602 73fbaec4 Sofia Papagiannaki
603 a3eb3a95 Giorgos Korfiatis
    membership_change_notify(project, membership.person, 'removed')
604 a3eb3a95 Giorgos Korfiatis
605 73fbaec4 Sofia Papagiannaki
    return membership
606 73fbaec4 Sofia Papagiannaki
607 ff67242a Giorgos Korfiatis
def enroll_member(project_id, user, request_user=None):
608 907f15db Giorgos Korfiatis
    project = get_project_for_update(project_id)
609 ff67242a Giorgos Korfiatis
    accept_membership_checks(project, request_user)
610 abd8467c Giorgos Korfiatis
    membership = create_membership(project, user)
611 14f7f6a5 Giorgos Korfiatis
612 14f7f6a5 Giorgos Korfiatis
    if not membership.can_accept():
613 14f7f6a5 Giorgos Korfiatis
        m = _(astakos_messages.NOT_MEMBERSHIP_REQUEST)
614 14f7f6a5 Giorgos Korfiatis
        raise PermissionDenied(m)
615 d4fc6292 Giorgos Korfiatis
616 907f15db Giorgos Korfiatis
    membership.accept()
617 466cc12c Giorgos Korfiatis
    membership_enroll_notify(project, membership.person)
618 907f15db Giorgos Korfiatis
619 907f15db Giorgos Korfiatis
    return membership
620 8dcaa6ac Giorgos Korfiatis
621 ff67242a Giorgos Korfiatis
def leave_project_checks(project):
622 907f15db Giorgos Korfiatis
    checkAlive(project)
623 8dcaa6ac Giorgos Korfiatis
624 03869281 Sofia Papagiannaki
    leave_policy = project.application.member_leave_policy
625 b0686c16 Giorgos Korfiatis
    if leave_policy == CLOSED_POLICY:
626 73fbaec4 Sofia Papagiannaki
        raise PermissionDenied(_(astakos_messages.MEMBER_LEAVE_POLICY_CLOSED))
627 73fbaec4 Sofia Papagiannaki
628 d4660e00 Giorgos Korfiatis
def can_leave_request(project, user):
629 d4660e00 Giorgos Korfiatis
    leave_policy = project.application.member_leave_policy
630 d4660e00 Giorgos Korfiatis
    if leave_policy == CLOSED_POLICY:
631 d4660e00 Giorgos Korfiatis
        return False
632 d4660e00 Giorgos Korfiatis
    m = user.get_membership(project)
633 d4660e00 Giorgos Korfiatis
    if m is None:
634 d4660e00 Giorgos Korfiatis
        return False
635 d4660e00 Giorgos Korfiatis
    if m.state != ProjectMembership.ACCEPTED:
636 d4660e00 Giorgos Korfiatis
        return False
637 d4660e00 Giorgos Korfiatis
    return True
638 d4660e00 Giorgos Korfiatis
639 ff67242a Giorgos Korfiatis
def leave_project(project_id, user_id):
640 e47fb17a Sofia Papagiannaki
    project = get_project_for_update(project_id)
641 ff67242a Giorgos Korfiatis
    leave_project_checks(project)
642 8dcaa6ac Giorgos Korfiatis
    membership = get_membership_for_update(project, user_id)
643 14f7f6a5 Giorgos Korfiatis
    if not membership.can_leave():
644 14f7f6a5 Giorgos Korfiatis
        m = _(astakos_messages.NOT_ACCEPTED_MEMBERSHIP)
645 14f7f6a5 Giorgos Korfiatis
        raise PermissionDenied(m)
646 4e057833 Sofia Papagiannaki
647 bb6a4465 Giorgos Korfiatis
    auto_accepted = False
648 4e057833 Sofia Papagiannaki
    leave_policy = project.application.member_leave_policy
649 b0686c16 Giorgos Korfiatis
    if leave_policy == AUTO_ACCEPT_POLICY:
650 73fbaec4 Sofia Papagiannaki
        membership.remove()
651 bb6a4465 Giorgos Korfiatis
        auto_accepted = True
652 73fbaec4 Sofia Papagiannaki
    else:
653 c1007621 Giorgos Korfiatis
        membership.leave_request()
654 bb6a4465 Giorgos Korfiatis
        membership_leave_request_notify(project, membership.person)
655 bb6a4465 Giorgos Korfiatis
    return auto_accepted
656 73fbaec4 Sofia Papagiannaki
657 ff67242a Giorgos Korfiatis
def join_project_checks(project):
658 907f15db Giorgos Korfiatis
    checkAlive(project)
659 8dcaa6ac Giorgos Korfiatis
660 974ee6a6 Sofia Papagiannaki
    join_policy = project.application.member_join_policy
661 b0686c16 Giorgos Korfiatis
    if join_policy == CLOSED_POLICY:
662 73fbaec4 Sofia Papagiannaki
        raise PermissionDenied(_(astakos_messages.MEMBER_JOIN_POLICY_CLOSED))
663 73fbaec4 Sofia Papagiannaki
664 d4660e00 Giorgos Korfiatis
def can_join_request(project, user):
665 d4660e00 Giorgos Korfiatis
    join_policy = project.application.member_join_policy
666 d4660e00 Giorgos Korfiatis
    if join_policy == CLOSED_POLICY:
667 d4660e00 Giorgos Korfiatis
        return False
668 d4660e00 Giorgos Korfiatis
    m = user.get_membership(project)
669 d4660e00 Giorgos Korfiatis
    if m:
670 d4660e00 Giorgos Korfiatis
        return False
671 d4660e00 Giorgos Korfiatis
    return True
672 d4660e00 Giorgos Korfiatis
673 ff67242a Giorgos Korfiatis
def join_project(project_id, user_id):
674 e47fb17a Sofia Papagiannaki
    project = get_project_for_update(project_id)
675 ff67242a Giorgos Korfiatis
    join_project_checks(project)
676 14f7f6a5 Giorgos Korfiatis
    membership = create_membership(project, user_id)
677 73fbaec4 Sofia Papagiannaki
678 bb6a4465 Giorgos Korfiatis
    auto_accepted = False
679 4e057833 Sofia Papagiannaki
    join_policy = project.application.member_join_policy
680 b0686c16 Giorgos Korfiatis
    if (join_policy == AUTO_ACCEPT_POLICY and
681 a073c3b2 Giorgos Korfiatis
        not project.violates_members_limit(adding=1)):
682 73fbaec4 Sofia Papagiannaki
        membership.accept()
683 bb6a4465 Giorgos Korfiatis
        auto_accepted = True
684 bb6a4465 Giorgos Korfiatis
    else:
685 bb6a4465 Giorgos Korfiatis
        membership_request_notify(project, membership.person)
686 bb6a4465 Giorgos Korfiatis
687 bb6a4465 Giorgos Korfiatis
    return auto_accepted
688 8dcaa6ac Giorgos Korfiatis
689 ee4aa6eb Giorgos Korfiatis
def submit_application(kw, request_user=None):
690 ee4aa6eb Giorgos Korfiatis
691 ee4aa6eb Giorgos Korfiatis
    kw['applicant'] = request_user
692 3e3743f2 Giorgos Korfiatis
    resource_policies = kw.pop('resource_policies', None)
693 69c822cc Giorgos Korfiatis
694 3e3743f2 Giorgos Korfiatis
    precursor = None
695 15ca2bea Giorgos Korfiatis
    precursor_id = kw.get('precursor_application', None)
696 15ca2bea Giorgos Korfiatis
    if precursor_id is not None:
697 ea1e5d9f Giorgos Korfiatis
        objs = ProjectApplication.objects
698 ea1e5d9f Giorgos Korfiatis
        precursor = objs.get_for_update(id=precursor_id)
699 15ca2bea Giorgos Korfiatis
        kw['precursor_application'] = precursor
700 73fbaec4 Sofia Papagiannaki
701 3e3743f2 Giorgos Korfiatis
        if (request_user and
702 3e3743f2 Giorgos Korfiatis
            (not precursor.owner == request_user and
703 beda5f0f Georgios D. Tsoukalas
             not request_user.is_superuser
704 beda5f0f Georgios D. Tsoukalas
             and not request_user.is_project_admin())):
705 3e3743f2 Giorgos Korfiatis
            m = _(astakos_messages.NOT_ALLOWED)
706 3e3743f2 Giorgos Korfiatis
            raise PermissionDenied(m)
707 ee4aa6eb Giorgos Korfiatis
708 c7c0ec58 Giorgos Korfiatis
    reached, limit = reached_pending_application_limit(request_user.id, precursor)
709 c7c0ec58 Giorgos Korfiatis
    if reached:
710 c7c0ec58 Giorgos Korfiatis
        m = _(astakos_messages.REACHED_PENDING_APPLICATION_LIMIT) % limit
711 c7c0ec58 Giorgos Korfiatis
        raise PermissionDenied(m)
712 c7c0ec58 Giorgos Korfiatis
713 3e3743f2 Giorgos Korfiatis
    application = ProjectApplication(**kw)
714 1352dabb Kostas Papadimitriou
715 3e3743f2 Giorgos Korfiatis
    if precursor is None:
716 3e3743f2 Giorgos Korfiatis
        application.chain = new_chain()
717 3e3743f2 Giorgos Korfiatis
    else:
718 3e3743f2 Giorgos Korfiatis
        chain = precursor.chain
719 3e3743f2 Giorgos Korfiatis
        application.chain = chain
720 ea1e5d9f Giorgos Korfiatis
        objs = ProjectApplication.objects
721 ea1e5d9f Giorgos Korfiatis
        q = objs.filter(chain=chain, state=ProjectApplication.PENDING)
722 ea1e5d9f Giorgos Korfiatis
        pending = q.select_for_update()
723 3e3743f2 Giorgos Korfiatis
        for app in pending:
724 3e3743f2 Giorgos Korfiatis
            app.state = ProjectApplication.REPLACED
725 3e3743f2 Giorgos Korfiatis
            app.save()
726 3e3743f2 Giorgos Korfiatis
727 3e3743f2 Giorgos Korfiatis
    application.save()
728 3e3743f2 Giorgos Korfiatis
    application.resource_policies = resource_policies
729 a3eb3a95 Giorgos Korfiatis
    application_submit_notify(application)
730 a3eb3a95 Giorgos Korfiatis
    return application
731 73fbaec4 Sofia Papagiannaki
732 3c638f72 Giorgos Korfiatis
def cancel_application(application_id, request_user=None):
733 3c638f72 Giorgos Korfiatis
    application = get_application_for_update(application_id)
734 3c638f72 Giorgos Korfiatis
    checkAllowed(application, request_user)
735 3c638f72 Giorgos Korfiatis
736 01bdbd17 Giorgos Korfiatis
    if not application.can_cancel():
737 01bdbd17 Giorgos Korfiatis
        m = _(astakos_messages.APPLICATION_CANNOT_CANCEL % (
738 01bdbd17 Giorgos Korfiatis
                application.id, application.state_display()))
739 01bdbd17 Giorgos Korfiatis
        raise PermissionDenied(m)
740 3c638f72 Giorgos Korfiatis
741 3c638f72 Giorgos Korfiatis
    application.cancel()
742 3c638f72 Giorgos Korfiatis
743 3c638f72 Giorgos Korfiatis
def dismiss_application(application_id, request_user=None):
744 3c638f72 Giorgos Korfiatis
    application = get_application_for_update(application_id)
745 3c638f72 Giorgos Korfiatis
    checkAllowed(application, request_user)
746 3c638f72 Giorgos Korfiatis
747 01bdbd17 Giorgos Korfiatis
    if not application.can_dismiss():
748 01bdbd17 Giorgos Korfiatis
        m = _(astakos_messages.APPLICATION_CANNOT_DISMISS % (
749 01bdbd17 Giorgos Korfiatis
                application.id, application.state_display()))
750 01bdbd17 Giorgos Korfiatis
        raise PermissionDenied(m)
751 3c638f72 Giorgos Korfiatis
752 3c638f72 Giorgos Korfiatis
    application.dismiss()
753 3c638f72 Giorgos Korfiatis
754 19eb3ee6 Giorgos Korfiatis
def deny_application(application_id):
755 19eb3ee6 Giorgos Korfiatis
    application = get_application_for_update(application_id)
756 01bdbd17 Giorgos Korfiatis
757 01bdbd17 Giorgos Korfiatis
    if not application.can_deny():
758 01bdbd17 Giorgos Korfiatis
        m = _(astakos_messages.APPLICATION_CANNOT_DENY % (
759 01bdbd17 Giorgos Korfiatis
                application.id, application.state_display()))
760 01bdbd17 Giorgos Korfiatis
        raise PermissionDenied(m)
761 19eb3ee6 Giorgos Korfiatis
762 19eb3ee6 Giorgos Korfiatis
    application.deny()
763 19eb3ee6 Giorgos Korfiatis
    application_deny_notify(application)
764 19eb3ee6 Giorgos Korfiatis
765 6cee26a0 Giorgos Korfiatis
def approve_application(app_id):
766 8dcaa6ac Giorgos Korfiatis
767 8dcaa6ac Giorgos Korfiatis
    try:
768 ea1e5d9f Giorgos Korfiatis
        objects = ProjectApplication.objects
769 ea1e5d9f Giorgos Korfiatis
        application = objects.get_for_update(id=app_id)
770 8dcaa6ac Giorgos Korfiatis
    except ProjectApplication.DoesNotExist:
771 6cee26a0 Giorgos Korfiatis
        m = _(astakos_messages.UNKNOWN_PROJECT_APPLICATION_ID % (app_id,))
772 6cee26a0 Giorgos Korfiatis
        raise PermissionDenied(m)
773 8dcaa6ac Giorgos Korfiatis
774 01bdbd17 Giorgos Korfiatis
    if not application.can_approve():
775 01bdbd17 Giorgos Korfiatis
        m = _(astakos_messages.APPLICATION_CANNOT_APPROVE % (
776 01bdbd17 Giorgos Korfiatis
                application.id, application.state_display()))
777 01bdbd17 Giorgos Korfiatis
        raise PermissionDenied(m)
778 01bdbd17 Giorgos Korfiatis
779 73fbaec4 Sofia Papagiannaki
    application.approve()
780 a3eb3a95 Giorgos Korfiatis
    application_approve_notify(application)
781 eb9ff37a Sofia Papagiannaki
782 7eadc230 Giorgos Korfiatis
def check_expiration(execute=False):
783 7eadc230 Giorgos Korfiatis
    objects = Project.objects
784 7eadc230 Giorgos Korfiatis
    expired = objects.expired_projects()
785 7eadc230 Giorgos Korfiatis
    if execute:
786 7eadc230 Giorgos Korfiatis
        for project in expired:
787 7eadc230 Giorgos Korfiatis
            terminate(project.id)
788 7eadc230 Giorgos Korfiatis
789 7eadc230 Giorgos Korfiatis
    return [project.expiration_info() for project in expired]
790 7eadc230 Giorgos Korfiatis
791 eb9ff37a Sofia Papagiannaki
def terminate(project_id):
792 5b9e9530 Giorgos Korfiatis
    project = get_project_for_update(project_id)
793 907f15db Giorgos Korfiatis
    checkAlive(project)
794 5b9e9530 Giorgos Korfiatis
795 5b9e9530 Giorgos Korfiatis
    project.terminate()
796 eb9ff37a Sofia Papagiannaki
797 a3eb3a95 Giorgos Korfiatis
    project_termination_notify(project)
798 eb9ff37a Sofia Papagiannaki
799 eb9ff37a Sofia Papagiannaki
def suspend(project_id):
800 eb9ff37a Sofia Papagiannaki
    project = get_project_by_id(project_id)
801 db99f198 Giorgos Korfiatis
    checkAlive(project)
802 db99f198 Giorgos Korfiatis
803 db99f198 Giorgos Korfiatis
    project.suspend()
804 1352dabb Kostas Papadimitriou
805 a3eb3a95 Giorgos Korfiatis
    project_suspension_notify(project)
806 db99f198 Giorgos Korfiatis
807 db99f198 Giorgos Korfiatis
def resume(project_id):
808 db99f198 Giorgos Korfiatis
    project = get_project_for_update(project_id)
809 db99f198 Giorgos Korfiatis
810 db99f198 Giorgos Korfiatis
    if not project.is_suspended:
811 db99f198 Giorgos Korfiatis
        m = _(astakos_messages.NOT_SUSPENDED_PROJECT) % project.__dict__
812 db99f198 Giorgos Korfiatis
        raise PermissionDenied(m)
813 db99f198 Giorgos Korfiatis
814 db99f198 Giorgos Korfiatis
    project.resume()
815 ff67242a Giorgos Korfiatis
816 ff67242a Giorgos Korfiatis
def get_by_chain_or_404(chain_id):
817 ff67242a Giorgos Korfiatis
    try:
818 ff67242a Giorgos Korfiatis
        project = Project.objects.get(id=chain_id)
819 ff67242a Giorgos Korfiatis
        application = project.application
820 ff67242a Giorgos Korfiatis
        return project, application
821 ff67242a Giorgos Korfiatis
    except:
822 ff67242a Giorgos Korfiatis
        application = ProjectApplication.objects.latest_of_chain(chain_id)
823 ff67242a Giorgos Korfiatis
        if application is None:
824 ff67242a Giorgos Korfiatis
            raise Http404
825 ff67242a Giorgos Korfiatis
        else:
826 ff67242a Giorgos Korfiatis
            return None, application
827 c7c0ec58 Giorgos Korfiatis
828 c7c0ec58 Giorgos Korfiatis
829 c7c0ec58 Giorgos Korfiatis
def get_user_setting(user_id, key):
830 c7c0ec58 Giorgos Korfiatis
    try:
831 c7c0ec58 Giorgos Korfiatis
        setting = UserSetting.objects.get(
832 c7c0ec58 Giorgos Korfiatis
            user=user_id, setting=key)
833 c7c0ec58 Giorgos Korfiatis
        return setting.value
834 c7c0ec58 Giorgos Korfiatis
    except UserSetting.DoesNotExist:
835 c7c0ec58 Giorgos Korfiatis
        return getattr(astakos_settings, key)
836 c7c0ec58 Giorgos Korfiatis
837 c7c0ec58 Giorgos Korfiatis
838 c7c0ec58 Giorgos Korfiatis
def set_user_setting(user_id, key, value):
839 c7c0ec58 Giorgos Korfiatis
    try:
840 c7c0ec58 Giorgos Korfiatis
        setting = UserSetting.objects.get_for_update(
841 c7c0ec58 Giorgos Korfiatis
            user=user_id, setting=key)
842 c7c0ec58 Giorgos Korfiatis
    except UserSetting.DoesNotExist:
843 c7c0ec58 Giorgos Korfiatis
        setting = UserSetting(user_id=user_id, setting=key)
844 c7c0ec58 Giorgos Korfiatis
    setting.value = value
845 c7c0ec58 Giorgos Korfiatis
    setting.save()
846 c7c0ec58 Giorgos Korfiatis
847 c7c0ec58 Giorgos Korfiatis
848 c7c0ec58 Giorgos Korfiatis
def unset_user_setting(user_id, key):
849 c7c0ec58 Giorgos Korfiatis
    UserSetting.objects.filter(user=user_id, setting=key).delete()
850 c7c0ec58 Giorgos Korfiatis
851 c7c0ec58 Giorgos Korfiatis
852 c7c0ec58 Giorgos Korfiatis
PENDING_APPLICATION_LIMIT_SETTING = 'PENDING_APPLICATION_LIMIT'
853 c7c0ec58 Giorgos Korfiatis
854 c7c0ec58 Giorgos Korfiatis
def get_pending_application_limit(user_id):
855 c7c0ec58 Giorgos Korfiatis
    key = PENDING_APPLICATION_LIMIT_SETTING
856 c7c0ec58 Giorgos Korfiatis
    return get_user_setting(user_id, key)
857 c7c0ec58 Giorgos Korfiatis
858 c7c0ec58 Giorgos Korfiatis
859 c7c0ec58 Giorgos Korfiatis
def set_pending_application_limit(user_id, value):
860 c7c0ec58 Giorgos Korfiatis
    key = PENDING_APPLICATION_LIMIT_SETTING
861 c7c0ec58 Giorgos Korfiatis
    return set_user_setting(user_id, key, value)
862 c7c0ec58 Giorgos Korfiatis
863 c7c0ec58 Giorgos Korfiatis
864 c7c0ec58 Giorgos Korfiatis
def unset_pending_application_limit(user_id):
865 c7c0ec58 Giorgos Korfiatis
    key = PENDING_APPLICATION_LIMIT_SETTING
866 c7c0ec58 Giorgos Korfiatis
    return unset_user_setting(user_id, key)
867 c7c0ec58 Giorgos Korfiatis
868 c7c0ec58 Giorgos Korfiatis
869 c7c0ec58 Giorgos Korfiatis
def _reached_pending_application_limit(user_id):
870 c7c0ec58 Giorgos Korfiatis
    limit = get_pending_application_limit(user_id)
871 c7c0ec58 Giorgos Korfiatis
872 c7c0ec58 Giorgos Korfiatis
    PENDING = ProjectApplication.PENDING
873 c7c0ec58 Giorgos Korfiatis
    pending = ProjectApplication.objects.filter(
874 c7c0ec58 Giorgos Korfiatis
        applicant__id=user_id, state=PENDING).count()
875 c7c0ec58 Giorgos Korfiatis
876 c7c0ec58 Giorgos Korfiatis
    return pending >= limit, limit
877 c7c0ec58 Giorgos Korfiatis
878 c7c0ec58 Giorgos Korfiatis
879 c7c0ec58 Giorgos Korfiatis
def reached_pending_application_limit(user_id, precursor=None):
880 c7c0ec58 Giorgos Korfiatis
    reached, limit = _reached_pending_application_limit(user_id)
881 c7c0ec58 Giorgos Korfiatis
882 c7c0ec58 Giorgos Korfiatis
    if precursor is None:
883 c7c0ec58 Giorgos Korfiatis
        return reached, limit
884 c7c0ec58 Giorgos Korfiatis
885 c7c0ec58 Giorgos Korfiatis
    chain = precursor.chain
886 c7c0ec58 Giorgos Korfiatis
    objs = ProjectApplication.objects
887 c7c0ec58 Giorgos Korfiatis
    q = objs.filter(chain=chain, state=ProjectApplication.PENDING)
888 c7c0ec58 Giorgos Korfiatis
    has_pending = q.exists()
889 c7c0ec58 Giorgos Korfiatis
890 c7c0ec58 Giorgos Korfiatis
    if not has_pending:
891 c7c0ec58 Giorgos Korfiatis
        return reached, limit
892 c7c0ec58 Giorgos Korfiatis
893 c7c0ec58 Giorgos Korfiatis
    return False, limit