Statistics
| Branch: | Tag: | Revision:

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

History | View | Annotate | Download (26.5 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 0932ac43 Giorgos Korfiatis
def get_chain_of_application_id(application_id):
418 0932ac43 Giorgos Korfiatis
    try:
419 0932ac43 Giorgos Korfiatis
        app = ProjectApplication.objects.get(id=application_id)
420 0932ac43 Giorgos Korfiatis
        chain = app.chain
421 0932ac43 Giorgos Korfiatis
        return chain.chain
422 0932ac43 Giorgos Korfiatis
    except:
423 0932ac43 Giorgos Korfiatis
        return None
424 0932ac43 Giorgos Korfiatis
425 eb9ff37a Sofia Papagiannaki
def get_project_by_id(project_id):
426 eb9ff37a Sofia Papagiannaki
    try:
427 eb9ff37a Sofia Papagiannaki
        return Project.objects.get(id=project_id)
428 eb9ff37a Sofia Papagiannaki
    except Project.DoesNotExist:
429 eb9ff37a Sofia Papagiannaki
        raise IOError(
430 eb9ff37a Sofia Papagiannaki
            _(astakos_messages.UNKNOWN_PROJECT_ID) % project_id)
431 eb9ff37a Sofia Papagiannaki
432 c10f1cf5 Giorgos Korfiatis
def get_project_by_name(name):
433 c10f1cf5 Giorgos Korfiatis
    try:
434 c10f1cf5 Giorgos Korfiatis
        return Project.objects.get(name=name)
435 c10f1cf5 Giorgos Korfiatis
    except Project.DoesNotExist:
436 c10f1cf5 Giorgos Korfiatis
        raise IOError(
437 c10f1cf5 Giorgos Korfiatis
            _(astakos_messages.UNKNOWN_PROJECT_ID) % project_id)
438 c10f1cf5 Giorgos Korfiatis
439 c10f1cf5 Giorgos Korfiatis
440 8dcaa6ac Giorgos Korfiatis
def get_project_for_update(project_id):
441 8dcaa6ac Giorgos Korfiatis
    try:
442 8dcaa6ac Giorgos Korfiatis
        return Project.objects.select_for_update().get(id=project_id)
443 8dcaa6ac Giorgos Korfiatis
    except Project.DoesNotExist:
444 8dcaa6ac Giorgos Korfiatis
        raise IOError(
445 8dcaa6ac Giorgos Korfiatis
            _(astakos_messages.UNKNOWN_PROJECT_ID) % project_id)
446 8dcaa6ac Giorgos Korfiatis
447 19eb3ee6 Giorgos Korfiatis
def get_application_for_update(application_id):
448 19eb3ee6 Giorgos Korfiatis
    try:
449 19eb3ee6 Giorgos Korfiatis
        objects = ProjectApplication.objects.select_for_update()
450 19eb3ee6 Giorgos Korfiatis
        return objects.get(id=application_id)
451 19eb3ee6 Giorgos Korfiatis
    except ProjectApplication.DoesNotExist:
452 19eb3ee6 Giorgos Korfiatis
        m = _(astakos_messages.UNKNOWN_PROJECT_APPLICATION_ID) % application_id
453 19eb3ee6 Giorgos Korfiatis
        raise IOError(m)
454 19eb3ee6 Giorgos Korfiatis
455 73fbaec4 Sofia Papagiannaki
def get_user_by_id(user_id):
456 73fbaec4 Sofia Papagiannaki
    try:
457 974ee6a6 Sofia Papagiannaki
        return AstakosUser.objects.get(id=user_id)
458 73fbaec4 Sofia Papagiannaki
    except AstakosUser.DoesNotExist:
459 73fbaec4 Sofia Papagiannaki
        raise IOError(_(astakos_messages.UNKNOWN_USER_ID) % user_id)
460 73fbaec4 Sofia Papagiannaki
461 3c049f6d Giorgos Korfiatis
def get_user_by_uuid(uuid):
462 3c049f6d Giorgos Korfiatis
    try:
463 3c049f6d Giorgos Korfiatis
        return AstakosUser.objects.get(uuid=uuid)
464 3c049f6d Giorgos Korfiatis
    except AstakosUser.DoesNotExist:
465 3c049f6d Giorgos Korfiatis
        raise IOError(_(astakos_messages.UNKNOWN_USER_ID) % user_id)
466 3c049f6d Giorgos Korfiatis
467 7dd3047d Sofia Papagiannaki
def create_membership(project, user):
468 8c7229a8 Giorgos Korfiatis
    if isinstance(project, (int, long)):
469 8dcaa6ac Giorgos Korfiatis
        project = get_project_by_id(project)
470 8c7229a8 Giorgos Korfiatis
    if isinstance(user, (int, long)):
471 7dd3047d Sofia Papagiannaki
        user = get_user_by_id(user)
472 97e93991 Kostas Papadimitriou
473 d9907a5e Giorgos Korfiatis
    if not user.is_active:
474 d9907a5e Giorgos Korfiatis
        m = _(astakos_messages.ACCOUNT_NOT_ACTIVE)
475 d9907a5e Giorgos Korfiatis
        raise PermissionDenied(m)
476 d9907a5e Giorgos Korfiatis
477 7dd3047d Sofia Papagiannaki
    m = ProjectMembership(
478 7dd3047d Sofia Papagiannaki
        project=project,
479 7dd3047d Sofia Papagiannaki
        person=user,
480 7dd3047d Sofia Papagiannaki
        request_date=datetime.now())
481 73fbaec4 Sofia Papagiannaki
    try:
482 7dd3047d Sofia Papagiannaki
        m.save()
483 73fbaec4 Sofia Papagiannaki
    except IntegrityError, e:
484 73fbaec4 Sofia Papagiannaki
        raise IOError(_(astakos_messages.MEMBERSHIP_REQUEST_EXISTS))
485 73fbaec4 Sofia Papagiannaki
    else:
486 fc61dfb7 Sofia Papagiannaki
        return m
487 73fbaec4 Sofia Papagiannaki
488 8dcaa6ac Giorgos Korfiatis
def get_membership_for_update(project, user):
489 8c7229a8 Giorgos Korfiatis
    if isinstance(project, (int, long)):
490 8dcaa6ac Giorgos Korfiatis
        project = get_project_by_id(project)
491 8c7229a8 Giorgos Korfiatis
    if isinstance(user, (int, long)):
492 73fbaec4 Sofia Papagiannaki
        user = get_user_by_id(user)
493 73fbaec4 Sofia Papagiannaki
    try:
494 b6fe8bb8 Giorgos Korfiatis
        sfu = ProjectMembership.objects.select_for_update()
495 b6fe8bb8 Giorgos Korfiatis
        m = sfu.get(project=project, person=user)
496 b6fe8bb8 Giorgos Korfiatis
        if m.is_pending:
497 b6fe8bb8 Giorgos Korfiatis
            raise PendingMembershipError()
498 b6fe8bb8 Giorgos Korfiatis
        return m
499 73fbaec4 Sofia Papagiannaki
    except ProjectMembership.DoesNotExist:
500 73fbaec4 Sofia Papagiannaki
        raise IOError(_(astakos_messages.NOT_MEMBERSHIP_REQUEST))
501 73fbaec4 Sofia Papagiannaki
502 3c638f72 Giorgos Korfiatis
def checkAllowed(entity, request_user):
503 3c638f72 Giorgos Korfiatis
    if isinstance(entity, Project):
504 3c638f72 Giorgos Korfiatis
        application = entity.application
505 3c638f72 Giorgos Korfiatis
    elif isinstance(entity, ProjectApplication):
506 3c638f72 Giorgos Korfiatis
        application = entity
507 3c638f72 Giorgos Korfiatis
    else:
508 3c638f72 Giorgos Korfiatis
        m = "%s not a Project nor a ProjectApplication" % (entity,)
509 3c638f72 Giorgos Korfiatis
        raise ValueError(m)
510 3c638f72 Giorgos Korfiatis
511 907f15db Giorgos Korfiatis
    if request_user and \
512 3c638f72 Giorgos Korfiatis
        (not application.owner == request_user and \
513 907f15db Giorgos Korfiatis
            not request_user.is_superuser):
514 907f15db Giorgos Korfiatis
        raise PermissionDenied(_(astakos_messages.NOT_ALLOWED))
515 907f15db Giorgos Korfiatis
516 907f15db Giorgos Korfiatis
def checkAlive(project):
517 907f15db Giorgos Korfiatis
    if not project.is_alive:
518 907f15db Giorgos Korfiatis
        raise PermissionDenied(
519 907f15db Giorgos Korfiatis
            _(astakos_messages.NOT_ALIVE_PROJECT) % project.__dict__)
520 907f15db Giorgos Korfiatis
521 ff67242a Giorgos Korfiatis
def accept_membership_checks(project, request_user):
522 907f15db Giorgos Korfiatis
    checkAllowed(project, request_user)
523 907f15db Giorgos Korfiatis
    checkAlive(project)
524 b0686c16 Giorgos Korfiatis
525 b0686c16 Giorgos Korfiatis
    join_policy = project.application.member_join_policy
526 b0686c16 Giorgos Korfiatis
    if join_policy == CLOSED_POLICY:
527 b0686c16 Giorgos Korfiatis
        raise PermissionDenied(_(astakos_messages.MEMBER_JOIN_POLICY_CLOSED))
528 b0686c16 Giorgos Korfiatis
529 8dcaa6ac Giorgos Korfiatis
    if project.violates_members_limit(adding=1):
530 73fbaec4 Sofia Papagiannaki
        raise PermissionDenied(_(astakos_messages.MEMBER_NUMBER_LIMIT_REACHED))
531 73fbaec4 Sofia Papagiannaki
532 ff67242a Giorgos Korfiatis
def accept_membership(project_id, user, request_user=None):
533 e47fb17a Sofia Papagiannaki
    project = get_project_for_update(project_id)
534 ff67242a Giorgos Korfiatis
    accept_membership_checks(project, request_user)
535 14f7f6a5 Giorgos Korfiatis
536 8dcaa6ac Giorgos Korfiatis
    membership = get_membership_for_update(project, user)
537 14f7f6a5 Giorgos Korfiatis
    if not membership.can_accept():
538 14f7f6a5 Giorgos Korfiatis
        m = _(astakos_messages.NOT_MEMBERSHIP_REQUEST)
539 14f7f6a5 Giorgos Korfiatis
        raise PermissionDenied(m)
540 d4fc6292 Giorgos Korfiatis
541 73fbaec4 Sofia Papagiannaki
    membership.accept()
542 73fbaec4 Sofia Papagiannaki
543 a3eb3a95 Giorgos Korfiatis
    membership_change_notify(project, membership.person, 'accepted')
544 a3eb3a95 Giorgos Korfiatis
545 73fbaec4 Sofia Papagiannaki
    return membership
546 73fbaec4 Sofia Papagiannaki
547 ff67242a Giorgos Korfiatis
def reject_membership_checks(project, request_user):
548 907f15db Giorgos Korfiatis
    checkAllowed(project, request_user)
549 907f15db Giorgos Korfiatis
    checkAlive(project)
550 e47fb17a Sofia Papagiannaki
551 ff67242a Giorgos Korfiatis
def reject_membership(project_id, user, request_user=None):
552 e47fb17a Sofia Papagiannaki
    project = get_project_for_update(project_id)
553 ff67242a Giorgos Korfiatis
    reject_membership_checks(project, request_user)
554 8dcaa6ac Giorgos Korfiatis
    membership = get_membership_for_update(project, user)
555 14f7f6a5 Giorgos Korfiatis
    if not membership.can_reject():
556 14f7f6a5 Giorgos Korfiatis
        m = _(astakos_messages.NOT_MEMBERSHIP_REQUEST)
557 14f7f6a5 Giorgos Korfiatis
        raise PermissionDenied(m)
558 d4fc6292 Giorgos Korfiatis
559 73fbaec4 Sofia Papagiannaki
    membership.reject()
560 73fbaec4 Sofia Papagiannaki
561 a3eb3a95 Giorgos Korfiatis
    membership_change_notify(project, membership.person, 'rejected')
562 a3eb3a95 Giorgos Korfiatis
563 73fbaec4 Sofia Papagiannaki
    return membership
564 73fbaec4 Sofia Papagiannaki
565 aad0e329 Giorgos Korfiatis
def cancel_membership_checks(project):
566 aad0e329 Giorgos Korfiatis
    checkAlive(project)
567 aad0e329 Giorgos Korfiatis
568 aad0e329 Giorgos Korfiatis
def cancel_membership(project_id, user_id):
569 aad0e329 Giorgos Korfiatis
    project = get_project_for_update(project_id)
570 aad0e329 Giorgos Korfiatis
    cancel_membership_checks(project)
571 aad0e329 Giorgos Korfiatis
    membership = get_membership_for_update(project, user_id)
572 aad0e329 Giorgos Korfiatis
    if not membership.can_cancel():
573 aad0e329 Giorgos Korfiatis
        m = _(astakos_messages.NOT_MEMBERSHIP_REQUEST)
574 aad0e329 Giorgos Korfiatis
        raise PermissionDenied(m)
575 aad0e329 Giorgos Korfiatis
576 aad0e329 Giorgos Korfiatis
    membership.cancel()
577 aad0e329 Giorgos Korfiatis
578 ff67242a Giorgos Korfiatis
def remove_membership_checks(project, request_user=None):
579 907f15db Giorgos Korfiatis
    checkAllowed(project, request_user)
580 907f15db Giorgos Korfiatis
    checkAlive(project)
581 73fbaec4 Sofia Papagiannaki
582 b0686c16 Giorgos Korfiatis
    leave_policy = project.application.member_leave_policy
583 b0686c16 Giorgos Korfiatis
    if leave_policy == CLOSED_POLICY:
584 b0686c16 Giorgos Korfiatis
        raise PermissionDenied(_(astakos_messages.MEMBER_LEAVE_POLICY_CLOSED))
585 b0686c16 Giorgos Korfiatis
586 ff67242a Giorgos Korfiatis
def remove_membership(project_id, user, request_user=None):
587 907f15db Giorgos Korfiatis
    project = get_project_for_update(project_id)
588 ff67242a Giorgos Korfiatis
    remove_membership_checks(project, request_user)
589 8dcaa6ac Giorgos Korfiatis
    membership = get_membership_for_update(project, user)
590 14f7f6a5 Giorgos Korfiatis
    if not membership.can_remove():
591 14f7f6a5 Giorgos Korfiatis
        m = _(astakos_messages.NOT_ACCEPTED_MEMBERSHIP)
592 14f7f6a5 Giorgos Korfiatis
        raise PermissionDenied(m)
593 d4fc6292 Giorgos Korfiatis
594 73fbaec4 Sofia Papagiannaki
    membership.remove()
595 73fbaec4 Sofia Papagiannaki
596 a3eb3a95 Giorgos Korfiatis
    membership_change_notify(project, membership.person, 'removed')
597 a3eb3a95 Giorgos Korfiatis
598 73fbaec4 Sofia Papagiannaki
    return membership
599 73fbaec4 Sofia Papagiannaki
600 ff67242a Giorgos Korfiatis
def enroll_member(project_id, user, request_user=None):
601 907f15db Giorgos Korfiatis
    project = get_project_for_update(project_id)
602 ff67242a Giorgos Korfiatis
    accept_membership_checks(project, request_user)
603 8dcaa6ac Giorgos Korfiatis
    membership = create_membership(project_id, user)
604 14f7f6a5 Giorgos Korfiatis
605 14f7f6a5 Giorgos Korfiatis
    if not membership.can_accept():
606 14f7f6a5 Giorgos Korfiatis
        m = _(astakos_messages.NOT_MEMBERSHIP_REQUEST)
607 14f7f6a5 Giorgos Korfiatis
        raise PermissionDenied(m)
608 d4fc6292 Giorgos Korfiatis
609 907f15db Giorgos Korfiatis
    membership.accept()
610 466cc12c Giorgos Korfiatis
    membership_enroll_notify(project, membership.person)
611 907f15db Giorgos Korfiatis
612 907f15db Giorgos Korfiatis
    return membership
613 8dcaa6ac Giorgos Korfiatis
614 ff67242a Giorgos Korfiatis
def leave_project_checks(project):
615 907f15db Giorgos Korfiatis
    checkAlive(project)
616 8dcaa6ac Giorgos Korfiatis
617 03869281 Sofia Papagiannaki
    leave_policy = project.application.member_leave_policy
618 b0686c16 Giorgos Korfiatis
    if leave_policy == CLOSED_POLICY:
619 73fbaec4 Sofia Papagiannaki
        raise PermissionDenied(_(astakos_messages.MEMBER_LEAVE_POLICY_CLOSED))
620 73fbaec4 Sofia Papagiannaki
621 d4660e00 Giorgos Korfiatis
def can_leave_request(project, user):
622 d4660e00 Giorgos Korfiatis
    leave_policy = project.application.member_leave_policy
623 d4660e00 Giorgos Korfiatis
    if leave_policy == CLOSED_POLICY:
624 d4660e00 Giorgos Korfiatis
        return False
625 d4660e00 Giorgos Korfiatis
    m = user.get_membership(project)
626 d4660e00 Giorgos Korfiatis
    if m is None:
627 d4660e00 Giorgos Korfiatis
        return False
628 d4660e00 Giorgos Korfiatis
    if m.state != ProjectMembership.ACCEPTED:
629 d4660e00 Giorgos Korfiatis
        return False
630 d4660e00 Giorgos Korfiatis
    return True
631 d4660e00 Giorgos Korfiatis
632 ff67242a Giorgos Korfiatis
def leave_project(project_id, user_id):
633 e47fb17a Sofia Papagiannaki
    project = get_project_for_update(project_id)
634 ff67242a Giorgos Korfiatis
    leave_project_checks(project)
635 8dcaa6ac Giorgos Korfiatis
    membership = get_membership_for_update(project, user_id)
636 14f7f6a5 Giorgos Korfiatis
    if not membership.can_leave():
637 14f7f6a5 Giorgos Korfiatis
        m = _(astakos_messages.NOT_ACCEPTED_MEMBERSHIP)
638 14f7f6a5 Giorgos Korfiatis
        raise PermissionDenied(m)
639 4e057833 Sofia Papagiannaki
640 bb6a4465 Giorgos Korfiatis
    auto_accepted = False
641 4e057833 Sofia Papagiannaki
    leave_policy = project.application.member_leave_policy
642 b0686c16 Giorgos Korfiatis
    if leave_policy == AUTO_ACCEPT_POLICY:
643 73fbaec4 Sofia Papagiannaki
        membership.remove()
644 bb6a4465 Giorgos Korfiatis
        auto_accepted = True
645 73fbaec4 Sofia Papagiannaki
    else:
646 c1007621 Giorgos Korfiatis
        membership.leave_request()
647 bb6a4465 Giorgos Korfiatis
        membership_leave_request_notify(project, membership.person)
648 bb6a4465 Giorgos Korfiatis
    return auto_accepted
649 73fbaec4 Sofia Papagiannaki
650 ff67242a Giorgos Korfiatis
def join_project_checks(project):
651 907f15db Giorgos Korfiatis
    checkAlive(project)
652 8dcaa6ac Giorgos Korfiatis
653 974ee6a6 Sofia Papagiannaki
    join_policy = project.application.member_join_policy
654 b0686c16 Giorgos Korfiatis
    if join_policy == CLOSED_POLICY:
655 73fbaec4 Sofia Papagiannaki
        raise PermissionDenied(_(astakos_messages.MEMBER_JOIN_POLICY_CLOSED))
656 73fbaec4 Sofia Papagiannaki
657 d4660e00 Giorgos Korfiatis
def can_join_request(project, user):
658 d4660e00 Giorgos Korfiatis
    join_policy = project.application.member_join_policy
659 d4660e00 Giorgos Korfiatis
    if join_policy == CLOSED_POLICY:
660 d4660e00 Giorgos Korfiatis
        return False
661 d4660e00 Giorgos Korfiatis
    m = user.get_membership(project)
662 d4660e00 Giorgos Korfiatis
    if m:
663 d4660e00 Giorgos Korfiatis
        return False
664 d4660e00 Giorgos Korfiatis
    return True
665 d4660e00 Giorgos Korfiatis
666 ff67242a Giorgos Korfiatis
def join_project(project_id, user_id):
667 e47fb17a Sofia Papagiannaki
    project = get_project_for_update(project_id)
668 ff67242a Giorgos Korfiatis
    join_project_checks(project)
669 14f7f6a5 Giorgos Korfiatis
    membership = create_membership(project, user_id)
670 73fbaec4 Sofia Papagiannaki
671 bb6a4465 Giorgos Korfiatis
    auto_accepted = False
672 4e057833 Sofia Papagiannaki
    join_policy = project.application.member_join_policy
673 b0686c16 Giorgos Korfiatis
    if (join_policy == AUTO_ACCEPT_POLICY and
674 a073c3b2 Giorgos Korfiatis
        not project.violates_members_limit(adding=1)):
675 73fbaec4 Sofia Papagiannaki
        membership.accept()
676 bb6a4465 Giorgos Korfiatis
        auto_accepted = True
677 bb6a4465 Giorgos Korfiatis
    else:
678 bb6a4465 Giorgos Korfiatis
        membership_request_notify(project, membership.person)
679 bb6a4465 Giorgos Korfiatis
680 bb6a4465 Giorgos Korfiatis
    return auto_accepted
681 8dcaa6ac Giorgos Korfiatis
682 ee4aa6eb Giorgos Korfiatis
def submit_application(kw, request_user=None):
683 ee4aa6eb Giorgos Korfiatis
684 ee4aa6eb Giorgos Korfiatis
    kw['applicant'] = request_user
685 3e3743f2 Giorgos Korfiatis
    resource_policies = kw.pop('resource_policies', None)
686 69c822cc Giorgos Korfiatis
687 3e3743f2 Giorgos Korfiatis
    precursor = None
688 15ca2bea Giorgos Korfiatis
    precursor_id = kw.get('precursor_application', None)
689 15ca2bea Giorgos Korfiatis
    if precursor_id is not None:
690 15ca2bea Giorgos Korfiatis
        sfu = ProjectApplication.objects.select_for_update()
691 15ca2bea Giorgos Korfiatis
        precursor = sfu.get(id=precursor_id)
692 15ca2bea Giorgos Korfiatis
        kw['precursor_application'] = precursor
693 73fbaec4 Sofia Papagiannaki
694 3e3743f2 Giorgos Korfiatis
        if (request_user and
695 3e3743f2 Giorgos Korfiatis
            (not precursor.owner == request_user and
696 beda5f0f Georgios D. Tsoukalas
             not request_user.is_superuser
697 beda5f0f Georgios D. Tsoukalas
             and not request_user.is_project_admin())):
698 3e3743f2 Giorgos Korfiatis
            m = _(astakos_messages.NOT_ALLOWED)
699 3e3743f2 Giorgos Korfiatis
            raise PermissionDenied(m)
700 ee4aa6eb Giorgos Korfiatis
701 3e3743f2 Giorgos Korfiatis
    application = ProjectApplication(**kw)
702 1352dabb Kostas Papadimitriou
703 3e3743f2 Giorgos Korfiatis
    if precursor is None:
704 3e3743f2 Giorgos Korfiatis
        application.chain = new_chain()
705 3e3743f2 Giorgos Korfiatis
    else:
706 3e3743f2 Giorgos Korfiatis
        chain = precursor.chain
707 3e3743f2 Giorgos Korfiatis
        application.chain = chain
708 3e3743f2 Giorgos Korfiatis
        sfu = ProjectApplication.objects.select_for_update()
709 3e3743f2 Giorgos Korfiatis
        pending = sfu.filter(chain=chain, state=ProjectApplication.PENDING)
710 3e3743f2 Giorgos Korfiatis
        for app in pending:
711 3e3743f2 Giorgos Korfiatis
            app.state = ProjectApplication.REPLACED
712 3e3743f2 Giorgos Korfiatis
            app.save()
713 3e3743f2 Giorgos Korfiatis
714 3e3743f2 Giorgos Korfiatis
    application.save()
715 3e3743f2 Giorgos Korfiatis
    application.resource_policies = resource_policies
716 a3eb3a95 Giorgos Korfiatis
    application_submit_notify(application)
717 a3eb3a95 Giorgos Korfiatis
    return application
718 73fbaec4 Sofia Papagiannaki
719 3c638f72 Giorgos Korfiatis
def cancel_application(application_id, request_user=None):
720 3c638f72 Giorgos Korfiatis
    application = get_application_for_update(application_id)
721 3c638f72 Giorgos Korfiatis
    checkAllowed(application, request_user)
722 3c638f72 Giorgos Korfiatis
723 01bdbd17 Giorgos Korfiatis
    if not application.can_cancel():
724 01bdbd17 Giorgos Korfiatis
        m = _(astakos_messages.APPLICATION_CANNOT_CANCEL % (
725 01bdbd17 Giorgos Korfiatis
                application.id, application.state_display()))
726 01bdbd17 Giorgos Korfiatis
        raise PermissionDenied(m)
727 3c638f72 Giorgos Korfiatis
728 3c638f72 Giorgos Korfiatis
    application.cancel()
729 3c638f72 Giorgos Korfiatis
730 3c638f72 Giorgos Korfiatis
def dismiss_application(application_id, request_user=None):
731 3c638f72 Giorgos Korfiatis
    application = get_application_for_update(application_id)
732 3c638f72 Giorgos Korfiatis
    checkAllowed(application, request_user)
733 3c638f72 Giorgos Korfiatis
734 01bdbd17 Giorgos Korfiatis
    if not application.can_dismiss():
735 01bdbd17 Giorgos Korfiatis
        m = _(astakos_messages.APPLICATION_CANNOT_DISMISS % (
736 01bdbd17 Giorgos Korfiatis
                application.id, application.state_display()))
737 01bdbd17 Giorgos Korfiatis
        raise PermissionDenied(m)
738 3c638f72 Giorgos Korfiatis
739 3c638f72 Giorgos Korfiatis
    application.dismiss()
740 3c638f72 Giorgos Korfiatis
741 19eb3ee6 Giorgos Korfiatis
def deny_application(application_id):
742 19eb3ee6 Giorgos Korfiatis
    application = get_application_for_update(application_id)
743 01bdbd17 Giorgos Korfiatis
744 01bdbd17 Giorgos Korfiatis
    if not application.can_deny():
745 01bdbd17 Giorgos Korfiatis
        m = _(astakos_messages.APPLICATION_CANNOT_DENY % (
746 01bdbd17 Giorgos Korfiatis
                application.id, application.state_display()))
747 01bdbd17 Giorgos Korfiatis
        raise PermissionDenied(m)
748 19eb3ee6 Giorgos Korfiatis
749 19eb3ee6 Giorgos Korfiatis
    application.deny()
750 19eb3ee6 Giorgos Korfiatis
    application_deny_notify(application)
751 19eb3ee6 Giorgos Korfiatis
752 6cee26a0 Giorgos Korfiatis
def approve_application(app_id):
753 8dcaa6ac Giorgos Korfiatis
754 8dcaa6ac Giorgos Korfiatis
    try:
755 8dcaa6ac Giorgos Korfiatis
        objects = ProjectApplication.objects.select_for_update()
756 8dcaa6ac Giorgos Korfiatis
        application = objects.get(id=app_id)
757 8dcaa6ac Giorgos Korfiatis
    except ProjectApplication.DoesNotExist:
758 6cee26a0 Giorgos Korfiatis
        m = _(astakos_messages.UNKNOWN_PROJECT_APPLICATION_ID % (app_id,))
759 6cee26a0 Giorgos Korfiatis
        raise PermissionDenied(m)
760 8dcaa6ac Giorgos Korfiatis
761 01bdbd17 Giorgos Korfiatis
    if not application.can_approve():
762 01bdbd17 Giorgos Korfiatis
        m = _(astakos_messages.APPLICATION_CANNOT_APPROVE % (
763 01bdbd17 Giorgos Korfiatis
                application.id, application.state_display()))
764 01bdbd17 Giorgos Korfiatis
        raise PermissionDenied(m)
765 01bdbd17 Giorgos Korfiatis
766 73fbaec4 Sofia Papagiannaki
    application.approve()
767 a3eb3a95 Giorgos Korfiatis
    application_approve_notify(application)
768 eb9ff37a Sofia Papagiannaki
769 7eadc230 Giorgos Korfiatis
def check_expiration(execute=False):
770 7eadc230 Giorgos Korfiatis
    objects = Project.objects
771 7eadc230 Giorgos Korfiatis
    expired = objects.expired_projects()
772 7eadc230 Giorgos Korfiatis
    if execute:
773 7eadc230 Giorgos Korfiatis
        for project in expired:
774 7eadc230 Giorgos Korfiatis
            terminate(project.id)
775 7eadc230 Giorgos Korfiatis
776 7eadc230 Giorgos Korfiatis
    return [project.expiration_info() for project in expired]
777 7eadc230 Giorgos Korfiatis
778 eb9ff37a Sofia Papagiannaki
def terminate(project_id):
779 5b9e9530 Giorgos Korfiatis
    project = get_project_for_update(project_id)
780 907f15db Giorgos Korfiatis
    checkAlive(project)
781 5b9e9530 Giorgos Korfiatis
782 5b9e9530 Giorgos Korfiatis
    project.terminate()
783 eb9ff37a Sofia Papagiannaki
784 a3eb3a95 Giorgos Korfiatis
    project_termination_notify(project)
785 eb9ff37a Sofia Papagiannaki
786 eb9ff37a Sofia Papagiannaki
def suspend(project_id):
787 eb9ff37a Sofia Papagiannaki
    project = get_project_by_id(project_id)
788 db99f198 Giorgos Korfiatis
    checkAlive(project)
789 db99f198 Giorgos Korfiatis
790 db99f198 Giorgos Korfiatis
    project.suspend()
791 1352dabb Kostas Papadimitriou
792 a3eb3a95 Giorgos Korfiatis
    project_suspension_notify(project)
793 db99f198 Giorgos Korfiatis
794 db99f198 Giorgos Korfiatis
def resume(project_id):
795 db99f198 Giorgos Korfiatis
    project = get_project_for_update(project_id)
796 db99f198 Giorgos Korfiatis
797 db99f198 Giorgos Korfiatis
    if not project.is_suspended:
798 db99f198 Giorgos Korfiatis
        m = _(astakos_messages.NOT_SUSPENDED_PROJECT) % project.__dict__
799 db99f198 Giorgos Korfiatis
        raise PermissionDenied(m)
800 db99f198 Giorgos Korfiatis
801 db99f198 Giorgos Korfiatis
    project.resume()
802 ff67242a Giorgos Korfiatis
803 ff67242a Giorgos Korfiatis
def get_by_chain_or_404(chain_id):
804 ff67242a Giorgos Korfiatis
    try:
805 ff67242a Giorgos Korfiatis
        project = Project.objects.get(id=chain_id)
806 ff67242a Giorgos Korfiatis
        application = project.application
807 ff67242a Giorgos Korfiatis
        return project, application
808 ff67242a Giorgos Korfiatis
    except:
809 ff67242a Giorgos Korfiatis
        application = ProjectApplication.objects.latest_of_chain(chain_id)
810 ff67242a Giorgos Korfiatis
        if application is None:
811 ff67242a Giorgos Korfiatis
            raise Http404
812 ff67242a Giorgos Korfiatis
        else:
813 ff67242a Giorgos Korfiatis
            return None, application