Statistics
| Branch: | Tag: | Revision:

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

History | View | Annotate | Download (28.4 kB)

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

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

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

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

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

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

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