Browse Source

Merge branch 'fix/better_api_doc' of github.com:tracim/tracim_backend into fix/few_more_tests

Guénaël Muller 6 years ago
parent
commit
3eba2081c1

+ 0 - 1
README.md View File

124
     docker pull mailhog/mailhog
124
     docker pull mailhog/mailhog
125
     docker run -d -p 1025:1025 -p 8025:8025 mailhog/mailhog
125
     docker run -d -p 1025:1025 -p 8025:8025 mailhog/mailhog
126
 
126
 
127
-
128
 Run your project's tests:
127
 Run your project's tests:
129
 
128
 
130
     pytest
129
     pytest

+ 275 - 0
development.ini.oloool View File

1
+###
2
+# app configuration
3
+# https://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html
4
+###
5
+;[pipeline:main]
6
+;pipeline = tracim_web
7
+
8
+[app:main]
9
+use = egg:tracim_backend
10
+
11
+pyramid.reload_templates = true
12
+pyramid.debug_authorization = false
13
+pyramid.debug_notfound = false
14
+pyramid.debug_routematch = false
15
+pyramid.default_locale_name = en
16
+;pyramid.includes =
17
+;    pyramid_debugtoolbar
18
+
19
+retry.attempts = 3
20
+
21
+sqlalchemy.url = sqlite:///%(here)s/tracim.sqlite
22
+
23
+# By default, the toolbar only appears for clients from IP addresses
24
+# '127.0.0.1' and '::1'.
25
+# debugtoolbar.hosts = 127.0.0.1 ::1
26
+
27
+###
28
+# TRACIM SPECIFIC CONF
29
+###
30
+
31
+### Global
32
+
33
+cache_dir = %(here)s/data
34
+# preview generator cache directory
35
+preview_cache_dir = /tmp/tracim/preview/
36
+# file depot storage
37
+depot_storage_name = tracim
38
+depot_storage_dir = %(here)s/depot/
39
+
40
+# The following parameters allow to personalize the home page
41
+# They are html ready (you can put html tags they will be interpreted)
42
+website.title = TRACIM
43
+website.title.color = #555
44
+website.home.subtitle = Default login: email: admin@admin.admin (password: admin@admin.admin)
45
+website.home.tag_line = <div class="text-center" style="font-weight: bold;">Collaboration, versionning and traceability</div>
46
+website.home.below_login_form = in case of problem, please contact the administrator.
47
+# Values may be 'all' or 'folders'
48
+website.treeview.content = all
49
+# The following base_url is used for links and icons
50
+# integrated in the email notifcations
51
+website.base_url = http://127.0.0.1:8080
52
+# If config not provided, it will be extracted from website.base_url
53
+website.server_name = 127.0.0.1
54
+
55
+# Specifies if the update of comments and attached files is allowed (by the owner only).
56
+# Examples:
57
+#    600 means 10 minutes (ie 600 seconds)
58
+#   3600 means 1 hour (60x60 seconds)
59
+#
60
+# Allowed values:
61
+#  -1 means that content update is allowed for ever
62
+#   0 means that content update is not allowed
63
+#   x means that content update is allowed for x seconds (with x>0)
64
+content.update.allowed.duration = 3600
65
+
66
+# Auth type (internal or ldap)
67
+auth_type = internal
68
+# If auth_type is ldap, uncomment following ldap_* parameters
69
+# LDAP server address
70
+# ldap_url = ldap://localhost:389
71
+# Base dn to make queries
72
+# ldap_base_dn = dc=directory,dc=fsf,dc=org
73
+# Bind dn to identify the search
74
+# ldap_bind_dn = cn=admin,dc=directory,dc=fsf,dc=org
75
+# The bind password
76
+# ldap_bind_pass = toor
77
+# Attribute name of user record who contain user login (email)
78
+# ldap_ldap_naming_attribute = uid
79
+# Matching between ldap attribute and ldap user field (ldap_attr1=user_field1,ldap_attr2=user_field2,...)
80
+# ldap_user_attributes = mail=email
81
+# TLS usage to communicate with your LDAP server
82
+# ldap_tls = False
83
+# If True, LDAP own tracim group managment (not available for now!)
84
+# ldap_group_enabled = False
85
+# User auth token validity in seconds (used to interfaces like web calendars)
86
+user.auth_token.validity = 604800
87
+
88
+### Mail
89
+
90
+# Reset password through email related configuration.
91
+# These emails will be sent through SMTP
92
+#
93
+resetpassword.email_sender = email@sender.com
94
+resetpassword.smtp_host = smtp.sender
95
+resetpassword.smtp_port = 25
96
+resetpassword.smtp_login = smtp.login
97
+resetpassword.smtp_passwd = smtp.password
98
+
99
+email.notification.activated = false
100
+# email.notification.log_file_path = /tmp/mail-notifications.log
101
+# email notifications can be sent with the user_id added as an identifier
102
+# this way email clients like Thunderbird will be able to distinguish
103
+# notifications generated by a user or another one
104
+email.notification.from.email = dev.tracim.maildaemon+{user_id}@algoo.fr
105
+email.notification.from.default_label = Tracim Notifications
106
+email.notification.reply_to.email = dev.tracim.maildaemon+{content_id}@algoo.fr
107
+email.notification.references.email = dev.tracim.maildaemon+{content_id}@algoo.fr
108
+email.notification.content_update.template.html = %(here)s/tracim/templates/mail/content_update_body_html.mak
109
+email.notification.content_update.template.text = %(here)s/tracim/templates/mail/content_update_body_text.mak
110
+email.notification.created_account.template.html = %(here)s/tracim/templates/mail/created_account_body_html.mak
111
+email.notification.created_account.template.text = %(here)s/tracim/templates/mail/created_account_body_text.mak
112
+# Note: items between { and } are variable names. Do not remove / rename them
113
+email.notification.content_update.subject = [{website_title}] [{workspace_label}] {content_label} ({content_status_label})
114
+email.notification.created_account.subject = [{website_title}] Created account
115
+# processing_mode may be sync or async
116
+email.notification.processing_mode = async
117
+email.notification.smtp.server = mail.gandi.net
118
+email.notification.smtp.port = 25
119
+email.notification.smtp.user = dev.tracim.maildaemon@algoo.fr
120
+email.notification.smtp.password = dev.tracim.maildaemon
121
+
122
+## Email sending configuration
123
+# processing_mode may be sync or async,
124
+# with async, please configure redis below
125
+email.processing_mode = sync
126
+# email.async.redis.host = localhost
127
+# email.async.redis.port = 6379
128
+# email.async.redis.db = 0
129
+
130
+# Email reply configuration
131
+email.reply.activated = false
132
+email.reply.imap.server = your_imap_server
133
+email.reply.imap.port = 993
134
+email.reply.imap.user = your_imap_user
135
+email.reply.imap.password = your_imap_password
136
+email.reply.imap.folder = INBOX
137
+email.reply.imap.use_ssl = true
138
+email.reply.imap.use_idle = true
139
+# Re-new connection each 10 minutes
140
+email.reply.connection.max_lifetime = 600
141
+# Token for communication between mail fetcher and tracim controller
142
+email.reply.token = mysecuretoken
143
+# Delay in seconds between each check
144
+email.reply.check.heartbeat = 60
145
+email.reply.use_html_parsing = true
146
+email.reply.use_txt_parsing = true
147
+# Lockfile path is required for email_reply feature,
148
+# it's just an empty file use to prevent concurrent access to imap unseen mail
149
+email.reply.lockfile_path = %(here)s/email_fetcher.lock
150
+
151
+### Radical (CalDav server) configuration
152
+
153
+# radicale.server.host = 0.0.0.0
154
+# radicale.server.port = 5232
155
+# radicale.server.ssl = false
156
+radicale.server.filesystem.folder = %(here)s/radicale/collections/
157
+# radicale.server.allow_origin = *
158
+# radicale.server.realm_message = Tracim Calendar - Password Required
159
+## url can be extended like http://127.0.0.1:5232/calendar
160
+## in this case, you have to create your own proxy behind this url.
161
+## and update following parameters
162
+# radicale.client.base_url.host = http://127.0.0.1:5232
163
+# radicale.client.base_url.prefix = /
164
+
165
+### WSGIDAV
166
+
167
+wsgidav.config_path = %(here)s/wsgidav.conf
168
+## url can be extended like 127.0.0.1/webdav
169
+## in this case, you have to create your own proxy behind this url.
170
+## Do not set http:// prefix.
171
+# wsgidav.client.base_url = 127.0.0.1:<WSGIDAV_PORT>
172
+
173
+###
174
+# wsgi server configuration
175
+###
176
+[uwsgi]
177
+# Legacy server config (waitress)
178
+[server:main]
179
+use = egg:waitress#main
180
+listen = localhost:6543
181
+
182
+[alembic]
183
+# path to migration scripts
184
+script_location = tracim/migration
185
+
186
+# template used to generate migration files
187
+# file_template = %%(rev)s_%%(slug)s
188
+
189
+# timezone to use when rendering the date
190
+# within the migration file as well as the filename.
191
+# string value is passed to dateutil.tz.gettz()
192
+# leave blank for localtime
193
+# timezone =
194
+
195
+# max length of characters to apply to the
196
+# "slug" field
197
+#truncate_slug_length = 40
198
+
199
+# set to 'true' to run the environment during
200
+# the 'revision' command, regardless of autogenerate
201
+# revision_environment = false
202
+
203
+# set to 'true' to allow .pyc and .pyo files without
204
+# a source .py file to be detected as revisions in the
205
+# versions/ directory
206
+# sourceless = false
207
+
208
+# version location specification; this defaults
209
+# to migrate/versions.  When using multiple version
210
+# directories, initial revisions must be specified with --version-path
211
+# version_locations = %(here)s/bar %(here)s/bat migrate/versions
212
+
213
+# the output encoding used when revision files
214
+# are written from script.py.mako
215
+# output_encoding = utf-8
216
+
217
+sqlalchemy.url = sqlite:///%(here)s/tracim.sqlite
218
+
219
+###
220
+# logging configuration
221
+# https://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html
222
+###
223
+
224
+[loggers]
225
+keys = root, tracim, sqlalchemy, alembic, sentry
226
+
227
+[handlers]
228
+keys = console, sentry
229
+
230
+[formatters]
231
+keys = generic
232
+
233
+[logger_root]
234
+level = INFO
235
+handlers = console, sentry
236
+
237
+[logger_sentry]
238
+level = WARN
239
+handlers = console
240
+qualname = sentry.errors
241
+propagate = 0
242
+
243
+[logger_tracim]
244
+level = DEBUG
245
+handlers =
246
+qualname = tracim
247
+
248
+[logger_sqlalchemy]
249
+level = INFO
250
+handlers =
251
+qualname = sqlalchemy.engine
252
+# "level = INFO" logs SQL queries.
253
+# "level = DEBUG" logs SQL queries and results.
254
+# "level = WARN" logs neither.  (Recommended for production systems.)
255
+
256
+[logger_alembic]
257
+level = INFO
258
+handlers =
259
+qualname = alembic
260
+
261
+[handler_console]
262
+class = StreamHandler
263
+args = (sys.stderr,)
264
+level = NOTSET
265
+formatter = generic
266
+
267
+[handler_sentry]
268
+class = raven.handlers.logging.SentryHandler
269
+args = ('http://1dbab0942cca4fbb97f3dae62cbc965d:4d1deecd8abc41e38c02b37ed4954f58@127.0.0.1:9000/4',)
270
+level = WARNING
271
+formatter = generic
272
+
273
+[formatter_generic]
274
+format = %(asctime)s %(levelname)-5.5s [%(name)s:%(lineno)s][%(threadName)s] %(message)s
275
+datefmt = %H:%M:%S

+ 1 - 1
setup.py View File

34
     # others
34
     # others
35
     'filedepot',
35
     'filedepot',
36
     'babel',
36
     'babel',
37
+    'python-slugify',
37
     # mail-notifier
38
     # mail-notifier
38
     'mako',
39
     'mako',
39
     'lxml',
40
     'lxml',
40
     'redis',
41
     'redis',
41
     'rq',
42
     'rq',
42
-    'python-slugify',
43
 ]
43
 ]
44
 
44
 
45
 tests_require = [
45
 tests_require = [

+ 1 - 1
tracim/exceptions.py View File

57
     pass
57
     pass
58
 
58
 
59
 
59
 
60
-class NotAuthentificated(TracimException):
60
+class NotAuthenticated(TracimException):
61
     pass
61
     pass
62
 
62
 
63
 
63
 

+ 3 - 1
tracim/lib/core/userworkspace.py View File

49
         """
49
         """
50
         Return WorkspaceInContext object from Workspace
50
         Return WorkspaceInContext object from Workspace
51
         """
51
         """
52
+        assert self._config
52
         workspace = UserRoleWorkspaceInContext(
53
         workspace = UserRoleWorkspaceInContext(
53
             user_role=user_role,
54
             user_role=user_role,
54
             dbsession=self._session,
55
             dbsession=self._session,
138
         workspace:Workspace
139
         workspace:Workspace
139
     ) -> typing.List[UserRoleInWorkspace]:
140
     ) -> typing.List[UserRoleInWorkspace]:
140
         return self._session.query(UserRoleInWorkspace)\
141
         return self._session.query(UserRoleInWorkspace)\
141
-            .filter(UserRoleInWorkspace.workspace_id == workspace.workspace_id).all()  # nopep8
142
+            .filter(UserRoleInWorkspace.workspace_id==workspace.workspace_id)\
143
+            .all()
142
 
144
 
143
     def save(self, role: UserRoleInWorkspace) -> None:
145
     def save(self, role: UserRoleInWorkspace) -> None:
144
         self._session.flush()
146
         self._session.flush()

+ 35 - 21
tracim/lib/mail_notifier/notifier.py View File

238
         notifiable_roles = WorkspaceApi(
238
         notifiable_roles = WorkspaceApi(
239
             current_user=user,
239
             current_user=user,
240
             session=self.session,
240
             session=self.session,
241
-            config=self.config
241
+            config=self.config,
242
         ).get_notifiable_roles(content.workspace)
242
         ).get_notifiable_roles(content.workspace)
243
 
243
 
244
         if len(notifiable_roles) <= 0:
244
         if len(notifiable_roles) <= 0:
358
         text_template_file_path = self.config.EMAIL_NOTIFICATION_CREATED_ACCOUNT_TEMPLATE_TEXT  # nopep8
358
         text_template_file_path = self.config.EMAIL_NOTIFICATION_CREATED_ACCOUNT_TEMPLATE_TEXT  # nopep8
359
         html_template_file_path = self.config.EMAIL_NOTIFICATION_CREATED_ACCOUNT_TEMPLATE_HTML  # nopep8
359
         html_template_file_path = self.config.EMAIL_NOTIFICATION_CREATED_ACCOUNT_TEMPLATE_HTML  # nopep8
360
 
360
 
361
+        context = {
362
+            'user': user,
363
+            'password': password,
364
+            # TODO - G.M - 11-06-2018 - [emailTemplateURL] correct value for logo_url  # nopep8
365
+            'logo_url': '',
366
+            # TODO - G.M - 11-06-2018 - [emailTemplateURL] correct value for login_url  # nopep8
367
+            'login_url': self.config.WEBSITE_BASE_URL,
368
+        }
361
         body_text = self._render_template(
369
         body_text = self._render_template(
362
             mako_template_filepath=text_template_file_path,
370
             mako_template_filepath=text_template_file_path,
363
-            context={
364
-                'user': user,
365
-                'password': password,
366
-                'login_url': self.config.WEBSITE_BASE_URL,
367
-            }
371
+            context=context
368
         )
372
         )
369
 
373
 
370
         body_html = self._render_template(
374
         body_html = self._render_template(
371
             mako_template_filepath=html_template_file_path,
375
             mako_template_filepath=html_template_file_path,
372
-            context={
373
-                'user': user,
374
-                'password': password,
375
-                'login_url': self.config.WEBSITE_BASE_URL,
376
-            }
376
+            context=context,
377
         )
377
         )
378
 
378
 
379
         part1 = MIMEText(body_text, 'plain', 'utf-8')
379
         part1 = MIMEText(body_text, 'plain', 'utf-8')
434
         content_text = ''
434
         content_text = ''
435
         call_to_action_text = ''
435
         call_to_action_text = ''
436
 
436
 
437
+        # TODO - G.M - 11-06-2018 - [emailTemplateURL] correct value for call_to_action_url  # nopep8
438
+        call_to_action_url =''
439
+        # TODO - G.M - 11-06-2018 - [emailTemplateURL] correct value for status_icon_url  # nopep8
440
+        status_icon_url = ''
441
+        # TODO - G.M - 11-06-2018 - [emailTemplateURL] correct value for workspace_url  # nopep8
442
+        workspace_url = ''
443
+        # TODO - G.M - 11-06-2018 - [emailTemplateURL] correct value for logo_url  # nopep8
444
+        logo_url = ''
445
+
437
         action = content.get_last_action().id
446
         action = content.get_last_action().id
438
         if ActionDescription.COMMENT == action:
447
         if ActionDescription.COMMENT == action:
439
             content_intro = l_('<span id="content-intro-username">{}</span> added a comment:').format(actor.display_name)
448
             content_intro = l_('<span id="content-intro-username">{}</span> added a comment:').format(actor.display_name)
523
             )
532
             )
524
             raise ValueError('Unexpected empty notification')
533
             raise ValueError('Unexpected empty notification')
525
 
534
 
535
+        context = {
536
+            'user': role.user,
537
+            'workspace': role.workspace,
538
+            'workspace_url': workspace_url,
539
+            'main_title': main_title,
540
+            'status_label': content.get_status().label,
541
+            'status_icon_url': status_icon_url,
542
+            'role_label': role.role_as_label(),
543
+            'content_intro': content_intro,
544
+            'content_text': content_text,
545
+            'call_to_action_text': call_to_action_text,
546
+            'call_to_action_url': call_to_action_url,
547
+            'logo_url': logo_url,
548
+        }
526
         user = role.user
549
         user = role.user
527
         workspace = role.workspace
550
         workspace = role.workspace
528
         body_content = self._render_template(
551
         body_content = self._render_template(
529
             mako_template_filepath=mako_template_filepath,
552
             mako_template_filepath=mako_template_filepath,
530
-            context={
531
-                'user': role.user,
532
-                'workspace': role.workspace,
533
-                'main_title': main_title,
534
-                'status': content.get_status().label,
535
-                'role': role.role_as_label(),
536
-                'content_intro': content_intro,
537
-                'content_text': content_text,
538
-                'call_to_action_text': call_to_action_text,
539
-            }
553
+            context=context,
540
         )
554
         )
541
         return body_content
555
         return body_content
542
 
556
 

+ 1 - 1
tracim/lib/utils/authentification.py View File

51
         if not login:
51
         if not login:
52
             return None
52
             return None
53
         user = uapi.get_one_by_email(login)
53
         user = uapi.get_one_by_email(login)
54
-    except (NoResultFound, UserDoesNotExist):
54
+    except UserDoesNotExist:
55
         return None
55
         return None
56
     return user
56
     return user

+ 3 - 3
tracim/lib/utils/authorization.py View File

44
 # We prefer to use decorators
44
 # We prefer to use decorators
45
 
45
 
46
 
46
 
47
-def require_same_user_or_profile(group):
47
+def require_same_user_or_profile(group: int):
48
     """
48
     """
49
     Decorator for view to restrict access of tracim request if candidate user
49
     Decorator for view to restrict access of tracim request if candidate user
50
     is distinct from authenticated user and not with high enough profile.
50
     is distinct from authenticated user and not with high enough profile.
64
     return decorator
64
     return decorator
65
 
65
 
66
 
66
 
67
-def require_profile(group):
67
+def require_profile(group: int):
68
     """
68
     """
69
     Decorator for view to restrict access of tracim request if profile is
69
     Decorator for view to restrict access of tracim request if profile is
70
     not high enough
70
     not high enough
82
     return decorator
82
     return decorator
83
 
83
 
84
 
84
 
85
-def require_workspace_role(minimal_required_role):
85
+def require_workspace_role(minimal_required_role: int):
86
     """
86
     """
87
     Decorator for view to restrict access of tracim request if role
87
     Decorator for view to restrict access of tracim request if role
88
     is not high enough
88
     is not high enough

+ 6 - 3
tracim/lib/utils/request.py View File

6
 from sqlalchemy.orm.exc import NoResultFound
6
 from sqlalchemy.orm.exc import NoResultFound
7
 
7
 
8
 
8
 
9
-from tracim.exceptions import NotAuthentificated
9
+from tracim.exceptions import NotAuthenticated
10
 from tracim.exceptions import UserNotFoundInTracimRequest
10
 from tracim.exceptions import UserNotFoundInTracimRequest
11
 from tracim.exceptions import UserDoesNotExist
11
 from tracim.exceptions import UserDoesNotExist
12
 from tracim.exceptions import WorkspaceNotFound
12
 from tracim.exceptions import WorkspaceNotFound
40
         )
40
         )
41
         # Current workspace, found by request headers or content
41
         # Current workspace, found by request headers or content
42
         self._current_workspace = None  # type: Workspace
42
         self._current_workspace = None  # type: Workspace
43
+
43
         # Authenticated user
44
         # Authenticated user
44
         self._current_user = None  # type: User
45
         self._current_user = None  # type: User
46
+
45
         # User found from request headers, content, distinct from authenticated
47
         # User found from request headers, content, distinct from authenticated
46
         # user
48
         # user
47
         self._user_candidate = None  # type: User
49
         self._user_candidate = None  # type: User
50
+
48
         # INFO - G.M - 18-05-2018 - Close db at the end of the request
51
         # INFO - G.M - 18-05-2018 - Close db at the end of the request
49
         self.add_finished_callback(self._cleanup)
52
         self.add_finished_callback(self._cleanup)
50
 
53
 
168
             raise UserNotFoundInTracimRequest('You request a current user but the context not permit to found one')  # nopep8
171
             raise UserNotFoundInTracimRequest('You request a current user but the context not permit to found one')  # nopep8
169
         user = uapi.get_one_by_email(login)
172
         user = uapi.get_one_by_email(login)
170
     except (UserDoesNotExist, UserNotFoundInTracimRequest) as exc:
173
     except (UserDoesNotExist, UserNotFoundInTracimRequest) as exc:
171
-        raise NotAuthentificated('User {} not found'.format(login)) from exc
174
+        raise NotAuthenticated('User {} not found'.format(login)) from exc
172
     return user
175
     return user
173
 
176
 
174
 
177
 
187
         if 'workspace_id' in request.matchdict:
190
         if 'workspace_id' in request.matchdict:
188
             workspace_id = request.matchdict['workspace_id']
191
             workspace_id = request.matchdict['workspace_id']
189
         if not workspace_id:
192
         if not workspace_id:
190
-            raise WorkspaceNotFound('No workspace_id param')
193
+            raise WorkspaceNotFound('No workspace_id property found in request')
191
         wapi = WorkspaceApi(
194
         wapi = WorkspaceApi(
192
             current_user=user,
195
             current_user=user,
193
             session=request.dbsession,
196
             session=request.dbsession,

+ 2 - 2
tracim/lib/webdav/design.py View File

164
                     <td>%s</td>
164
                     <td>%s</td>
165
                 </tr>
165
                 </tr>
166
                 ''' % ('warning' if event.id == content_revision.revision_id else '',
166
                 ''' % ('warning' if event.id == content_revision.revision_id else '',
167
-                       event.type.icon,
167
+                       event.type.fa_icon,
168
                        label,
168
                        label,
169
                        date,
169
                        date,
170
                        event.owner.display_name,
170
                        event.owner.display_name,
282
                         </div>
282
                         </div>
283
                     </div>
283
                     </div>
284
                     ''' % ('warning' if t.id == content_revision.revision_id else '',
284
                     ''' % ('warning' if t.id == content_revision.revision_id else '',
285
-                           t.type.icon,
285
+                           t.type.fa_icon,
286
                            t.owner.display_name,
286
                            t.owner.display_name,
287
                            t.create_readable_date(),
287
                            t.create_readable_date(),
288
                            label,
288
                            label,

+ 21 - 9
tracim/models/applications.py View File

10
             self,
10
             self,
11
             label: str,
11
             label: str,
12
             slug: str,
12
             slug: str,
13
-            icon: str,
13
+            fa_icon: str,
14
             hexcolor: str,
14
             hexcolor: str,
15
             is_active: bool,
15
             is_active: bool,
16
             config: typing.Dict[str, str],
16
             config: typing.Dict[str, str],
17
             main_route: str,
17
             main_route: str,
18
     ) -> None:
18
     ) -> None:
19
+        """
20
+        @param label: public label of application
21
+        @param slug: identifier of application
22
+        @param icon: font awesome icon class
23
+        @param hexcolor: hexa color of application main color
24
+        @param is_active: True if application enable, False if inactive
25
+        @param config: a dict with eventual application config
26
+        @param main_route: the route of the frontend "home" screen of
27
+        the application. For exemple, if you have an application
28
+        called "calendar", the main route will be something
29
+        like /#/workspace/{wid}/calendar.
30
+        """
19
         self.label = label
31
         self.label = label
20
         self.slug = slug
32
         self.slug = slug
21
-        self.icon = icon
33
+        self.fa_icon = fa_icon
22
         self.hexcolor = hexcolor
34
         self.hexcolor = hexcolor
23
         self.is_active = is_active
35
         self.is_active = is_active
24
         self.config = config
36
         self.config = config
29
 calendar = Application(
41
 calendar = Application(
30
     label='Calendar',
42
     label='Calendar',
31
     slug='calendar',
43
     slug='calendar',
32
-    icon='calendar-alt',
44
+    fa_icon='calendar-alt',
33
     hexcolor='#757575',
45
     hexcolor='#757575',
34
     is_active=True,
46
     is_active=True,
35
     config={},
47
     config={},
39
 thread = Application(
51
 thread = Application(
40
     label='Threads',
52
     label='Threads',
41
     slug='contents/threads',
53
     slug='contents/threads',
42
-    icon='comments-o',
54
+    fa_icon='comments-o',
43
     hexcolor='#ad4cf9',
55
     hexcolor='#ad4cf9',
44
     is_active=True,
56
     is_active=True,
45
     config={},
57
     config={},
47
 
59
 
48
 )
60
 )
49
 
61
 
50
-file = Application(
62
+_file = Application(
51
     label='Files',
63
     label='Files',
52
     slug='contents/files',
64
     slug='contents/files',
53
-    icon='paperclip',
65
+    fa_icon='paperclip',
54
     hexcolor='#FF9900',
66
     hexcolor='#FF9900',
55
     is_active=True,
67
     is_active=True,
56
     config={},
68
     config={},
60
 markdownpluspage = Application(
72
 markdownpluspage = Application(
61
     label='Markdown Plus Documents',  # TODO - G.M - 24-05-2018 - Check label
73
     label='Markdown Plus Documents',  # TODO - G.M - 24-05-2018 - Check label
62
     slug='contents/markdownpluspage',
74
     slug='contents/markdownpluspage',
63
-    icon='file-code',
75
+    fa_icon='file-code',
64
     hexcolor='#f12d2d',
76
     hexcolor='#f12d2d',
65
     is_active=True,
77
     is_active=True,
66
     config={},
78
     config={},
70
 htmlpage = Application(
82
 htmlpage = Application(
71
     label='Text Documents',  # TODO - G.M - 24-05-2018 - Check label
83
     label='Text Documents',  # TODO - G.M - 24-05-2018 - Check label
72
     slug='contents/htmlpage',
84
     slug='contents/htmlpage',
73
-    icon='file-text-o',
85
+    fa_icon='file-text-o',
74
     hexcolor='#3f52e3',
86
     hexcolor='#3f52e3',
75
     is_active=True,
87
     is_active=True,
76
     config={},
88
     config={},
81
 applications = [
93
 applications = [
82
     htmlpage,
94
     htmlpage,
83
     markdownpluspage,
95
     markdownpluspage,
84
-    file,
96
+    _file,
85
     thread,
97
     thread,
86
     calendar,
98
     calendar,
87
 ]
99
 ]

+ 9 - 8
tracim/models/data.py View File

162
     #
162
     #
163
     #
163
     #
164
     # @property
164
     # @property
165
-    # def icon(self):
165
+    # def fa_icon(self):
166
     #     return UserRoleInWorkspace.ICON[self.role]
166
     #     return UserRoleInWorkspace.ICON[self.role]
167
     #
167
     #
168
     # @property
168
     # @property
200
     def __init__(self, role_id):
200
     def __init__(self, role_id):
201
         self.role_type_id = role_id
201
         self.role_type_id = role_id
202
         # TODO - G.M - 10-04-2018 - [Cleanup] Drop this
202
         # TODO - G.M - 10-04-2018 - [Cleanup] Drop this
203
-        # self.icon = UserRoleInWorkspace.ICON[role_id]
203
+        # self.fa_icon = UserRoleInWorkspace.ICON[role_id]
204
         # self.role_label = UserRoleInWorkspace.LABEL[role_id]
204
         # self.role_label = UserRoleInWorkspace.LABEL[role_id]
205
         # self.css_style = UserRoleInWorkspace.STYLE[role_id]
205
         # self.css_style = UserRoleInWorkspace.STYLE[role_id]
206
 
206
 
265
     def __init__(self, id):
265
     def __init__(self, id):
266
         assert id in ActionDescription.allowed_values()
266
         assert id in ActionDescription.allowed_values()
267
         self.id = id
267
         self.id = id
268
-        # FIXME - G.M - 17-04-2018 - Label and icon needed for webdav
268
+        # FIXME - G.M - 17-04-2018 - Label and fa_icon needed for webdav
269
         #  design template,
269
         #  design template,
270
         # find a way to not rely on this.
270
         # find a way to not rely on this.
271
         self.label = self.id
271
         self.label = self.id
272
-        self.icon = ActionDescription._ICONS[id]
272
+        self.fa_icon = ActionDescription._ICONS[id]
273
+        #self.icon = self.fa_icon
273
         # TODO - G.M - 10-04-2018 - [Cleanup] Drop this
274
         # TODO - G.M - 10-04-2018 - [Cleanup] Drop this
274
         # self.label = ActionDescription._LABELS[id]
275
         # self.label = ActionDescription._LABELS[id]
275
 
276
 
343
         self.id = id
344
         self.id = id
344
         self.label = self.id
345
         self.label = self.id
345
         # TODO - G.M - 10-04-2018 - [Cleanup] Drop this
346
         # TODO - G.M - 10-04-2018 - [Cleanup] Drop this
346
-        # self.icon = ContentStatus._ICONS[id]
347
+        # self.fa_icon = ContentStatus._ICONS[id]
347
         # self.css = ContentStatus._CSS[id]
348
         # self.css = ContentStatus._CSS[id]
348
         #
349
         #
349
         # if type==ContentType.Thread:
350
         # if type==ContentType.Thread:
520
     def __init__(self, type):
521
     def __init__(self, type):
521
         self.id = type
522
         self.id = type
522
         # TODO - G.M - 10-04-2018 - [Cleanup] Drop this
523
         # TODO - G.M - 10-04-2018 - [Cleanup] Drop this
523
-        # self.icon = ContentType._CSS_ICONS[type]
524
+        # self.fa_icon = ContentType._CSS_ICONS[type]
524
         # self.color = ContentType._CSS_COLORS[type]  # deprecated
525
         # self.color = ContentType._CSS_COLORS[type]  # deprecated
525
         # self.css = ContentType._CSS_COLORS[type]
526
         # self.css = ContentType._CSS_COLORS[type]
526
         # self.label = ContentType._LABEL[type]
527
         # self.label = ContentType._LABEL[type]
530
         return dict(id=self.type,
531
         return dict(id=self.type,
531
                     type=self.type,
532
                     type=self.type,
532
                     # TODO - G.M - 10-04-2018 - [Cleanup] Drop this
533
                     # TODO - G.M - 10-04-2018 - [Cleanup] Drop this
533
-                    # icon=self.icon,
534
+                    # fa_icon=self.fa_icon,
534
                     # color=self.color,
535
                     # color=self.color,
535
                     # label=self.label,
536
                     # label=self.label,
536
                     priority=self.priority)
537
                     priority=self.priority)
1457
         assert hasattr(type, 'id')
1458
         assert hasattr(type, 'id')
1458
         # TODO - G.M - 10-04-2018 - [Cleanup] Drop this
1459
         # TODO - G.M - 10-04-2018 - [Cleanup] Drop this
1459
         # assert hasattr(type, 'css')
1460
         # assert hasattr(type, 'css')
1460
-        # assert hasattr(type, 'icon')
1461
+        # assert hasattr(type, 'fa_icon')
1461
         # assert hasattr(type, 'label')
1462
         # assert hasattr(type, 'label')
1462
 
1463
 
1463
     def created_as_delta(self, delta_from_datetime:datetime=None):
1464
     def created_as_delta(self, delta_from_datetime:datetime=None):

+ 5 - 5
tracim/models/workspace_menu_entries.py View File

14
             self,
14
             self,
15
             label: str,
15
             label: str,
16
             slug: str,
16
             slug: str,
17
-            icon: str,
17
+            fa_icon: str,
18
             hexcolor: str,
18
             hexcolor: str,
19
             route: str,
19
             route: str,
20
     ) -> None:
20
     ) -> None:
22
         self.label = label
22
         self.label = label
23
         self.route = route
23
         self.route = route
24
         self.hexcolor = hexcolor
24
         self.hexcolor = hexcolor
25
-        self.icon = icon
25
+        self.fa_icon = fa_icon
26
 
26
 
27
 dashboard_menu_entry = WorkspaceMenuEntry(
27
 dashboard_menu_entry = WorkspaceMenuEntry(
28
   slug='dashboard',
28
   slug='dashboard',
29
   label='Dashboard',
29
   label='Dashboard',
30
   route='/#/workspaces/{workspace_id}/dashboard',
30
   route='/#/workspaces/{workspace_id}/dashboard',
31
   hexcolor='#252525',
31
   hexcolor='#252525',
32
-  icon="",
32
+  fa_icon="",
33
 )
33
 )
34
 all_content_menu_entry = WorkspaceMenuEntry(
34
 all_content_menu_entry = WorkspaceMenuEntry(
35
   slug="contents/all",
35
   slug="contents/all",
36
   label="All Contents",
36
   label="All Contents",
37
   route="/#/workspaces/{workspace_id}/contents",
37
   route="/#/workspaces/{workspace_id}/contents",
38
   hexcolor="#fdfdfd",
38
   hexcolor="#fdfdfd",
39
-  icon="",
39
+  fa_icon="",
40
 )
40
 )
41
 
41
 
42
 # TODO - G.M - 08-06-2018 - This is hardcoded default menu entry,
42
 # TODO - G.M - 08-06-2018 - This is hardcoded default menu entry,
57
                 slug=app.slug,
57
                 slug=app.slug,
58
                 label=app.label,
58
                 label=app.label,
59
                 hexcolor=app.hexcolor,
59
                 hexcolor=app.hexcolor,
60
-                icon=app.icon,
60
+                fa_icon=app.fa_icon,
61
                 route=app.main_route
61
                 route=app.main_route
62
             )
62
             )
63
             menu_entries.append(new_entry)
63
             menu_entries.append(new_entry)

+ 5 - 6
tracim/templates/mail/content_update_body_html.mak View File

38
     <table style="width: 100%; cell-padding: 0; border-collapse: collapse; margin: 0">
38
     <table style="width: 100%; cell-padding: 0; border-collapse: collapse; margin: 0">
39
       <tr style="background-color: F5F5F5; border-bottom: 1px solid #CCC;" >
39
       <tr style="background-color: F5F5F5; border-bottom: 1px solid #CCC;" >
40
         <td style="background-color: #666;">
40
         <td style="background-color: #666;">
41
-            <!-- FIXME - G.M - 09-06-2018 - restore logo -->
41
+            <img alt="logo" src="${logo_url}" style="vertical-align: middle;">
42
         </td>
42
         </td>
43
         <td style="padding: 0.5em; background-color: #666; text-align: left;">
43
         <td style="padding: 0.5em; background-color: #666; text-align: left;">
44
           <span style="font-size: 1.3em; color: #FFF; font-weight: bold;">
44
           <span style="font-size: 1.3em; color: #FFF; font-weight: bold;">
45
             ${main_title}
45
             ${main_title}
46
             &mdash;&nbsp;<span style="font-weight: bold; color: #999; font-weight: bold;">
46
             &mdash;&nbsp;<span style="font-weight: bold; color: #999; font-weight: bold;">
47
-              ${status|n}
48
-              <!-- FIXME - G.M - 09-06-2018 - restore icon -->
47
+              ${status_label|n}
48
+              <img alt="status_icon" src="${status_icon_url}" style="vertical-align: middle;">
49
             </span>
49
             </span>
50
         </td>
50
         </td>
51
       </tr>
51
       </tr>
54
     <p id="content-intro">${content_intro|n}</p>
54
     <p id="content-intro">${content_intro|n}</p>
55
     <div id="content-body">
55
     <div id="content-body">
56
         <div>${content_text|n}</div>
56
         <div>${content_text|n}</div>
57
-        <!-- FIXME - G.M - 09-06-2018 - fix action url -->
58
         <div href='' id="call-to-action-container">
57
         <div href='' id="call-to-action-container">
59
         </div>
58
         </div>
60
     </div>
59
     </div>
61
     
60
     
62
     <div id="footer">
61
     <div id="footer">
63
         <p>
62
         <p>
64
-            <!-- FIXME - G.M - 09-06-2018 - Set correct workspace url -->
65
-            ${_('{user_display_name}, you receive this email because you are registered on <i>{website_title}</i> and you are <i>{user_role_label}</i> in the workspace <a href="{workspace_url}">{workspace_label}</a>.').format(user_display_name=user.display_name, user_role_label=role, workspace_url='', workspace_label=workspace.label, website_title=config.WEBSITE_TITLE)|n}
63
+
64
+            ${_('{user_display_name}, you receive this email because you are registered on <i>{website_title}</i> and you are <i>{user_role_label}</i> in the workspace <a href="{workspace_url}">{workspace_label}</a>.').format(user_display_name=user.display_name, user_role_label=role_label, workspace_url=workspace_url, workspace_label=workspace.label, website_title=config.WEBSITE_TITLE)|n}
66
         </p>
65
         </p>
67
         <hr/>
66
         <hr/>
68
         <p>
67
         <p>

+ 1 - 1
tracim/templates/mail/content_update_body_text.mak View File

16
 
16
 
17
 
17
 
18
 You receive this email because you are registered on /${config.WEBSITE_TITLE}/
18
 You receive this email because you are registered on /${config.WEBSITE_TITLE}/
19
-and you are /${role}/ in the workspace /${workspace.label}/
19
+and you are /${role_label}/ in the workspace /${workspace.label}/
20
 
20
 
21
 ----
21
 ----
22
 
22
 

+ 1 - 1
tracim/templates/mail/created_account_body_html.mak View File

38
     <table style="width: 100%; cell-padding: 0; border-collapse: collapse; margin: 0">
38
     <table style="width: 100%; cell-padding: 0; border-collapse: collapse; margin: 0">
39
       <tr style="background-color: F5F5F5; border-bottom: 1px solid #CCC;" >
39
       <tr style="background-color: F5F5F5; border-bottom: 1px solid #CCC;" >
40
         <td style="background-color: #666;">
40
         <td style="background-color: #666;">
41
-            <!-- FIXME - G.M - 09-06-2018 - restore logo -->
41
+            <img alt="logo" src="${logo_url}" style="vertical-align: middle;">
42
         </td>
42
         </td>
43
         <td style="padding: 0.5em; background-color: #666; text-align: left;">
43
         <td style="padding: 0.5em; background-color: #666; text-align: left;">
44
           <span style="font-size: 1.3em; color: #FFF; font-weight: bold;">
44
           <span style="font-size: 1.3em; color: #FFF; font-weight: bold;">

+ 5 - 5
tracim/tests/functional/test_system.py View File

26
         application = res[0]
26
         application = res[0]
27
         assert application['label'] == "Text Documents"
27
         assert application['label'] == "Text Documents"
28
         assert application['slug'] == 'contents/htmlpage'
28
         assert application['slug'] == 'contents/htmlpage'
29
-        assert application['icon'] == 'file-text-o'
29
+        assert application['fa_icon'] == 'file-text-o'
30
         assert application['hexcolor'] == '#3f52e3'
30
         assert application['hexcolor'] == '#3f52e3'
31
         assert application['is_active'] is True
31
         assert application['is_active'] is True
32
         assert 'config' in application
32
         assert 'config' in application
33
         application = res[1]
33
         application = res[1]
34
         assert application['label'] == "Markdown Plus Documents"
34
         assert application['label'] == "Markdown Plus Documents"
35
         assert application['slug'] == 'contents/markdownpluspage'
35
         assert application['slug'] == 'contents/markdownpluspage'
36
-        assert application['icon'] == 'file-code'
36
+        assert application['fa_icon'] == 'file-code'
37
         assert application['hexcolor'] == '#f12d2d'
37
         assert application['hexcolor'] == '#f12d2d'
38
         assert application['is_active'] is True
38
         assert application['is_active'] is True
39
         assert 'config' in application
39
         assert 'config' in application
40
         application = res[2]
40
         application = res[2]
41
         assert application['label'] == "Files"
41
         assert application['label'] == "Files"
42
         assert application['slug'] == 'contents/files'
42
         assert application['slug'] == 'contents/files'
43
-        assert application['icon'] == 'paperclip'
43
+        assert application['fa_icon'] == 'paperclip'
44
         assert application['hexcolor'] == '#FF9900'
44
         assert application['hexcolor'] == '#FF9900'
45
         assert application['is_active'] is True
45
         assert application['is_active'] is True
46
         assert 'config' in application
46
         assert 'config' in application
47
         application = res[3]
47
         application = res[3]
48
         assert application['label'] == "Threads"
48
         assert application['label'] == "Threads"
49
         assert application['slug'] == 'contents/threads'
49
         assert application['slug'] == 'contents/threads'
50
-        assert application['icon'] == 'comments-o'
50
+        assert application['fa_icon'] == 'comments-o'
51
         assert application['hexcolor'] == '#ad4cf9'
51
         assert application['hexcolor'] == '#ad4cf9'
52
         assert application['is_active'] is True
52
         assert application['is_active'] is True
53
         assert 'config' in application
53
         assert 'config' in application
54
         application = res[4]
54
         application = res[4]
55
         assert application['label'] == "Calendar"
55
         assert application['label'] == "Calendar"
56
         assert application['slug'] == 'calendar'
56
         assert application['slug'] == 'calendar'
57
-        assert application['icon'] == 'calendar-alt'
57
+        assert application['fa_icon'] == 'calendar-alt'
58
         assert application['hexcolor'] == '#757575'
58
         assert application['hexcolor'] == '#757575'
59
         assert application['is_active'] is True
59
         assert application['is_active'] is True
60
         assert 'config' in application
60
         assert 'config' in application

+ 7 - 7
tracim/tests/functional/test_user.py View File

37
         assert sidebar_entry['label'] == 'Dashboard'
37
         assert sidebar_entry['label'] == 'Dashboard'
38
         assert sidebar_entry['route'] == '/#/workspaces/1/dashboard'  # nopep8
38
         assert sidebar_entry['route'] == '/#/workspaces/1/dashboard'  # nopep8
39
         assert sidebar_entry['hexcolor'] == "#252525"
39
         assert sidebar_entry['hexcolor'] == "#252525"
40
-        assert sidebar_entry['icon'] == ""
40
+        assert sidebar_entry['fa_icon'] == ""
41
 
41
 
42
         sidebar_entry = workspace['sidebar_entries'][1]
42
         sidebar_entry = workspace['sidebar_entries'][1]
43
         assert sidebar_entry['slug'] == 'contents/all'
43
         assert sidebar_entry['slug'] == 'contents/all'
44
         assert sidebar_entry['label'] == 'All Contents'
44
         assert sidebar_entry['label'] == 'All Contents'
45
         assert sidebar_entry['route'] == "/#/workspaces/1/contents"  # nopep8
45
         assert sidebar_entry['route'] == "/#/workspaces/1/contents"  # nopep8
46
         assert sidebar_entry['hexcolor'] == "#fdfdfd"
46
         assert sidebar_entry['hexcolor'] == "#fdfdfd"
47
-        assert sidebar_entry['icon'] == ""
47
+        assert sidebar_entry['fa_icon'] == ""
48
 
48
 
49
         sidebar_entry = workspace['sidebar_entries'][2]
49
         sidebar_entry = workspace['sidebar_entries'][2]
50
         assert sidebar_entry['slug'] == 'contents/htmlpage'
50
         assert sidebar_entry['slug'] == 'contents/htmlpage'
51
         assert sidebar_entry['label'] == 'Text Documents'
51
         assert sidebar_entry['label'] == 'Text Documents'
52
         assert sidebar_entry['route'] == '/#/workspaces/1/contents?type=htmlpage'  # nopep8
52
         assert sidebar_entry['route'] == '/#/workspaces/1/contents?type=htmlpage'  # nopep8
53
         assert sidebar_entry['hexcolor'] == "#3f52e3"
53
         assert sidebar_entry['hexcolor'] == "#3f52e3"
54
-        assert sidebar_entry['icon'] == "file-text-o"
54
+        assert sidebar_entry['fa_icon'] == "file-text-o"
55
 
55
 
56
         sidebar_entry = workspace['sidebar_entries'][3]
56
         sidebar_entry = workspace['sidebar_entries'][3]
57
         assert sidebar_entry['slug'] == 'contents/markdownpluspage'
57
         assert sidebar_entry['slug'] == 'contents/markdownpluspage'
58
         assert sidebar_entry['label'] == 'Markdown Plus Documents'
58
         assert sidebar_entry['label'] == 'Markdown Plus Documents'
59
         assert sidebar_entry['route'] == "/#/workspaces/1/contents?type=markdownpluspage"    # nopep8
59
         assert sidebar_entry['route'] == "/#/workspaces/1/contents?type=markdownpluspage"    # nopep8
60
         assert sidebar_entry['hexcolor'] == "#f12d2d"
60
         assert sidebar_entry['hexcolor'] == "#f12d2d"
61
-        assert sidebar_entry['icon'] == "file-code"
61
+        assert sidebar_entry['fa_icon'] == "file-code"
62
 
62
 
63
         sidebar_entry = workspace['sidebar_entries'][4]
63
         sidebar_entry = workspace['sidebar_entries'][4]
64
         assert sidebar_entry['slug'] == 'contents/files'
64
         assert sidebar_entry['slug'] == 'contents/files'
65
         assert sidebar_entry['label'] == 'Files'
65
         assert sidebar_entry['label'] == 'Files'
66
         assert sidebar_entry['route'] == "/#/workspaces/1/contents?type=file"  # nopep8
66
         assert sidebar_entry['route'] == "/#/workspaces/1/contents?type=file"  # nopep8
67
         assert sidebar_entry['hexcolor'] == "#FF9900"
67
         assert sidebar_entry['hexcolor'] == "#FF9900"
68
-        assert sidebar_entry['icon'] == "paperclip"
68
+        assert sidebar_entry['fa_icon'] == "paperclip"
69
 
69
 
70
         sidebar_entry = workspace['sidebar_entries'][5]
70
         sidebar_entry = workspace['sidebar_entries'][5]
71
         assert sidebar_entry['slug'] == 'contents/threads'
71
         assert sidebar_entry['slug'] == 'contents/threads'
72
         assert sidebar_entry['label'] == 'Threads'
72
         assert sidebar_entry['label'] == 'Threads'
73
         assert sidebar_entry['route'] == "/#/workspaces/1/contents?type=thread"  # nopep8
73
         assert sidebar_entry['route'] == "/#/workspaces/1/contents?type=thread"  # nopep8
74
         assert sidebar_entry['hexcolor'] == "#ad4cf9"
74
         assert sidebar_entry['hexcolor'] == "#ad4cf9"
75
-        assert sidebar_entry['icon'] == "comments-o"
75
+        assert sidebar_entry['fa_icon'] == "comments-o"
76
 
76
 
77
         sidebar_entry = workspace['sidebar_entries'][6]
77
         sidebar_entry = workspace['sidebar_entries'][6]
78
         assert sidebar_entry['slug'] == 'calendar'
78
         assert sidebar_entry['slug'] == 'calendar'
79
         assert sidebar_entry['label'] == 'Calendar'
79
         assert sidebar_entry['label'] == 'Calendar'
80
         assert sidebar_entry['route'] == "/#/workspaces/1/calendar"  # nopep8
80
         assert sidebar_entry['route'] == "/#/workspaces/1/calendar"  # nopep8
81
         assert sidebar_entry['hexcolor'] == "#757575"
81
         assert sidebar_entry['hexcolor'] == "#757575"
82
-        assert sidebar_entry['icon'] == "calendar-alt"
82
+        assert sidebar_entry['fa_icon'] == "calendar-alt"
83
 
83
 
84
     def test_api__get_user_workspaces__err_403__unallowed_user(self):
84
     def test_api__get_user_workspaces__err_403__unallowed_user(self):
85
         """
85
         """

+ 7 - 7
tracim/tests/functional/test_workspaces.py View File

38
         assert sidebar_entry['label'] == 'Dashboard'
38
         assert sidebar_entry['label'] == 'Dashboard'
39
         assert sidebar_entry['route'] == '/#/workspaces/1/dashboard'  # nopep8
39
         assert sidebar_entry['route'] == '/#/workspaces/1/dashboard'  # nopep8
40
         assert sidebar_entry['hexcolor'] == "#252525"
40
         assert sidebar_entry['hexcolor'] == "#252525"
41
-        assert sidebar_entry['icon'] == ""
41
+        assert sidebar_entry['fa_icon'] == ""
42
 
42
 
43
         sidebar_entry = workspace['sidebar_entries'][1]
43
         sidebar_entry = workspace['sidebar_entries'][1]
44
         assert sidebar_entry['slug'] == 'contents/all'
44
         assert sidebar_entry['slug'] == 'contents/all'
45
         assert sidebar_entry['label'] == 'All Contents'
45
         assert sidebar_entry['label'] == 'All Contents'
46
         assert sidebar_entry['route'] == "/#/workspaces/1/contents"  # nopep8
46
         assert sidebar_entry['route'] == "/#/workspaces/1/contents"  # nopep8
47
         assert sidebar_entry['hexcolor'] == "#fdfdfd"
47
         assert sidebar_entry['hexcolor'] == "#fdfdfd"
48
-        assert sidebar_entry['icon'] == ""
48
+        assert sidebar_entry['fa_icon'] == ""
49
 
49
 
50
         sidebar_entry = workspace['sidebar_entries'][2]
50
         sidebar_entry = workspace['sidebar_entries'][2]
51
         assert sidebar_entry['slug'] == 'contents/htmlpage'
51
         assert sidebar_entry['slug'] == 'contents/htmlpage'
52
         assert sidebar_entry['label'] == 'Text Documents'
52
         assert sidebar_entry['label'] == 'Text Documents'
53
         assert sidebar_entry['route'] == '/#/workspaces/1/contents?type=htmlpage'  # nopep8
53
         assert sidebar_entry['route'] == '/#/workspaces/1/contents?type=htmlpage'  # nopep8
54
         assert sidebar_entry['hexcolor'] == "#3f52e3"
54
         assert sidebar_entry['hexcolor'] == "#3f52e3"
55
-        assert sidebar_entry['icon'] == "file-text-o"
55
+        assert sidebar_entry['fa_icon'] == "file-text-o"
56
 
56
 
57
         sidebar_entry = workspace['sidebar_entries'][3]
57
         sidebar_entry = workspace['sidebar_entries'][3]
58
         assert sidebar_entry['slug'] == 'contents/markdownpluspage'
58
         assert sidebar_entry['slug'] == 'contents/markdownpluspage'
59
         assert sidebar_entry['label'] == 'Markdown Plus Documents'
59
         assert sidebar_entry['label'] == 'Markdown Plus Documents'
60
         assert sidebar_entry['route'] == "/#/workspaces/1/contents?type=markdownpluspage"    # nopep8
60
         assert sidebar_entry['route'] == "/#/workspaces/1/contents?type=markdownpluspage"    # nopep8
61
         assert sidebar_entry['hexcolor'] == "#f12d2d"
61
         assert sidebar_entry['hexcolor'] == "#f12d2d"
62
-        assert sidebar_entry['icon'] == "file-code"
62
+        assert sidebar_entry['fa_icon'] == "file-code"
63
 
63
 
64
         sidebar_entry = workspace['sidebar_entries'][4]
64
         sidebar_entry = workspace['sidebar_entries'][4]
65
         assert sidebar_entry['slug'] == 'contents/files'
65
         assert sidebar_entry['slug'] == 'contents/files'
66
         assert sidebar_entry['label'] == 'Files'
66
         assert sidebar_entry['label'] == 'Files'
67
         assert sidebar_entry['route'] == "/#/workspaces/1/contents?type=file"  # nopep8
67
         assert sidebar_entry['route'] == "/#/workspaces/1/contents?type=file"  # nopep8
68
         assert sidebar_entry['hexcolor'] == "#FF9900"
68
         assert sidebar_entry['hexcolor'] == "#FF9900"
69
-        assert sidebar_entry['icon'] == "paperclip"
69
+        assert sidebar_entry['fa_icon'] == "paperclip"
70
 
70
 
71
         sidebar_entry = workspace['sidebar_entries'][5]
71
         sidebar_entry = workspace['sidebar_entries'][5]
72
         assert sidebar_entry['slug'] == 'contents/threads'
72
         assert sidebar_entry['slug'] == 'contents/threads'
73
         assert sidebar_entry['label'] == 'Threads'
73
         assert sidebar_entry['label'] == 'Threads'
74
         assert sidebar_entry['route'] == "/#/workspaces/1/contents?type=thread"  # nopep8
74
         assert sidebar_entry['route'] == "/#/workspaces/1/contents?type=thread"  # nopep8
75
         assert sidebar_entry['hexcolor'] == "#ad4cf9"
75
         assert sidebar_entry['hexcolor'] == "#ad4cf9"
76
-        assert sidebar_entry['icon'] == "comments-o"
76
+        assert sidebar_entry['fa_icon'] == "comments-o"
77
 
77
 
78
         sidebar_entry = workspace['sidebar_entries'][6]
78
         sidebar_entry = workspace['sidebar_entries'][6]
79
         assert sidebar_entry['slug'] == 'calendar'
79
         assert sidebar_entry['slug'] == 'calendar'
80
         assert sidebar_entry['label'] == 'Calendar'
80
         assert sidebar_entry['label'] == 'Calendar'
81
         assert sidebar_entry['route'] == "/#/workspaces/1/calendar"  # nopep8
81
         assert sidebar_entry['route'] == "/#/workspaces/1/calendar"  # nopep8
82
         assert sidebar_entry['hexcolor'] == "#757575"
82
         assert sidebar_entry['hexcolor'] == "#757575"
83
-        assert sidebar_entry['icon'] == "calendar-alt"
83
+        assert sidebar_entry['fa_icon'] == "calendar-alt"
84
 
84
 
85
     def test_api__get_workspace__err_403__unallowed_user(self) -> None:
85
     def test_api__get_workspace__err_403__unallowed_user(self) -> None:
86
         """
86
         """

+ 2 - 2
tracim/views/core_api/schemas.py View File

114
                     'which must be replaced on backend size '
114
                     'which must be replaced on backend size '
115
                     '(the route must be ready-to-use)'
115
                     '(the route must be ready-to-use)'
116
     )
116
     )
117
-    icon = marshmallow.fields.String(
117
+    fa_icon = marshmallow.fields.String(
118
         example='file-text-o',
118
         example='file-text-o',
119
         description='CSS class of the icon. Example: file-o for using Fontawesome file-text-o icon',  # nopep8
119
         description='CSS class of the icon. Example: file-o for using Fontawesome file-text-o icon',  # nopep8
120
     )
120
     )
170
 class ApplicationSchema(marshmallow.Schema):
170
 class ApplicationSchema(marshmallow.Schema):
171
     label = marshmallow.fields.String(example='Calendar')
171
     label = marshmallow.fields.String(example='Calendar')
172
     slug = marshmallow.fields.String(example='calendar')
172
     slug = marshmallow.fields.String(example='calendar')
173
-    icon = marshmallow.fields.String(
173
+    fa_icon = marshmallow.fields.String(
174
         example='file-o',
174
         example='file-o',
175
         description='CSS class of the icon. Example: file-o for using Fontawesome file-o icon',  # nopep8
175
         description='CSS class of the icon. Example: file-o for using Fontawesome file-o icon',  # nopep8
176
     )
176
     )

+ 2 - 2
tracim/views/core_api/session_controller.py View File

13
 from tracim.views.core_api.schemas import NoContentSchema
13
 from tracim.views.core_api.schemas import NoContentSchema
14
 from tracim.views.core_api.schemas import LoginOutputHeaders
14
 from tracim.views.core_api.schemas import LoginOutputHeaders
15
 from tracim.views.core_api.schemas import BasicAuthSchema
15
 from tracim.views.core_api.schemas import BasicAuthSchema
16
-from tracim.exceptions import NotAuthentificated
16
+from tracim.exceptions import NotAuthenticated
17
 from tracim.exceptions import AuthenticationFailed
17
 from tracim.exceptions import AuthenticationFailed
18
 
18
 
19
 
19
 
52
         return
52
         return
53
 
53
 
54
     @hapic.with_api_doc()
54
     @hapic.with_api_doc()
55
-    @hapic.handle_exception(NotAuthentificated, HTTPStatus.UNAUTHORIZED)
55
+    @hapic.handle_exception(NotAuthenticated, HTTPStatus.UNAUTHORIZED)
56
     @hapic.output_body(UserSchema(),)
56
     @hapic.output_body(UserSchema(),)
57
     def whoami(self, context, request: TracimRequest, hapic_data=None):
57
     def whoami(self, context, request: TracimRequest, hapic_data=None):
58
         """
58
         """

+ 2 - 2
tracim/views/core_api/system_controller.py View File

1
 # coding=utf-8
1
 # coding=utf-8
2
 from pyramid.config import Configurator
2
 from pyramid.config import Configurator
3
 
3
 
4
-from tracim.exceptions import NotAuthentificated, InsufficientUserProfile
4
+from tracim.exceptions import NotAuthenticated, InsufficientUserProfile
5
 from tracim.lib.utils.authorization import require_profile
5
 from tracim.lib.utils.authorization import require_profile
6
 from tracim.models import Group
6
 from tracim.models import Group
7
 from tracim.models.applications import applications
7
 from tracim.models.applications import applications
20
 class SystemController(Controller):
20
 class SystemController(Controller):
21
 
21
 
22
     @hapic.with_api_doc()
22
     @hapic.with_api_doc()
23
-    @hapic.handle_exception(NotAuthentificated, HTTPStatus.UNAUTHORIZED)
23
+    @hapic.handle_exception(NotAuthenticated, HTTPStatus.UNAUTHORIZED)
24
     @hapic.handle_exception(InsufficientUserProfile, HTTPStatus.FORBIDDEN)
24
     @hapic.handle_exception(InsufficientUserProfile, HTTPStatus.FORBIDDEN)
25
     @require_profile(Group.TIM_USER)
25
     @require_profile(Group.TIM_USER)
26
     @hapic.output_body(ApplicationSchema(many=True),)
26
     @hapic.output_body(ApplicationSchema(many=True),)

+ 2 - 2
tracim/views/core_api/user_controller.py View File

12
 
12
 
13
 from tracim import hapic, TracimRequest
13
 from tracim import hapic, TracimRequest
14
 
14
 
15
-from tracim.exceptions import NotAuthentificated
15
+from tracim.exceptions import NotAuthenticated
16
 from tracim.exceptions import InsufficientUserProfile
16
 from tracim.exceptions import InsufficientUserProfile
17
 from tracim.exceptions import UserDoesNotExist
17
 from tracim.exceptions import UserDoesNotExist
18
 from tracim.lib.core.workspace import WorkspaceApi
18
 from tracim.lib.core.workspace import WorkspaceApi
24
 class UserController(Controller):
24
 class UserController(Controller):
25
 
25
 
26
     @hapic.with_api_doc()
26
     @hapic.with_api_doc()
27
-    @hapic.handle_exception(NotAuthentificated, HTTPStatus.UNAUTHORIZED)
27
+    @hapic.handle_exception(NotAuthenticated, HTTPStatus.UNAUTHORIZED)
28
     @hapic.handle_exception(InsufficientUserProfile, HTTPStatus.FORBIDDEN)
28
     @hapic.handle_exception(InsufficientUserProfile, HTTPStatus.FORBIDDEN)
29
     @hapic.handle_exception(UserDoesNotExist, HTTPStatus.NOT_FOUND)
29
     @hapic.handle_exception(UserDoesNotExist, HTTPStatus.NOT_FOUND)
30
     @require_same_user_or_profile(Group.TIM_ADMIN)
30
     @require_same_user_or_profile(Group.TIM_ADMIN)

+ 3 - 3
tracim/views/core_api/workspace_controller.py View File

15
     from http import client as HTTPStatus
15
     from http import client as HTTPStatus
16
 
16
 
17
 from tracim import hapic, TracimRequest
17
 from tracim import hapic, TracimRequest
18
-from tracim.exceptions import NotAuthentificated
18
+from tracim.exceptions import NotAuthenticated
19
 from tracim.exceptions import InsufficientUserProfile
19
 from tracim.exceptions import InsufficientUserProfile
20
 from tracim.exceptions import WorkspaceNotFound
20
 from tracim.exceptions import WorkspaceNotFound
21
 from tracim.lib.core.user import UserApi
21
 from tracim.lib.core.user import UserApi
29
 class WorkspaceController(Controller):
29
 class WorkspaceController(Controller):
30
 
30
 
31
     @hapic.with_api_doc()
31
     @hapic.with_api_doc()
32
-    @hapic.handle_exception(NotAuthentificated, HTTPStatus.UNAUTHORIZED)
32
+    @hapic.handle_exception(NotAuthenticated, HTTPStatus.UNAUTHORIZED)
33
     @hapic.handle_exception(InsufficientUserProfile, HTTPStatus.FORBIDDEN)
33
     @hapic.handle_exception(InsufficientUserProfile, HTTPStatus.FORBIDDEN)
34
     @hapic.handle_exception(WorkspaceNotFound, HTTPStatus.FORBIDDEN)
34
     @hapic.handle_exception(WorkspaceNotFound, HTTPStatus.FORBIDDEN)
35
     @require_workspace_role(UserRoleInWorkspace.READER)
35
     @require_workspace_role(UserRoleInWorkspace.READER)
49
         return wapi.get_workspace_with_context(request.current_workspace)
49
         return wapi.get_workspace_with_context(request.current_workspace)
50
 
50
 
51
     @hapic.with_api_doc()
51
     @hapic.with_api_doc()
52
-    @hapic.handle_exception(NotAuthentificated, HTTPStatus.UNAUTHORIZED)
52
+    @hapic.handle_exception(NotAuthenticated, HTTPStatus.UNAUTHORIZED)
53
     @hapic.handle_exception(InsufficientUserProfile, HTTPStatus.FORBIDDEN)
53
     @hapic.handle_exception(InsufficientUserProfile, HTTPStatus.FORBIDDEN)
54
     @hapic.handle_exception(WorkspaceNotFound, HTTPStatus.FORBIDDEN)
54
     @hapic.handle_exception(WorkspaceNotFound, HTTPStatus.FORBIDDEN)
55
     @require_workspace_role(UserRoleInWorkspace.READER)
55
     @require_workspace_role(UserRoleInWorkspace.READER)