Statistics
| Branch: | Tag: | Revision:

root / snf-astakos-app / astakos / im / functions.py @ 7deaaa5f

History | View | Annotate | Download (23.7 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 f36af44a Antony Chazapis
from django.core.mail import send_mail
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 27e26a41 Sofia Papagiannaki
50 683cf244 Sofia Papagiannaki
from urllib import quote
51 f36af44a Antony Chazapis
from urlparse import urljoin
52 8f5a3a06 Sofia Papagiannaki
from smtplib import SMTPException
53 751d24cf Sofia Papagiannaki
from datetime import datetime
54 111f3da6 Sofia Papagiannaki
from functools import wraps
55 f36af44a Antony Chazapis
56 bf0c6de5 Sofia Papagiannaki
from astakos.im.settings import (
57 c0b26605 Sofia Papagiannaki
    DEFAULT_CONTACT_EMAIL, SITENAME, BASEURL, LOGGING_LEVEL,
58 c0b26605 Sofia Papagiannaki
    VERIFICATION_EMAIL_SUBJECT, ACCOUNT_CREATION_SUBJECT,
59 c0b26605 Sofia Papagiannaki
    GROUP_CREATION_SUBJECT, HELPDESK_NOTIFICATION_EMAIL_SUBJECT,
60 c0b26605 Sofia Papagiannaki
    INVITATION_EMAIL_SUBJECT, GREETING_EMAIL_SUBJECT, FEEDBACK_EMAIL_SUBJECT,
61 73fbaec4 Sofia Papagiannaki
    EMAIL_CHANGE_EMAIL_SUBJECT,
62 73fbaec4 Sofia Papagiannaki
    PROJECT_CREATION_SUBJECT, PROJECT_APPROVED_SUBJECT,
63 73fbaec4 Sofia Papagiannaki
    PROJECT_TERMINATION_SUBJECT, PROJECT_SUSPENSION_SUBJECT,
64 272cf735 Sofia Papagiannaki
    PROJECT_MEMBERSHIP_CHANGE_SUBJECT,
65 272cf735 Sofia Papagiannaki
    PROJECT_MEMBER_JOIN_POLICIES, PROJECT_MEMBER_LEAVE_POLICIES)
66 73fbaec4 Sofia Papagiannaki
from astakos.im.notifications import build_notification, NotificationError
67 73fbaec4 Sofia Papagiannaki
from astakos.im.models import (
68 974ee6a6 Sofia Papagiannaki
    AstakosUser, ProjectMembership, ProjectApplication, Project,
69 0514bcc7 Giorgos Korfiatis
    trigger_sync, PendingMembershipError, get_resource_names)
70 15ca2bea Giorgos Korfiatis
from astakos.im.models import submit_application as models_submit_application
71 a3eb3a95 Giorgos Korfiatis
from astakos.im.project_notif import (
72 a3eb3a95 Giorgos Korfiatis
    membership_change_notify,
73 a3eb3a95 Giorgos Korfiatis
    application_submit_notify, application_approve_notify,
74 19eb3ee6 Giorgos Korfiatis
    application_deny_notify,
75 a3eb3a95 Giorgos Korfiatis
    project_termination_notify, project_suspension_notify)
76 0514bcc7 Giorgos Korfiatis
from astakos.im.endpoints.qh import qh_register_user, qh_get_quota
77 73fbaec4 Sofia Papagiannaki
78 ae497612 Olga Brani
import astakos.im.messages as astakos_messages
79 f36af44a Antony Chazapis
80 f36af44a Antony Chazapis
logger = logging.getLogger(__name__)
81 f36af44a Antony Chazapis
82 5ce3ce4f Sofia Papagiannaki
83 111f3da6 Sofia Papagiannaki
def logged(func, msg):
84 111f3da6 Sofia Papagiannaki
    @wraps(func)
85 111f3da6 Sofia Papagiannaki
    def with_logging(*args, **kwargs):
86 111f3da6 Sofia Papagiannaki
        email = ''
87 111f3da6 Sofia Papagiannaki
        user = None
88 9a06d96f Olga Brani
        try:
89 111f3da6 Sofia Papagiannaki
            request = args[0]
90 9a06d96f Olga Brani
            email = request.user.email
91 9a06d96f Olga Brani
        except (KeyError, AttributeError), e:
92 9a06d96f Olga Brani
            email = ''
93 111f3da6 Sofia Papagiannaki
        r = func(*args, **kwargs)
94 c9e378c7 Sofia Papagiannaki
        if LOGGING_LEVEL:
95 aab4d540 Sofia Papagiannaki
            logger.log(LOGGING_LEVEL, msg % email)
96 111f3da6 Sofia Papagiannaki
        return r
97 111f3da6 Sofia Papagiannaki
    return with_logging
98 111f3da6 Sofia Papagiannaki
99 bf0c6de5 Sofia Papagiannaki
100 bf0c6de5 Sofia Papagiannaki
def login(request, user):
101 bf0c6de5 Sofia Papagiannaki
    auth_login(request, user)
102 c3c2212a Sofia Papagiannaki
    from astakos.im.models import SessionCatalog
103 c3c2212a Sofia Papagiannaki
    SessionCatalog(
104 c0b26605 Sofia Papagiannaki
        session_key=request.session.session_key,
105 c3c2212a Sofia Papagiannaki
        user=user
106 c3c2212a Sofia Papagiannaki
    ).save()
107 bf0c6de5 Sofia Papagiannaki
108 bf0c6de5 Sofia Papagiannaki
login = logged(login, '%s logged in.')
109 111f3da6 Sofia Papagiannaki
logout = logged(auth_logout, '%s logged out.')
110 111f3da6 Sofia Papagiannaki
111 5ce3ce4f Sofia Papagiannaki
112 683cf244 Sofia Papagiannaki
def send_verification(user, template_name='im/activation_email.txt'):
113 f36af44a Antony Chazapis
    """
114 683cf244 Sofia Papagiannaki
    Send email to user to verify his/her email and activate his/her account.
115 5ce3ce4f Sofia Papagiannaki

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

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

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

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

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

295 27e26a41 Sofia Papagiannaki
    Raises SendGreetingError, ValidationError
296 683cf244 Sofia Papagiannaki
    """
297 683cf244 Sofia Papagiannaki
    user.is_active = True
298 4bdd7e3d Kostas Papadimitriou
    user.email_verified = True
299 f1ab6639 Kostas Papadimitriou
    if not user.activation_sent:
300 f1ab6639 Kostas Papadimitriou
        user.activation_sent = datetime.now()
301 683cf244 Sofia Papagiannaki
    user.save()
302 21e0fdad Giorgos Korfiatis
    qh_register_user(user)
303 23b9b72f Sofia Papagiannaki
    send_helpdesk_notification(user, helpdesk_email_template_name)
304 683cf244 Sofia Papagiannaki
    send_greeting(user, email_template_name)
305 683cf244 Sofia Papagiannaki
306 21e0fdad Giorgos Korfiatis
def deactivate(user):
307 21e0fdad Giorgos Korfiatis
    user.is_active = False
308 21e0fdad Giorgos Korfiatis
    user.save()
309 21e0fdad Giorgos Korfiatis
310 73fbaec4 Sofia Papagiannaki
def invite(inviter, email, realname):
311 73fbaec4 Sofia Papagiannaki
    inv = Invitation(inviter=inviter, username=email, realname=realname)
312 73fbaec4 Sofia Papagiannaki
    inv.save()
313 73fbaec4 Sofia Papagiannaki
    send_invitation(inv)
314 73fbaec4 Sofia Papagiannaki
    inviter.invitations = max(0, self.invitations - 1)
315 73fbaec4 Sofia Papagiannaki
    inviter.save()
316 5ce3ce4f Sofia Papagiannaki
317 9a06d96f Olga Brani
def switch_account_to_shibboleth(user, local_user,
318 9a06d96f Olga Brani
                                 greeting_template_name='im/welcome_email.txt'):
319 9a06d96f Olga Brani
    try:
320 9a06d96f Olga Brani
        provider = user.provider
321 9a06d96f Olga Brani
    except AttributeError:
322 23b9b72f Sofia Papagiannaki
        return
323 9a06d96f Olga Brani
    else:
324 9a06d96f Olga Brani
        if not provider == 'shibboleth':
325 9a06d96f Olga Brani
            return
326 9a06d96f Olga Brani
        user.delete()
327 9a06d96f Olga Brani
        local_user.provider = 'shibboleth'
328 9a06d96f Olga Brani
        local_user.third_party_identifier = user.third_party_identifier
329 9a06d96f Olga Brani
        local_user.save()
330 9a06d96f Olga Brani
        send_greeting(local_user, greeting_template_name)
331 9a06d96f Olga Brani
        return local_user
332 59f598f1 Sofia Papagiannaki
333 5ce3ce4f Sofia Papagiannaki
334 8f5a3a06 Sofia Papagiannaki
class SendMailError(Exception):
335 18ffbee1 Sofia Papagiannaki
    pass
336 8f5a3a06 Sofia Papagiannaki
337 5ce3ce4f Sofia Papagiannaki
338 8f5a3a06 Sofia Papagiannaki
class SendAdminNotificationError(SendMailError):
339 8f5a3a06 Sofia Papagiannaki
    def __init__(self):
340 ae497612 Olga Brani
        self.message = _(astakos_messages.ADMIN_NOTIFICATION_SEND_ERR)
341 18ffbee1 Sofia Papagiannaki
        super(SendAdminNotificationError, self).__init__()
342 8f5a3a06 Sofia Papagiannaki
343 5ce3ce4f Sofia Papagiannaki
344 18ffbee1 Sofia Papagiannaki
class SendVerificationError(SendMailError):
345 8f5a3a06 Sofia Papagiannaki
    def __init__(self):
346 ae497612 Olga Brani
        self.message = _(astakos_messages.VERIFICATION_SEND_ERR)
347 18ffbee1 Sofia Papagiannaki
        super(SendVerificationError, self).__init__()
348 8f5a3a06 Sofia Papagiannaki
349 5ce3ce4f Sofia Papagiannaki
350 18ffbee1 Sofia Papagiannaki
class SendInvitationError(SendMailError):
351 8f5a3a06 Sofia Papagiannaki
    def __init__(self):
352 ae497612 Olga Brani
        self.message = _(astakos_messages.INVITATION_SEND_ERR)
353 18ffbee1 Sofia Papagiannaki
        super(SendInvitationError, self).__init__()
354 8f5a3a06 Sofia Papagiannaki
355 5ce3ce4f Sofia Papagiannaki
356 18ffbee1 Sofia Papagiannaki
class SendGreetingError(SendMailError):
357 8f5a3a06 Sofia Papagiannaki
    def __init__(self):
358 ae497612 Olga Brani
        self.message = _(astakos_messages.GREETING_SEND_ERR)
359 18ffbee1 Sofia Papagiannaki
        super(SendGreetingError, self).__init__()
360 8f5a3a06 Sofia Papagiannaki
361 5ce3ce4f Sofia Papagiannaki
362 18ffbee1 Sofia Papagiannaki
class SendFeedbackError(SendMailError):
363 8f5a3a06 Sofia Papagiannaki
    def __init__(self):
364 ae497612 Olga Brani
        self.message = _(astakos_messages.FEEDBACK_SEND_ERR)
365 49790d9d Sofia Papagiannaki
        super(SendFeedbackError, self).__init__()
366 49790d9d Sofia Papagiannaki
367 5ce3ce4f Sofia Papagiannaki
368 49790d9d Sofia Papagiannaki
class ChangeEmailError(SendMailError):
369 49790d9d Sofia Papagiannaki
    def __init__(self):
370 ccab6eb5 Sofia Papagiannaki
        self.message = _(astakos_messages.CHANGE_EMAIL_SEND_ERR)
371 35f8ccf1 Sofia Papagiannaki
        super(ChangeEmailError, self).__init__()
372 a0be6a0c Sofia Papagiannaki
373 5ce3ce4f Sofia Papagiannaki
374 a0be6a0c Sofia Papagiannaki
class SendNotificationError(SendMailError):
375 a0be6a0c Sofia Papagiannaki
    def __init__(self):
376 ae497612 Olga Brani
        self.message = _(astakos_messages.NOTIFICATION_SEND_ERR)
377 a0be6a0c Sofia Papagiannaki
        super(SendNotificationError, self).__init__()
378 73fbaec4 Sofia Papagiannaki
379 73fbaec4 Sofia Papagiannaki
380 0514bcc7 Giorgos Korfiatis
def get_quota(user):
381 0514bcc7 Giorgos Korfiatis
    resources = get_resource_names()
382 0514bcc7 Giorgos Korfiatis
    return qh_get_quota(user, resources)
383 0514bcc7 Giorgos Korfiatis
384 0514bcc7 Giorgos Korfiatis
385 73fbaec4 Sofia Papagiannaki
### PROJECT VIEWS ###
386 fcc1e93f Sofia Papagiannaki
387 b0686c16 Giorgos Korfiatis
AUTO_ACCEPT_POLICY = 1
388 b0686c16 Giorgos Korfiatis
MODERATED_POLICY   = 2
389 b0686c16 Giorgos Korfiatis
CLOSED_POLICY      = 3
390 b0686c16 Giorgos Korfiatis
391 b0686c16 Giorgos Korfiatis
POLICIES = [ AUTO_ACCEPT_POLICY, MODERATED_POLICY, CLOSED_POLICY ]
392 73fbaec4 Sofia Papagiannaki
393 73fbaec4 Sofia Papagiannaki
def get_project_by_application_id(project_application_id):
394 73fbaec4 Sofia Papagiannaki
    try:
395 73fbaec4 Sofia Papagiannaki
        return Project.objects.get(application__id=project_application_id)
396 73fbaec4 Sofia Papagiannaki
    except Project.DoesNotExist:
397 73fbaec4 Sofia Papagiannaki
        raise IOError(
398 73fbaec4 Sofia Papagiannaki
            _(astakos_messages.UNKNOWN_PROJECT_APPLICATION_ID) % project_application_id)
399 73fbaec4 Sofia Papagiannaki
400 8dcaa6ac Giorgos Korfiatis
def get_project_id_of_application_id(project_application_id):
401 8dcaa6ac Giorgos Korfiatis
    try:
402 8dcaa6ac Giorgos Korfiatis
        return Project.objects.get(application__id=project_application_id).id
403 8dcaa6ac Giorgos Korfiatis
    except Project.DoesNotExist:
404 8dcaa6ac Giorgos Korfiatis
        raise IOError(
405 8dcaa6ac Giorgos Korfiatis
            _(astakos_messages.UNKNOWN_PROJECT_APPLICATION_ID) % project_application_id)
406 8dcaa6ac Giorgos Korfiatis
407 eb9ff37a Sofia Papagiannaki
def get_project_by_id(project_id):
408 eb9ff37a Sofia Papagiannaki
    try:
409 eb9ff37a Sofia Papagiannaki
        return Project.objects.get(id=project_id)
410 eb9ff37a Sofia Papagiannaki
    except Project.DoesNotExist:
411 eb9ff37a Sofia Papagiannaki
        raise IOError(
412 eb9ff37a Sofia Papagiannaki
            _(astakos_messages.UNKNOWN_PROJECT_ID) % project_id)
413 eb9ff37a Sofia Papagiannaki
414 8dcaa6ac Giorgos Korfiatis
def get_project_for_update(project_id):
415 8dcaa6ac Giorgos Korfiatis
    try:
416 8dcaa6ac Giorgos Korfiatis
        return Project.objects.select_for_update().get(id=project_id)
417 8dcaa6ac Giorgos Korfiatis
    except Project.DoesNotExist:
418 8dcaa6ac Giorgos Korfiatis
        raise IOError(
419 8dcaa6ac Giorgos Korfiatis
            _(astakos_messages.UNKNOWN_PROJECT_ID) % project_id)
420 8dcaa6ac Giorgos Korfiatis
421 19eb3ee6 Giorgos Korfiatis
def get_application_for_update(application_id):
422 19eb3ee6 Giorgos Korfiatis
    try:
423 19eb3ee6 Giorgos Korfiatis
        objects = ProjectApplication.objects.select_for_update()
424 19eb3ee6 Giorgos Korfiatis
        return objects.get(id=application_id)
425 19eb3ee6 Giorgos Korfiatis
    except ProjectApplication.DoesNotExist:
426 19eb3ee6 Giorgos Korfiatis
        m = _(astakos_messages.UNKNOWN_PROJECT_APPLICATION_ID) % application_id
427 19eb3ee6 Giorgos Korfiatis
        raise IOError(m)
428 19eb3ee6 Giorgos Korfiatis
429 73fbaec4 Sofia Papagiannaki
def get_user_by_id(user_id):
430 73fbaec4 Sofia Papagiannaki
    try:
431 974ee6a6 Sofia Papagiannaki
        return AstakosUser.objects.get(id=user_id)
432 73fbaec4 Sofia Papagiannaki
    except AstakosUser.DoesNotExist:
433 73fbaec4 Sofia Papagiannaki
        raise IOError(_(astakos_messages.UNKNOWN_USER_ID) % user_id)
434 73fbaec4 Sofia Papagiannaki
435 7dd3047d Sofia Papagiannaki
def create_membership(project, user):
436 7dd3047d Sofia Papagiannaki
    if isinstance(project, int):
437 8dcaa6ac Giorgos Korfiatis
        project = get_project_by_id(project)
438 7dd3047d Sofia Papagiannaki
    if isinstance(user, int):
439 7dd3047d Sofia Papagiannaki
        user = get_user_by_id(user)
440 7dd3047d Sofia Papagiannaki
    m = ProjectMembership(
441 7dd3047d Sofia Papagiannaki
        project=project,
442 7dd3047d Sofia Papagiannaki
        person=user,
443 7dd3047d Sofia Papagiannaki
        request_date=datetime.now())
444 73fbaec4 Sofia Papagiannaki
    try:
445 7dd3047d Sofia Papagiannaki
        m.save()
446 73fbaec4 Sofia Papagiannaki
    except IntegrityError, e:
447 73fbaec4 Sofia Papagiannaki
        raise IOError(_(astakos_messages.MEMBERSHIP_REQUEST_EXISTS))
448 73fbaec4 Sofia Papagiannaki
    else:
449 fc61dfb7 Sofia Papagiannaki
        return m
450 73fbaec4 Sofia Papagiannaki
451 8dcaa6ac Giorgos Korfiatis
def get_membership_for_update(project, user):
452 974ee6a6 Sofia Papagiannaki
    if isinstance(project, int):
453 8dcaa6ac Giorgos Korfiatis
        project = get_project_by_id(project)
454 974ee6a6 Sofia Papagiannaki
    if isinstance(user, int):
455 73fbaec4 Sofia Papagiannaki
        user = get_user_by_id(user)
456 73fbaec4 Sofia Papagiannaki
    try:
457 b6fe8bb8 Giorgos Korfiatis
        sfu = ProjectMembership.objects.select_for_update()
458 b6fe8bb8 Giorgos Korfiatis
        m = sfu.get(project=project, person=user)
459 b6fe8bb8 Giorgos Korfiatis
        if m.is_pending:
460 b6fe8bb8 Giorgos Korfiatis
            raise PendingMembershipError()
461 b6fe8bb8 Giorgos Korfiatis
        return m
462 73fbaec4 Sofia Papagiannaki
    except ProjectMembership.DoesNotExist:
463 73fbaec4 Sofia Papagiannaki
        raise IOError(_(astakos_messages.NOT_MEMBERSHIP_REQUEST))
464 73fbaec4 Sofia Papagiannaki
465 3c638f72 Giorgos Korfiatis
def checkAllowed(entity, request_user):
466 3c638f72 Giorgos Korfiatis
    if isinstance(entity, Project):
467 3c638f72 Giorgos Korfiatis
        application = entity.application
468 3c638f72 Giorgos Korfiatis
    elif isinstance(entity, ProjectApplication):
469 3c638f72 Giorgos Korfiatis
        application = entity
470 3c638f72 Giorgos Korfiatis
    else:
471 3c638f72 Giorgos Korfiatis
        m = "%s not a Project nor a ProjectApplication" % (entity,)
472 3c638f72 Giorgos Korfiatis
        raise ValueError(m)
473 3c638f72 Giorgos Korfiatis
474 907f15db Giorgos Korfiatis
    if request_user and \
475 3c638f72 Giorgos Korfiatis
        (not application.owner == request_user and \
476 907f15db Giorgos Korfiatis
            not request_user.is_superuser):
477 907f15db Giorgos Korfiatis
        raise PermissionDenied(_(astakos_messages.NOT_ALLOWED))
478 907f15db Giorgos Korfiatis
479 907f15db Giorgos Korfiatis
def checkAlive(project):
480 907f15db Giorgos Korfiatis
    if not project.is_alive:
481 907f15db Giorgos Korfiatis
        raise PermissionDenied(
482 907f15db Giorgos Korfiatis
            _(astakos_messages.NOT_ALIVE_PROJECT) % project.__dict__)
483 907f15db Giorgos Korfiatis
484 8dcaa6ac Giorgos Korfiatis
def accept_membership(project_application_id, user, request_user=None):
485 73fbaec4 Sofia Papagiannaki
    """
486 73fbaec4 Sofia Papagiannaki
        Raises:
487 73fbaec4 Sofia Papagiannaki
            django.core.exceptions.PermissionDenied
488 73fbaec4 Sofia Papagiannaki
            IOError
489 73fbaec4 Sofia Papagiannaki
    """
490 8dcaa6ac Giorgos Korfiatis
    project_id = get_project_id_of_application_id(project_application_id)
491 8dcaa6ac Giorgos Korfiatis
    return do_accept_membership(project_id, user, request_user)
492 8dcaa6ac Giorgos Korfiatis
493 e47fb17a Sofia Papagiannaki
def do_accept_membership_checks(project, request_user):
494 907f15db Giorgos Korfiatis
    checkAllowed(project, request_user)
495 907f15db Giorgos Korfiatis
    checkAlive(project)
496 b0686c16 Giorgos Korfiatis
497 b0686c16 Giorgos Korfiatis
    join_policy = project.application.member_join_policy
498 b0686c16 Giorgos Korfiatis
    if join_policy == CLOSED_POLICY:
499 b0686c16 Giorgos Korfiatis
        raise PermissionDenied(_(astakos_messages.MEMBER_JOIN_POLICY_CLOSED))
500 b0686c16 Giorgos Korfiatis
501 8dcaa6ac Giorgos Korfiatis
    if project.violates_members_limit(adding=1):
502 73fbaec4 Sofia Papagiannaki
        raise PermissionDenied(_(astakos_messages.MEMBER_NUMBER_LIMIT_REACHED))
503 73fbaec4 Sofia Papagiannaki
504 907f15db Giorgos Korfiatis
def do_accept_membership(project_id, user, request_user=None):
505 e47fb17a Sofia Papagiannaki
    project = get_project_for_update(project_id)
506 907f15db Giorgos Korfiatis
    do_accept_membership_checks(project, request_user)
507 e47fb17a Sofia Papagiannaki
508 8dcaa6ac Giorgos Korfiatis
    membership = get_membership_for_update(project, user)
509 73fbaec4 Sofia Papagiannaki
    membership.accept()
510 3e47bb0b Sofia Papagiannaki
    trigger_sync()
511 73fbaec4 Sofia Papagiannaki
512 a3eb3a95 Giorgos Korfiatis
    membership_change_notify(project, membership.person, 'accepted')
513 a3eb3a95 Giorgos Korfiatis
514 73fbaec4 Sofia Papagiannaki
    return membership
515 73fbaec4 Sofia Papagiannaki
516 8dcaa6ac Giorgos Korfiatis
def reject_membership(project_application_id, user, request_user=None):
517 73fbaec4 Sofia Papagiannaki
    """
518 73fbaec4 Sofia Papagiannaki
        Raises:
519 73fbaec4 Sofia Papagiannaki
            django.core.exceptions.PermissionDenied
520 73fbaec4 Sofia Papagiannaki
            IOError
521 73fbaec4 Sofia Papagiannaki
    """
522 8dcaa6ac Giorgos Korfiatis
    project_id = get_project_id_of_application_id(project_application_id)
523 8dcaa6ac Giorgos Korfiatis
    return do_reject_membership(project_id, user, request_user)
524 8dcaa6ac Giorgos Korfiatis
525 e47fb17a Sofia Papagiannaki
def do_reject_membership_checks(project, request_user):
526 907f15db Giorgos Korfiatis
    checkAllowed(project, request_user)
527 907f15db Giorgos Korfiatis
    checkAlive(project)
528 e47fb17a Sofia Papagiannaki
529 907f15db Giorgos Korfiatis
def do_reject_membership(project_id, user, request_user=None):
530 e47fb17a Sofia Papagiannaki
    project = get_project_for_update(project_id)
531 907f15db Giorgos Korfiatis
    do_reject_membership_checks(project, request_user)
532 1352dabb Kostas Papadimitriou
533 8dcaa6ac Giorgos Korfiatis
    membership = get_membership_for_update(project, user)
534 73fbaec4 Sofia Papagiannaki
    membership.reject()
535 73fbaec4 Sofia Papagiannaki
536 a3eb3a95 Giorgos Korfiatis
    membership_change_notify(project, membership.person, 'rejected')
537 a3eb3a95 Giorgos Korfiatis
538 73fbaec4 Sofia Papagiannaki
    return membership
539 73fbaec4 Sofia Papagiannaki
540 8dcaa6ac Giorgos Korfiatis
def remove_membership(project_application_id, user, request_user=None):
541 73fbaec4 Sofia Papagiannaki
    """
542 73fbaec4 Sofia Papagiannaki
        Raises:
543 73fbaec4 Sofia Papagiannaki
            django.core.exceptions.PermissionDenied
544 73fbaec4 Sofia Papagiannaki
            IOError
545 73fbaec4 Sofia Papagiannaki
    """
546 8dcaa6ac Giorgos Korfiatis
    project_id = get_project_id_of_application_id(project_application_id)
547 8dcaa6ac Giorgos Korfiatis
    return do_remove_membership(project_id, user, request_user)
548 8dcaa6ac Giorgos Korfiatis
549 8c3e6cb5 Kostas Papadimitriou
def do_remove_membership_checks(project, membership, request_user=None):
550 907f15db Giorgos Korfiatis
    checkAllowed(project, request_user)
551 907f15db Giorgos Korfiatis
    checkAlive(project)
552 73fbaec4 Sofia Papagiannaki
553 b0686c16 Giorgos Korfiatis
    leave_policy = project.application.member_leave_policy
554 b0686c16 Giorgos Korfiatis
    if leave_policy == CLOSED_POLICY:
555 b0686c16 Giorgos Korfiatis
        raise PermissionDenied(_(astakos_messages.MEMBER_LEAVE_POLICY_CLOSED))
556 b0686c16 Giorgos Korfiatis
557 907f15db Giorgos Korfiatis
def do_remove_membership(project_id, user, request_user=None):
558 907f15db Giorgos Korfiatis
    project = get_project_for_update(project_id)
559 907f15db Giorgos Korfiatis
    do_remove_membership_checks(project, request_user)
560 907f15db Giorgos Korfiatis
561 8dcaa6ac Giorgos Korfiatis
    membership = get_membership_for_update(project, user)
562 73fbaec4 Sofia Papagiannaki
    membership.remove()
563 3e47bb0b Sofia Papagiannaki
    trigger_sync()
564 73fbaec4 Sofia Papagiannaki
565 a3eb3a95 Giorgos Korfiatis
    membership_change_notify(project, membership.person, 'removed')
566 a3eb3a95 Giorgos Korfiatis
567 73fbaec4 Sofia Papagiannaki
    return membership
568 73fbaec4 Sofia Papagiannaki
569 8dcaa6ac Giorgos Korfiatis
def enroll_member(project_application_id, user, request_user=None):
570 8dcaa6ac Giorgos Korfiatis
    project_id = get_project_id_of_application_id(project_application_id)
571 8dcaa6ac Giorgos Korfiatis
    return do_enroll_member(project_id, user, request_user)
572 8dcaa6ac Giorgos Korfiatis
573 8dcaa6ac Giorgos Korfiatis
def do_enroll_member(project_id, user, request_user=None):
574 907f15db Giorgos Korfiatis
    project = get_project_for_update(project_id)
575 907f15db Giorgos Korfiatis
    do_accept_membership_checks(project, request_user)
576 907f15db Giorgos Korfiatis
577 8dcaa6ac Giorgos Korfiatis
    membership = create_membership(project_id, user)
578 907f15db Giorgos Korfiatis
    membership.accept()
579 907f15db Giorgos Korfiatis
    trigger_sync()
580 907f15db Giorgos Korfiatis
581 907f15db Giorgos Korfiatis
    # TODO send proper notification
582 907f15db Giorgos Korfiatis
    return membership
583 8dcaa6ac Giorgos Korfiatis
584 73fbaec4 Sofia Papagiannaki
def leave_project(project_application_id, user_id):
585 73fbaec4 Sofia Papagiannaki
    """
586 73fbaec4 Sofia Papagiannaki
        Raises:
587 73fbaec4 Sofia Papagiannaki
            django.core.exceptions.PermissionDenied
588 73fbaec4 Sofia Papagiannaki
            IOError
589 73fbaec4 Sofia Papagiannaki
    """
590 8dcaa6ac Giorgos Korfiatis
    project_id = get_project_id_of_application_id(project_application_id)
591 8dcaa6ac Giorgos Korfiatis
    return do_leave_project(project_id, user_id)
592 8dcaa6ac Giorgos Korfiatis
593 e47fb17a Sofia Papagiannaki
def do_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 907f15db Giorgos Korfiatis
def do_leave_project(project_id, user_id):
601 e47fb17a Sofia Papagiannaki
    project = get_project_for_update(project_id)
602 907f15db Giorgos Korfiatis
    do_leave_project_checks(project)
603 e47fb17a Sofia Papagiannaki
604 8dcaa6ac Giorgos Korfiatis
    membership = get_membership_for_update(project, user_id)
605 4e057833 Sofia Papagiannaki
606 4e057833 Sofia Papagiannaki
    leave_policy = project.application.member_leave_policy
607 b0686c16 Giorgos Korfiatis
    if leave_policy == AUTO_ACCEPT_POLICY:
608 73fbaec4 Sofia Papagiannaki
        membership.remove()
609 3e47bb0b Sofia Papagiannaki
        trigger_sync()
610 73fbaec4 Sofia Papagiannaki
    else:
611 73fbaec4 Sofia Papagiannaki
        membership.leave_request_date = datetime.now()
612 73fbaec4 Sofia Papagiannaki
        membership.save()
613 73fbaec4 Sofia Papagiannaki
    return membership
614 73fbaec4 Sofia Papagiannaki
615 73fbaec4 Sofia Papagiannaki
def join_project(project_application_id, user_id):
616 73fbaec4 Sofia Papagiannaki
    """
617 73fbaec4 Sofia Papagiannaki
        Raises:
618 73fbaec4 Sofia Papagiannaki
            django.core.exceptions.PermissionDenied
619 73fbaec4 Sofia Papagiannaki
            IOError
620 73fbaec4 Sofia Papagiannaki
    """
621 8dcaa6ac Giorgos Korfiatis
    project_id = get_project_id_of_application_id(project_application_id)
622 8dcaa6ac Giorgos Korfiatis
    return do_join_project(project_id, user_id)
623 8dcaa6ac Giorgos Korfiatis
624 e47fb17a Sofia Papagiannaki
def do_join_project_checks(project):
625 907f15db Giorgos Korfiatis
    checkAlive(project)
626 8dcaa6ac Giorgos Korfiatis
627 974ee6a6 Sofia Papagiannaki
    join_policy = project.application.member_join_policy
628 b0686c16 Giorgos Korfiatis
    if join_policy == CLOSED_POLICY:
629 73fbaec4 Sofia Papagiannaki
        raise PermissionDenied(_(astakos_messages.MEMBER_JOIN_POLICY_CLOSED))
630 73fbaec4 Sofia Papagiannaki
631 907f15db Giorgos Korfiatis
def do_join_project(project_id, user_id):
632 e47fb17a Sofia Papagiannaki
    project = get_project_for_update(project_id)
633 907f15db Giorgos Korfiatis
    do_join_project_checks(project)
634 e47fb17a Sofia Papagiannaki
635 8dcaa6ac Giorgos Korfiatis
    membership = create_membership(project, user_id)
636 73fbaec4 Sofia Papagiannaki
637 4e057833 Sofia Papagiannaki
    join_policy = project.application.member_join_policy
638 b0686c16 Giorgos Korfiatis
    if (join_policy == AUTO_ACCEPT_POLICY and
639 a073c3b2 Giorgos Korfiatis
        not project.violates_members_limit(adding=1)):
640 73fbaec4 Sofia Papagiannaki
        membership.accept()
641 3e47bb0b Sofia Papagiannaki
        trigger_sync()
642 73fbaec4 Sofia Papagiannaki
    return membership
643 8dcaa6ac Giorgos Korfiatis
644 ee4aa6eb Giorgos Korfiatis
def submit_application(kw, request_user=None):
645 ee4aa6eb Giorgos Korfiatis
646 ee4aa6eb Giorgos Korfiatis
    kw['applicant'] = request_user
647 69c822cc Giorgos Korfiatis
648 15ca2bea Giorgos Korfiatis
    precursor_id = kw.get('precursor_application', None)
649 15ca2bea Giorgos Korfiatis
    if precursor_id is not None:
650 15ca2bea Giorgos Korfiatis
        sfu = ProjectApplication.objects.select_for_update()
651 15ca2bea Giorgos Korfiatis
        precursor = sfu.get(id=precursor_id)
652 15ca2bea Giorgos Korfiatis
        kw['precursor_application'] = precursor
653 73fbaec4 Sofia Papagiannaki
654 ee4aa6eb Giorgos Korfiatis
        if request_user and \
655 ee4aa6eb Giorgos Korfiatis
            (not precursor.owner == request_user and \
656 ee4aa6eb Giorgos Korfiatis
                not request_user.is_superuser):
657 ee4aa6eb Giorgos Korfiatis
            raise PermissionDenied(_(astakos_messages.NOT_ALLOWED))
658 ee4aa6eb Giorgos Korfiatis
659 15ca2bea Giorgos Korfiatis
    application = models_submit_application(**kw)
660 1352dabb Kostas Papadimitriou
661 a3eb3a95 Giorgos Korfiatis
    application_submit_notify(application)
662 a3eb3a95 Giorgos Korfiatis
    return application
663 73fbaec4 Sofia Papagiannaki
664 3c638f72 Giorgos Korfiatis
def cancel_application(application_id, request_user=None):
665 3c638f72 Giorgos Korfiatis
    application = get_application_for_update(application_id)
666 3c638f72 Giorgos Korfiatis
    checkAllowed(application, request_user)
667 3c638f72 Giorgos Korfiatis
668 3c638f72 Giorgos Korfiatis
    if application.state != ProjectApplication.PENDING:
669 3c638f72 Giorgos Korfiatis
        raise PermissionDenied()
670 3c638f72 Giorgos Korfiatis
671 3c638f72 Giorgos Korfiatis
    application.cancel()
672 3c638f72 Giorgos Korfiatis
673 3c638f72 Giorgos Korfiatis
def dismiss_application(application_id, request_user=None):
674 3c638f72 Giorgos Korfiatis
    application = get_application_for_update(application_id)
675 3c638f72 Giorgos Korfiatis
    checkAllowed(application, request_user)
676 3c638f72 Giorgos Korfiatis
677 3c638f72 Giorgos Korfiatis
    if application.state != ProjectApplication.DENIED:
678 3c638f72 Giorgos Korfiatis
        raise PermissionDenied()
679 3c638f72 Giorgos Korfiatis
680 3c638f72 Giorgos Korfiatis
    application.dismiss()
681 3c638f72 Giorgos Korfiatis
682 19eb3ee6 Giorgos Korfiatis
def deny_application(application_id):
683 19eb3ee6 Giorgos Korfiatis
    application = get_application_for_update(application_id)
684 19eb3ee6 Giorgos Korfiatis
    if application.state != ProjectApplication.PENDING:
685 19eb3ee6 Giorgos Korfiatis
        raise PermissionDenied()
686 19eb3ee6 Giorgos Korfiatis
687 19eb3ee6 Giorgos Korfiatis
    application.deny()
688 19eb3ee6 Giorgos Korfiatis
    application_deny_notify(application)
689 19eb3ee6 Giorgos Korfiatis
690 8dcaa6ac Giorgos Korfiatis
def approve_application(app):
691 8dcaa6ac Giorgos Korfiatis
692 8dcaa6ac Giorgos Korfiatis
    app_id = app if isinstance(app, int) else app.id
693 8dcaa6ac Giorgos Korfiatis
694 8dcaa6ac Giorgos Korfiatis
    try:
695 8dcaa6ac Giorgos Korfiatis
        objects = ProjectApplication.objects.select_for_update()
696 8dcaa6ac Giorgos Korfiatis
        application = objects.get(id=app_id)
697 8dcaa6ac Giorgos Korfiatis
    except ProjectApplication.DoesNotExist:
698 8dcaa6ac Giorgos Korfiatis
        raise PermissionDenied()
699 8dcaa6ac Giorgos Korfiatis
700 73fbaec4 Sofia Papagiannaki
    application.approve()
701 3e47bb0b Sofia Papagiannaki
    trigger_sync()
702 8dcaa6ac Giorgos Korfiatis
703 a3eb3a95 Giorgos Korfiatis
    application_approve_notify(application)
704 eb9ff37a Sofia Papagiannaki
705 eb9ff37a Sofia Papagiannaki
def terminate(project_id):
706 5b9e9530 Giorgos Korfiatis
    project = get_project_for_update(project_id)
707 907f15db Giorgos Korfiatis
    checkAlive(project)
708 5b9e9530 Giorgos Korfiatis
709 5b9e9530 Giorgos Korfiatis
    project.terminate()
710 eb9ff37a Sofia Papagiannaki
    trigger_sync()
711 eb9ff37a Sofia Papagiannaki
712 a3eb3a95 Giorgos Korfiatis
    project_termination_notify(project)
713 eb9ff37a Sofia Papagiannaki
714 eb9ff37a Sofia Papagiannaki
def suspend(project_id):
715 eb9ff37a Sofia Papagiannaki
    project = get_project_by_id(project_id)
716 db99f198 Giorgos Korfiatis
    checkAlive(project)
717 db99f198 Giorgos Korfiatis
718 db99f198 Giorgos Korfiatis
    project.suspend()
719 eb9ff37a Sofia Papagiannaki
    trigger_sync()
720 1352dabb Kostas Papadimitriou
721 a3eb3a95 Giorgos Korfiatis
    project_suspension_notify(project)
722 db99f198 Giorgos Korfiatis
723 db99f198 Giorgos Korfiatis
def resume(project_id):
724 db99f198 Giorgos Korfiatis
    project = get_project_for_update(project_id)
725 db99f198 Giorgos Korfiatis
726 db99f198 Giorgos Korfiatis
    if not project.is_suspended:
727 db99f198 Giorgos Korfiatis
        m = _(astakos_messages.NOT_SUSPENDED_PROJECT) % project.__dict__
728 db99f198 Giorgos Korfiatis
        raise PermissionDenied(m)
729 db99f198 Giorgos Korfiatis
730 db99f198 Giorgos Korfiatis
    project.resume()
731 db99f198 Giorgos Korfiatis
    trigger_sync()