Skip to content
This repository was archived by the owner on Jun 1, 2022. It is now read-only.

Commit 449a460

Browse files
committed
Merge pull request #293 from editorsnotes/auth-forms
Auth forms
2 parents f92b8e1 + 292a560 commit 449a460

27 files changed

+640
-181
lines changed

editorsnotes/api/fields.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ def __init__(self, *args, **kwargs):
8989
'pk': 'id'
9090
}
9191
kwargs['read_only'] = True
92+
self.format = None
9293
super(IdentityURLField, self).__init__(*args, **kwargs)
9394

9495

editorsnotes/api/ld.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
('@id', '@graph'),
2626
('@container', '@index'),
2727
))),
28-
('display_name', 'schame:name'),
28+
('display_name', 'schema:name'),
2929
('embedded', OrderedDict((
3030
('@id', '@graph'),
3131
('@container', '@index'),

editorsnotes/api/serializers/activity.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414

1515
# TODO: make these fields nested, maybe
1616
class ActivitySerializer(serializers.ModelSerializer):
17-
user = serializers.ReadOnlyField(source='user.username')
17+
user_id = serializers.ReadOnlyField(source='user.id')
1818
project = serializers.ReadOnlyField(source='project.slug')
1919
type = serializers.ReadOnlyField(source='content_type.model')
2020
url = serializers.SerializerMethodField('get_object_url')
@@ -23,7 +23,7 @@ class ActivitySerializer(serializers.ModelSerializer):
2323

2424
class Meta:
2525
model = LogActivity
26-
fields = ('user', 'project', 'time', 'type', 'url', 'title', 'action',)
26+
fields = ('user_id', 'project', 'time', 'type', 'url', 'title', 'action',)
2727

2828
def get_object_url(self, obj):
2929
if obj.action == DELETION or obj.content_object is None:

editorsnotes/api/serializers/auth.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ def get_type(self, obj):
7373
class UserSerializer(EmbeddedItemsMixin, serializers.ModelSerializer):
7474
url = IdentityURLField(
7575
view_name='api:users-detail',
76-
lookup_kwarg_attrs={'username': 'username'}
76+
lookup_kwarg_attrs={'pk': 'pk'}
7777
)
7878

7979
type = serializers.SerializerMethodField()
@@ -91,8 +91,8 @@ class UserSerializer(EmbeddedItemsMixin, serializers.ModelSerializer):
9191
source='*',
9292
read_only=True,
9393
view_name='api:users-activity',
94-
lookup_field='username',
95-
lookup_url_kwarg='username'
94+
lookup_field='pk',
95+
lookup_url_kwarg='pk'
9696
)
9797

9898
class Meta:

editorsnotes/api/serializers/mixins.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,12 +50,12 @@ def get_users_from_urls(self, urls):
5050
if not urls:
5151
return {}
5252

53-
usernames = [
54-
resolve(urlparse(url).path).kwargs['username']
53+
user_ids = [
54+
resolve(urlparse(url).path).kwargs['id']
5555
for url in urls
5656
]
5757

58-
qs = User.objects.filter(username__in=usernames)
58+
qs = User.objects.filter(id__in=user_ids)
5959

6060
serializer = UserSerializer(instance=qs, many=True,
6161
context=self.context)

editorsnotes/api/tests/hydra.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ def test_read_only_hyperlinked_collection_property(self):
140140

141141
def test_read_write_hyperlinked_collection_property(self):
142142
request = Request(make_dummy_request())
143-
request._user = User(username='Patrick', is_superuser=True)
143+
request._user = User(is_superuser=True)
144144

145145
context = {'request': request}
146146
serializer = ProjectSerializer(self.project, context=context)

editorsnotes/api/tests/ld.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ class HydraLinksTestCase(ClearContentTypesTransactionTestCase):
2424
fixtures = ['projects.json']
2525

2626
def setUp(self):
27-
self.user = User.objects.get(username='barry')
27+
self.user = User.objects.get(email='barry@example.com')
2828
self.project = Project.objects.get(slug='emma')
2929
self.note = Note.objects.create(
3030
title='A test note',
@@ -52,7 +52,7 @@ def test_authenticated_hydra_class_request(self):
5252
An authenticated request with sufficient permissions should know about
5353
"GET", "PUT", and "POST" operations on a project item.
5454
"""
55-
self.client.login(username='barry', password='barry')
55+
self.client.login(username='barry@example.com', password='barry')
5656

5757
response = self.client.get(
5858
reverse('api:notes-detail',
@@ -69,7 +69,7 @@ def test_authenticated_user_project_home(self):
6969
The project resource for an authenticated user should show links to
7070
add items to all projects.
7171
"""
72-
self.client.login(username='barry', password='barry')
72+
self.client.login(username='barry@example.com', password='barry')
7373
response = self.client.get(
7474
reverse('api:projects-detail', args=[self.project.slug]),
7575
HTTP_ACCEPT='application/json')
@@ -115,7 +115,7 @@ def test_authenticated_user_project_home(self):
115115
})
116116

117117
def test_authenticated_user_home(self):
118-
self.client.login(username='barry', password='barry')
118+
self.client.login(username='barry@example.com', password='barry')
119119
response = self.client.get('/', HTTP_ACCEPT='application/json')
120120

121121
project_url = self.dummy_req.build_absolute_uri(

editorsnotes/api/tests/views.py

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -105,9 +105,9 @@ class TopicAPITestCase(ClearContentTypesTransactionTestCase):
105105
fixtures = ['projects.json']
106106

107107
def setUp(self):
108-
self.user = User.objects.get(username='barry')
108+
self.user = User.objects.get(email='barry@example.com')
109109
self.project = Project.objects.get(slug='emma')
110-
self.client.login(username='barry', password='barry')
110+
self.client.login(username='barry@example.com', password='barry')
111111

112112
def create_test_topic(self):
113113
data = TEST_TOPIC.copy()
@@ -154,7 +154,7 @@ def test_topic_api_create(self):
154154

155155
# 'time': ???,
156156
expected = {
157-
'user': 'barry',
157+
'user_id': 1,
158158
'project': 'emma',
159159
'type': topic_obj._meta.model_name,
160160
'url': topic_obj.get_absolute_url(),
@@ -175,7 +175,7 @@ def test_topic_api_create(self):
175175
def test_topic_api_create_bad_permissions(self):
176176
"Creating a topic in an outside project is NOT OK"
177177
self.client.logout()
178-
self.client.login(username='esther', password='esther')
178+
self.client.login(username='esther@example.com', password='esther')
179179
response = self.client.post(
180180
reverse('api:topics-list', args=[self.project.slug]),
181181
json.dumps(TEST_TOPIC),
@@ -236,7 +236,7 @@ def test_topic_api_list(self):
236236
def test_topic_api_list_other_projects(self):
237237
"Other projects' topic lists should be viewable, even if logged out"
238238
self.client.logout()
239-
self.client.login(username='esther', password='esther')
239+
self.client.login(username='esther@example.com', password='esther')
240240
response = self.client.get(reverse('api:topics-list',
241241
args=[self.project.slug]),
242242
HTTP_ACCEPT='application/json')
@@ -283,7 +283,7 @@ def test_topic_api_update(self):
283283

284284
# 'time': ???,
285285
expected = {
286-
'user': 'barry',
286+
'user_id': 1,
287287
'project': 'emma',
288288
'type': updated_topic_obj._meta.model_name,
289289
'url': updated_topic_obj.get_absolute_url(),
@@ -303,7 +303,7 @@ def test_topic_api_update_bad_permissions(self):
303303
data['markup'] = u'a bad, garbage guy'
304304

305305
self.client.logout()
306-
self.client.login(username='esther', password='esther')
306+
self.client.login(username='esther@example.com', password='esther')
307307

308308
response = self.client.put(
309309
reverse('api:topics-detail',
@@ -352,7 +352,7 @@ def test_topic_api_delete(self):
352352

353353
# 'time': ???,
354354
expected = {
355-
'user': 'barry',
355+
'user_id': 1,
356356
'project': 'emma',
357357
'type': topic_obj._meta.model_name,
358358
'url': None,
@@ -367,7 +367,7 @@ def test_topic_api_delete_bad_permissions(self):
367367
"Deleting a topic in an outside project is NOT OK"
368368
topic_obj = create_topic(user=self.user, project=self.project)
369369
self.client.logout()
370-
self.client.login(username='esther', password='esther')
370+
self.client.login(username='esther@example.com', password='esther')
371371

372372
response = self.client.delete(
373373
reverse('api:topics-detail',
@@ -393,9 +393,9 @@ class DocumentAPITestCase(ClearContentTypesTransactionTestCase):
393393
fixtures = ['projects.json']
394394

395395
def setUp(self):
396-
self.user = User.objects.get(username='barry')
396+
self.user = User.objects.get(email='barry@example.com')
397397
self.project = Project.objects.get(slug='emma')
398-
self.client.login(username='barry', password='barry')
398+
self.client.login(username='barry@example.com', password='barry')
399399

400400
def create_test_document(self):
401401
data = TEST_DOCUMENT
@@ -426,7 +426,7 @@ def test_document_api_create_bad_permissions(self):
426426
"Creating a document in another project is NOT OK"
427427
data = TEST_DOCUMENT.copy()
428428
self.client.logout()
429-
self.client.login(username='esther', password='esther')
429+
self.client.login(username='esther@example.com', password='esther')
430430
response = self.client.post(
431431
reverse('api:documents-list', args=[self.project.slug]),
432432
json.dumps(data),
@@ -483,7 +483,7 @@ def test_document_api_list(self):
483483
original_response_content = response.data
484484

485485
self.client.logout()
486-
self.client.login(username='esther', password='esther')
486+
self.client.login(username='esther@example.com', password='esther')
487487
response = self.client.get(reverse('api:documents-list',
488488
args=[self.project.slug]),
489489
HTTP_ACCEPT='application/json')
@@ -533,7 +533,7 @@ def test_document_api_update_bad_permissions(self):
533533
document_obj = create_document(
534534
project=self.project, creator=self.user, last_updater=self.user)
535535
self.client.logout()
536-
self.client.login(username='esther', password='esther')
536+
self.client.login(username='esther@example.com', password='esther')
537537

538538
data = TEST_DOCUMENT.copy()
539539
data['description'] = u'a stupid book!!!!!!!'
@@ -581,7 +581,7 @@ def test_document_api_delete_bad_permissions(self):
581581
document_obj = create_document(
582582
project=self.project, creator=self.user, last_updater=self.user)
583583
self.client.logout()
584-
self.client.login(username='esther', password='esther')
584+
self.client.login(username='esther@example.com', password='esther')
585585
response = self.client.delete(
586586
reverse('api:documents-detail',
587587
args=[self.project.slug, document_obj.id]),
@@ -608,9 +608,9 @@ class NoteAPITestCase(ClearContentTypesTransactionTestCase):
608608
fixtures = ['projects.json']
609609

610610
def setUp(self):
611-
self.user = User.objects.get(username='barry')
611+
self.user = User.objects.get(email='barry@example.com')
612612
self.project = Project.objects.get(slug='emma')
613-
self.client.login(username='barry', password='barry')
613+
self.client.login(username='barry@example.com', password='barry')
614614

615615
def create_test_note(self):
616616
data = TEST_NOTE
@@ -670,7 +670,7 @@ def test_note_api_create_bad_permissions(self):
670670
"Creating a note in an outside project is NOT OK"
671671
data = TEST_NOTE.copy()
672672
self.client.logout()
673-
self.client.login(username='esther', password='esther')
673+
self.client.login(username='esther@example.com', password='esther')
674674
response = self.client.post(
675675
reverse('api:notes-list', args=[self.project.slug]),
676676
json.dumps(data),
@@ -723,7 +723,7 @@ def test_note_api_list(self):
723723
original_response_content = response.data
724724

725725
self.client.logout()
726-
self.client.login(username='esther', password='esther')
726+
self.client.login(username='esther@example.com', password='esther')
727727
response = self.client.get(reverse('api:notes-list',
728728
args=[self.project.slug]),
729729
HTTP_ACCEPT='application/json')
@@ -764,7 +764,7 @@ def test_note_api_update_bad_permissions(self):
764764
"Updating a note in an outside project is NOT OK"
765765
note_obj = self.create_test_note()
766766
self.client.logout()
767-
self.client.login(username='esther', password='esther')
767+
self.client.login(username='esther@example.com', password='esther')
768768
data = TEST_NOTE.copy()
769769
data['title'] = u'Нет!!!!!!'
770770
response = self.client.put(
@@ -818,7 +818,7 @@ def test_note_api_delete_bad_permissions(self):
818818
"Deleting a note in an outside project is NOT OK"
819819
note_obj = self.create_test_note()
820820
self.client.logout()
821-
self.client.login(username='esther', password='esther')
821+
self.client.login(username='esther@example.com', password='esther')
822822
response = self.client.delete(
823823
reverse('api:notes-detail', args=[self.project.slug, note_obj.id]),
824824
content_type='application/json'

editorsnotes/api/urls.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,9 +60,9 @@ def format_patterns(urlpatterns):
6060
url(r'^search/$', views.SearchView.as_view(), name='search'),
6161
url(r'^notes/$', views.AllProjectNoteList.as_view(), name='all-projects-notes-list'),
6262
url(r'^projects/$', views.ProjectList.as_view(), name='projects-list'),
63-
url(r'^projects/(?P<project_slug>\w+)', include(project_specific_patterns)),
64-
url(r'^users/(?P<username>[\w@\+\.\-]+)/$', views.UserDetail.as_view(), name='users-detail'),
65-
url(r'^users/(?P<username>[\w@\+\.\-]+)/activity/$', views.ActivityView.as_view(), name='users-activity'),
63+
url(r'^projects/(?P<project_slug>[\w\-]+)', include(project_specific_patterns)),
64+
url(r'^users/(?P<pk>\d+)/$', views.UserDetail.as_view(), name='users-detail'),
65+
url(r'^users/(?P<pk>\d+)/activity/$', views.ActivityView.as_view(), name='users-activity'),
6666
url(r'^me/$', views.SelfUserDetail.as_view(), name='users-detail-self'),
6767

6868
)

editorsnotes/api/views/auth.py

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,6 @@ def get_object(self):
7474
class UserDetail(EmbeddedReferencesMixin, RetrieveAPIView):
7575
queryset = User.objects.all()
7676
serializer_class = UserSerializer
77-
lookup_field = 'username'
7877

7978

8079
class SelfUserDetail(EmbeddedReferencesMixin, RetrieveAPIView):
@@ -108,11 +107,11 @@ class ActivityView(ElasticSearchListMixin, ListAPIView):
108107
queryset = LogActivity.objects.all()
109108

110109
def get_object(self):
111-
username = self.kwargs.get('username', None)
110+
user_id = self.kwargs.get('id', None)
112111
project_slug = self.kwargs.get('project_slug', None)
113112

114-
if username is not None:
115-
obj = get_object_or_404(User, username=username)
113+
if user_id is not None:
114+
obj = get_object_or_404(User, id=user_id)
116115
elif project_slug is not None:
117116
obj = get_object_or_404(Project, slug=project_slug)
118117
else:
@@ -129,7 +128,7 @@ def get_es_search(self):
129128
# FIXME FIXME FIXME: Users' and projects' actions should be indexed by
130129
# their URLs, not their usernames/slugs
131130
if isinstance(obj, User):
132-
search = search.filter('term', **{'data.user': obj.username})
131+
search = search.filter('term', **{'data.user_id': obj.id})
133132
else:
134133
search = search.filter('term', **{'data.project': obj.slug})
135134

editorsnotes/api/views/browse.py

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,9 @@
77

88
from editorsnotes.api.serializers import ProjectSerializer
99
from editorsnotes.api.serializers.hydra import link_properties_for_project
10+
from editorsnotes.auth.models import Project
1011
from editorsnotes.main.models import Note, Topic, Document
11-
from editorsnotes.search import items as items_search
12+
from editorsnotes.search import items_index
1213

1314

1415
__all__ = ['root', 'browse_items']
@@ -53,15 +54,15 @@ def root(request, format=None):
5354

5455

5556
def search_model(Model, query):
56-
query = query.to_dict()
57-
query['fields'] = ['display_title', 'url']
58-
results = items_search.search_model(Model, query)
57+
es_query = items_index\
58+
.make_search_for_model(Model)\
59+
.fields(['display_title', 'url'])
60+
61+
results = es_query.execute()
62+
5963
return [
60-
{
61-
'title': result['fields']['display_title'][0],
62-
'url': result['fields']['url'][0]
63-
}
64-
for result in results['hits']['hits']
64+
{ 'title': result.display_title[0], 'url': result.url[0] }
65+
for result in results.hits
6566
]
6667

6768

@@ -75,5 +76,6 @@ def browse_items(request, format=None):
7576
ret['notes'] = search_model(Note, es_query.filter(
7677
'term', **{'serialized.is_private': 'false'}
7778
))
79+
ret['projects'] = search_model(Project, es_query)
7880

7981
return Response(ret)

0 commit comments

Comments
 (0)