Revision 59f598f1

b/snf-astakos-app/astakos/im/api.py
92 92
                     'uniq':user.email,
93 93
                     'auth_token':user.auth_token,
94 94
                     'auth_token_created':user.auth_token_created.isoformat(),
95
                     'auth_token_expires':user.auth_token_expires.isoformat()}
95
                     'auth_token_expires':user.auth_token_expires.isoformat(),
96
                     'has_credits':user.has_credits}
96 97
        response.content = json.dumps(user_info)
97 98
        response['Content-Type'] = 'application/json; charset=UTF-8'
98 99
        response['Content-Length'] = len(response.content)
b/snf-astakos-app/astakos/im/functions.py
41 41
from random import randint
42 42

  
43 43
from astakos.im.settings import DEFAULT_CONTACT_EMAIL, DEFAULT_FROM_EMAIL, SITENAME, BASEURL
44
from astakos.im.models import Invitation
44
from astakos.im.models import Invitation, AstakosUser
45 45

  
46 46
logger = logging.getLogger(__name__)
47 47

  
......
98 98
    logger.info('Sent invitation %s', invitation)
99 99
    inviter.invitations = max(0, inviter.invitations - 1)
100 100
    inviter.save()
101

  
102
def set_user_credibility(email, has_credits):
103
    try:
104
        user = AstakosUser.objects.get(email=email)
105
        user.has_credits = has_credits
106
        user.save()
107
    except AstakosUser.DoesNotExist, e:
108
        logger.exception(e)
b/snf-astakos-app/astakos/im/migrations/0005_auto__add_field_astakosuser_has_credits.py
1
# encoding: utf-8
2
import datetime
3
from south.db import db
4
from south.v2 import SchemaMigration
5
from django.db import models
6

  
7
class Migration(SchemaMigration):
8

  
9
    def forwards(self, orm):
10
        
11
        # Adding field 'AstakosUser.has_credits'
12
        db.add_column('im_astakosuser', 'has_credits', self.gf('django.db.models.fields.BooleanField')(default=False), keep_default=False)
13

  
14

  
15
    def backwards(self, orm):
16
        
17
        # Deleting field 'AstakosUser.has_credits'
18
        db.delete_column('im_astakosuser', 'has_credits')
19

  
20

  
21
    models = {
22
        'auth.group': {
23
            'Meta': {'object_name': 'Group'},
24
            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
25
            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
26
            'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
27
        },
28
        'auth.permission': {
29
            'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
30
            'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
31
            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
32
            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
33
            'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
34
        },
35
        'auth.user': {
36
            'Meta': {'object_name': 'User'},
37
            'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
38
            'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
39
            'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
40
            'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
41
            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
42
            'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
43
            'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
44
            'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
45
            'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
46
            'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
47
            'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
48
            'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
49
            'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
50
        },
51
        'contenttypes.contenttype': {
52
            'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
53
            'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
54
            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
55
            'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
56
            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
57
        },
58
        'im.astakosuser': {
59
            'Meta': {'object_name': 'AstakosUser', '_ormbases': ['auth.User']},
60
            'affiliation': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
61
            'auth_token': ('django.db.models.fields.CharField', [], {'max_length': '32', 'null': 'True', 'blank': 'True'}),
62
            'auth_token_created': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}),
63
            'auth_token_expires': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}),
64
            'email_verified': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
65
            'has_credits': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
66
            'invitations': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
67
            'is_verified': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
68
            'level': ('django.db.models.fields.IntegerField', [], {'default': '4'}),
69
            'provider': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
70
            'third_party_identifier': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
71
            'updated': ('django.db.models.fields.DateTimeField', [], {}),
72
            'user_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['auth.User']", 'unique': 'True', 'primary_key': 'True'})
73
        },
74
        'im.invitation': {
75
            'Meta': {'object_name': 'Invitation'},
76
            'accepted': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
77
            'code': ('django.db.models.fields.BigIntegerField', [], {'db_index': 'True'}),
78
            'consumed': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
79
            'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
80
            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
81
            'inviter': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'invitations_sent'", 'null': 'True', 'to': "orm['im.AstakosUser']"}),
82
            'is_accepted': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
83
            'is_consumed': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
84
            'realname': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
85
            'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'})
86
        }
87
    }
88

  
89
    complete_apps = ['im']
b/snf-astakos-app/astakos/im/models.py
42 42
from django.contrib.auth.models import User, UserManager
43 43

  
44 44
from astakos.im.settings import DEFAULT_USER_LEVEL, INVITATIONS_PER_LEVEL, AUTH_TOKEN_DURATION, BILLING_FIELDS, QUEUE_CONNECTION
45
from astakos.im.queue.userevent import UserEvent
45 46
from synnefo.lib.queue import exchange_connect, exchange_send, exchange_close, Receipt
46 47

  
47 48
QUEUE_CLIENT_ID = 3 # Astakos.
......
74 75
    
75 76
    email_verified = models.BooleanField('Email verified?', default=False)
76 77
    
78
    has_credits = models.BooleanField('Has credits?', default=False)
79
    
77 80
    @property
78 81
    def realname(self):
79 82
        return '%s %s' %(self.first_name, self.last_name)
......
165 168
        return False
166 169
    
167 170
    if QUEUE_CONNECTION and should_send(user):
168
        l = [[elem, str(user.__getattribute__(elem))] for elem in BILLING_FIELDS]
169
        details = dict(l)
170
        details['eventType'] = 'create' if not user.id else 'modify'
171
        body = Receipt(QUEUE_CLIENT_ID, user.email, '', 0, details).format()
171
        eventType = 'create' if not user.id else 'modify'
172
        body = UserEvent(QUEUE_CLIENT_ID, user, eventType, {}).format()
172 173
        conn = exchange_connect(QUEUE_CONNECTION)
173
        routing_key = QUEUE_CONNECTION.replace('#', body['id'])
174
        routing_key = QUEUE_CONNECTION.replace('*', 'user')
174 175
        exchange_send(conn, routing_key, body)
175
        exchange_close(conn)
176
        exchange_close(conn)
b/snf-astakos-app/astakos/im/queue/listener.py
1
# Copyright 2011-2012 GRNET S.A. All rights reserved.
2
#
3
# Redistribution and use in source and binary forms, with or
4
# without modification, are permitted provided that the following
5
# conditions are met:
6
#
7
#   1. Redistributions of source code must retain the above
8
#      copyright notice, this list of conditions and the following
9
#      disclaimer.
10
#
11
#   2. Redistributions in binary form must reproduce the above
12
#      copyright notice, this list of conditions and the following
13
#      disclaimer in the documentation and/or other materials
14
#      provided with the distribution.
15
#
16
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27
# POSSIBILITY OF SUCH DAMAGE.
28
#
29
# The views and conclusions contained in the software and
30
# documentation are those of the authors and should not be
31
# interpreted as representing official policies, either expressed
32
# or implied, of GRNET S.A.
33

  
34
import logging
35
import json
36

  
37
from astakos.im.functions import set_user_credibility
38

  
39
logger = logging.getLogger(__name__)
40

  
41
def on_creditevent(msg):
42
    try:
43
        email = msg.get('userid')
44
        has_credits = True if msg.get('status') == 'on' else False
45
        set_user_credibility(email, has_credits)
46
    except Exception, e:
47
        logger.exception(e)
b/snf-astakos-app/astakos/im/queue/userevent.py
1
# Copyright 2011-2012 GRNET S.A. All rights reserved.
2
#
3
# Redistribution and use in source and binary forms, with or
4
# without modification, are permitted provided that the following
5
# conditions are met:
6
#
7
#   1. Redistributions of source code must retain the above
8
#      copyright notice, this list of conditions and the following
9
#      disclaimer.
10
#
11
#   2. Redistributions in binary form must reproduce the above
12
#      copyright notice, this list of conditions and the following
13
#      disclaimer in the documentation and/or other materials
14
#      provided with the distribution.
15
#
16
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27
# POSSIBILITY OF SUCH DAMAGE.
28
#
29
# The views and conclusions contained in the software and
30
# documentation are those of the authors and should not be
31
# interpreted as representing official policies, either expressed
32
# or implied, of GRNET S.A.
33

  
34
import json
35

  
36
from time import time
37
from hashlib import sha1
38
from random import random
39

  
40
class UserEvent(object):
41
    def __init__(self, client, user, eventType, details={}):
42
        self.eventVersion = '1.0'
43
        self.occurredMillis = int(time() * 1000)
44
        self.receivedMillis = self.occurredMillis
45
        self.clientID = client
46
        self.userID = user.email
47
        self.is_active = user.is_active
48
        self.role = 'default'
49
        self.eventType = eventType
50
        self.details = details
51
        hash = sha1()
52
        hash.update(json.dumps([client, self.userID, self.is_active, self.role,
53
                                self.eventType, self.details, random()]))
54
        self.id = hash.hexdigest()
55
    
56
    def format(self):
57
        return self.__dict__
b/snf-astakos-app/astakos/im/settings.py
62 62
BILLING_FIELDS = getattr(settings, 'ASTAKOS_BILLING_FIELDS', ['id', 'is_active', 'provider', 'third_party_identifier'])
63 63

  
64 64
# Queue for billing.
65
QUEUE_CONNECTION = getattr(settings, 'ASTAKOS_QUEUE_CONNECTION', None) # Example: 'rabbitmq://guest:guest@localhost:5672/astakos.userEvent.#'
65
QUEUE_CONNECTION = getattr(settings, 'ASTAKOS_QUEUE_CONNECTION', None) # Example: 'rabbitmq://guest:guest@localhost:5672/astakos.*'
66 66

  
67 67
# Set where the user should be redirected after logout
68 68
LOGOUT_NEXT = getattr(settings, 'ASTAKOS_LOGOUT_NEXT', '')

Also available in: Unified diff