Statistics
| Branch: | Tag: | Revision:

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

History | View | Annotate | Download (25 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 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 84a3f701 Giorgos Korfiatis
from astakos.im.endpoints.qh import qh_register_user_with_quotas, 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 f9224cc0 Sofia Papagiannaki
        send_mail(_(VERIFICATION_EMAIL_SUBJECT), message, sender, [user.email],
130 f9224cc0 Sofia Papagiannaki
                  connection=get_connection())
131 f9224cc0 Sofia Papagiannaki
132 8f5a3a06 Sofia Papagiannaki
    except (SMTPException, socket.error) as e:
133 8f5a3a06 Sofia Papagiannaki
        logger.exception(e)
134 8f5a3a06 Sofia Papagiannaki
        raise SendVerificationError()
135 8f5a3a06 Sofia Papagiannaki
    else:
136 111f3da6 Sofia Papagiannaki
        msg = 'Sent activation %s' % user.email
137 aab4d540 Sofia Papagiannaki
        logger.log(LOGGING_LEVEL, msg)
138 683cf244 Sofia Papagiannaki
139 5ce3ce4f Sofia Papagiannaki
140 751d24cf Sofia Papagiannaki
def send_activation(user, template_name='im/activation_email.txt'):
141 751d24cf Sofia Papagiannaki
    send_verification(user, template_name)
142 751d24cf Sofia Papagiannaki
    user.activation_sent = datetime.now()
143 751d24cf Sofia Papagiannaki
    user.save()
144 683cf244 Sofia Papagiannaki
145 5ce3ce4f Sofia Papagiannaki
146 9a06d96f Olga Brani
def _send_admin_notification(template_name,
147 9a06d96f Olga Brani
                             dictionary=None,
148 9a06d96f Olga Brani
                             subject='alpha2 testing notification',):
149 683cf244 Sofia Papagiannaki
    """
150 1cbce16f Sofia Papagiannaki
    Send notification email to settings.ADMINS.
151 5ce3ce4f Sofia Papagiannaki

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

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

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

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

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