-
Notifications
You must be signed in to change notification settings - Fork 1
/
web_user.py
230 lines (202 loc) · 7.76 KB
/
web_user.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
# For copyright and license terms, see COPYRIGHT.rst (top level of repository)
# Repository: https://github.com/C3S/collecting_society
import uuid
import string
import random
from trytond.model import ModelView, ModelSQL, fields, Unique
from trytond.pool import Pool, PoolMeta
# from trytond.pyson import Eval, Greater
from trytond.rpc import RPC
__all__ = [
'UserRole',
'User',
'UserResUser',
'UserUserRole',
'UserParty',
]
_OPT_IN_STATES = [
('new', 'New'),
('mail-sent', 'Mail Sent'),
('opted-in', 'Opted-In'),
('opted-out', 'Opted-Out'),
]
class UserRole(ModelSQL, ModelView):
"Web User Role"
__name__ = 'web.user.role'
_history = True
name = fields.Char(
'Name', required=True, translate=True,
help='The display name of role.')
code = fields.Char(
'Code', required=True,
help='The internal or programmatical name of the role.')
class User(metaclass=PoolMeta):
__name__ = 'web.user'
_history = True
_rec_name = 'email'
nickname = fields.Char(
'Nickname', help='The name shown to other users')
user = fields.One2One(
'web.user-res.user', 'web_user', 'res_user', 'Tryton User',
readonly=True, states={'required': True},
help='The Tryton user of the web user')
devices = fields.One2Many('device', 'web_user', 'Devices')
roles = fields.Many2Many(
'web.user-web.user.role', 'user', 'role', 'Roles')
default_role = fields.Selection('get_roles', 'Default Role')
acl = fields.One2Many(
'ace', 'web_user', 'Access Control List',
help="The permissions for a web user.")
picture_data = fields.Binary(
'Picture Data', help='Picture Data')
picture_data_mime_type = fields.Char(
'Picture Data Mime Type', help='The mime type of picture data.')
opt_in_state = fields.Selection(
_OPT_IN_STATES, 'Opt-in State',
help='The authentication state of the opt-in method:\n\n'
'New: The web-user is newly created.\n'
'Mail Sent: An opt-in link is sent to the email.\n'
'Opted-In: The link is clicked.\n'
'Opted-Out: The web-user opted-out.')
opt_in_uuid = fields.Char(
'Opt-in UUID',
help='The universally unique identifier of the opt-in of a web user')
opt_in_timestamp = fields.DateTime('Date of Opt-in')
opt_out_timestamp = fields.DateTime('Date of Opt-out')
abuse_rank = fields.Integer(
'Abuse Rank', help='Times of potential abuse.')
new_email = fields.Char(
'New Email', help='On profile change, the new email '
'stays here till the user clicks the activation link')
@classmethod
def __setup__(cls):
super().__setup__()
cls.party = fields.One2One(
'web.user-party.party', 'user', 'party', 'Party',
states={'required': True},
help='The party of the web user')
cls.__rpc__.update(
{'authenticate': RPC(check_access=False)})
table = cls.__table__()
cls._sql_constraints += [
('opt_in_uuid_uniq', Unique(table, table.opt_in_uuid),
'The opt-in UUID of the Webuser must be unique.'),
]
@staticmethod
def default_opt_in_state():
return 'new'
@staticmethod
def default_opt_in_uuid():
return str(uuid.uuid4())
@staticmethod
def get_roles():
Role = Pool().get('web.user.role')
roles = Role.search([])
return [(x.code, x.name) for x in roles] + [(None, '')]
@classmethod
def create(cls, vlist):
pool = Pool()
User = pool.get('res.user')
Party = pool.get('party.party')
Artist = pool.get('artist')
UserRole = pool.get('web.user.role')
licenser = UserRole.search([('code', '=', 'licenser')])
if licenser:
licenser = licenser[0]
vlist = [x.copy() for x in vlist]
for values in vlist:
nickname = values.get('nickname')
email = values.get('email')
user_email = email + ':::' + ''.join(
random.sample(string.ascii_lowercase, 10))
# autocreate party
if not values.get('party'):
values['party'] = Party.create(
[
{
'name': nickname or email,
'contact_mechanisms': [(
'create', [{
'type': 'email',
'value': email
}]
)]
}])[0].id
# autocreate user
if not values.get('user'):
values['user'] = User.create(
[
{
'name': nickname or user_email,
'login': user_email,
'email': email,
'active': False,
}])[0].id
elist = super().create(vlist)
for entry in elist:
# autocreate first artist
if licenser in entry.roles and entry.nickname:
artist, = Artist.create(
[
{
'name': nickname,
'party': entry.party.id,
'entity_origin': 'direct',
'entity_creator': entry.party.id,
'claim_state': 'claimed'
}])
entry.party.artists = [artist]
entry.party.default_solo_artist = artist.id
entry.party.save()
return elist
class UserResUser(ModelSQL):
'Web User - Tryton User'
__name__ = 'web.user-res.user'
web_user = fields.Many2One(
'web.user', 'Web User', ondelete='CASCADE', required=True)
res_user = fields.Many2One(
'res.user', 'Tryton User', ondelete='CASCADE', required=True)
@classmethod
def __setup__(cls):
super(UserResUser, cls).__setup__()
table = cls.__table__()
cls._sql_constraints += [
('web_user_uniq', Unique(table, table.web_user),
'Error!\n'
'A web user can only be linked to one Tryton user.\n'
'The used web user is already linked to another Tryton user.'),
('res_user_uniq', Unique(table, table.res_user),
'Error!\n'
'A Tryton user can only be linked to one web user.\n'
'The used Tryton user is already linked to another web user.'),
]
class UserUserRole(ModelSQL, ModelView):
"Web User - Web User Role"
__name__ = 'web.user-web.user.role'
_history = True
user = fields.Many2One(
'web.user', 'User', ondelete='CASCADE', required=True)
role = fields.Many2One(
'web.user.role', 'Role', ondelete='CASCADE', required=True)
class UserParty(ModelSQL):
"Web User - Party"
__name__ = 'web.user-party.party'
_history = True
user = fields.Many2One(
'web.user', 'User', ondelete='CASCADE', required=True)
party = fields.Many2One(
'party.party', 'Party', ondelete='CASCADE', required=True)
@classmethod
def __setup__(cls):
super().__setup__()
table = cls.__table__()
cls._sql_constraints += [
('user_uniq', Unique(table, table.user),
'Error!\n'
'A web user can only be linked to one party.\n'
'The used web user is already linked to another party.'),
('party_uniq', Unique(table, table.party),
'Error!\n'
'A party can only be linked to one web user.\n'
'The used party is already linked to another web user.'),
]