Statistics
| Branch: | Tag: | Revision:

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

History | View | Annotate | Download (26 kB)

1 f36af44a Antony Chazapis
# Copyright 2011 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 bf0c6de5 Sofia Papagiannaki
from astakos.im.settings import (
58 c0b26605 Sofia Papagiannaki
    DEFAULT_CONTACT_EMAIL, SITENAME, BASEURL, LOGGING_LEVEL,
59 c0b26605 Sofia Papagiannaki
    VERIFICATION_EMAIL_SUBJECT, ACCOUNT_CREATION_SUBJECT,
60 c0b26605 Sofia Papagiannaki
    GROUP_CREATION_SUBJECT, HELPDESK_NOTIFICATION_EMAIL_SUBJECT,
61 c0b26605 Sofia Papagiannaki
    INVITATION_EMAIL_SUBJECT, GREETING_EMAIL_SUBJECT, FEEDBACK_EMAIL_SUBJECT,
62 73fbaec4 Sofia Papagiannaki
    EMAIL_CHANGE_EMAIL_SUBJECT,
63 73fbaec4 Sofia Papagiannaki
    PROJECT_CREATION_SUBJECT, PROJECT_APPROVED_SUBJECT,
64 73fbaec4 Sofia Papagiannaki
    PROJECT_TERMINATION_SUBJECT, PROJECT_SUSPENSION_SUBJECT,
65 272cf735 Sofia Papagiannaki
    PROJECT_MEMBERSHIP_CHANGE_SUBJECT,
66 272cf735 Sofia Papagiannaki
    PROJECT_MEMBER_JOIN_POLICIES, PROJECT_MEMBER_LEAVE_POLICIES)
67 73fbaec4 Sofia Papagiannaki
from astakos.im.notifications import build_notification, NotificationError
68 73fbaec4 Sofia Papagiannaki
from astakos.im.models import (
69 974ee6a6 Sofia Papagiannaki
    AstakosUser, ProjectMembership, ProjectApplication, Project,
70 8cf9b2dd Giorgos Korfiatis
    PendingMembershipError, get_resource_names, new_chain)
71 a3eb3a95 Giorgos Korfiatis
from astakos.im.project_notif import (
72 466cc12c Giorgos Korfiatis
    membership_change_notify, membership_enroll_notify,
73 bb6a4465 Giorgos Korfiatis
    membership_request_notify, membership_leave_request_notify,
74 a3eb3a95 Giorgos Korfiatis
    application_submit_notify, application_approve_notify,
75 19eb3ee6 Giorgos Korfiatis
    application_deny_notify,
76 a3eb3a95 Giorgos Korfiatis
    project_termination_notify, project_suspension_notify)
77 84a3f701 Giorgos Korfiatis
from astakos.im.endpoints.qh import qh_register_user_with_quotas, qh_get_quota
78 73fbaec4 Sofia Papagiannaki
79 ae497612 Olga Brani
import astakos.im.messages as astakos_messages
80 f36af44a Antony Chazapis
81 f36af44a Antony Chazapis
logger = logging.getLogger(__name__)
82 f36af44a Antony Chazapis
83 5ce3ce4f Sofia Papagiannaki
84 111f3da6 Sofia Papagiannaki
def logged(func, msg):
85 111f3da6 Sofia Papagiannaki
    @wraps(func)
86 111f3da6 Sofia Papagiannaki
    def with_logging(*args, **kwargs):
87 111f3da6 Sofia Papagiannaki
        email = ''
88 111f3da6 Sofia Papagiannaki
        user = None
89 9a06d96f Olga Brani
        try:
90 111f3da6 Sofia Papagiannaki
            request = args[0]
91 9a06d96f Olga Brani
            email = request.user.email
92 9a06d96f Olga Brani
        except (KeyError, AttributeError), e:
93 9a06d96f Olga Brani
            email = ''
94 111f3da6 Sofia Papagiannaki
        r = func(*args, **kwargs)
95 c9e378c7 Sofia Papagiannaki
        if LOGGING_LEVEL:
96 aab4d540 Sofia Papagiannaki
            logger.log(LOGGING_LEVEL, msg % email)
97 111f3da6 Sofia Papagiannaki
        return r
98 111f3da6 Sofia Papagiannaki
    return with_logging
99 111f3da6 Sofia Papagiannaki
100 bf0c6de5 Sofia Papagiannaki
101 bf0c6de5 Sofia Papagiannaki
def login(request, user):
102 bf0c6de5 Sofia Papagiannaki
    auth_login(request, user)
103 c3c2212a Sofia Papagiannaki
    from astakos.im.models import SessionCatalog
104 c3c2212a Sofia Papagiannaki
    SessionCatalog(
105 c0b26605 Sofia Papagiannaki
        session_key=request.session.session_key,
106 c3c2212a Sofia Papagiannaki
        user=user
107 c3c2212a Sofia Papagiannaki
    ).save()
108 bf0c6de5 Sofia Papagiannaki
109 bf0c6de5 Sofia Papagiannaki
login = logged(login, '%s logged in.')
110 111f3da6 Sofia Papagiannaki
logout = logged(auth_logout, '%s logged out.')
111 111f3da6 Sofia Papagiannaki
112 5ce3ce4f Sofia Papagiannaki
113 683cf244 Sofia Papagiannaki
def send_verification(user, template_name='im/activation_email.txt'):
114 f36af44a Antony Chazapis
    """
115 683cf244 Sofia Papagiannaki
    Send email to user to verify his/her email and activate his/her account.
116 5ce3ce4f Sofia Papagiannaki

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

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

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

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

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

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