Skip to content

Commit

Permalink
Merge pull request #90 from plone/more-mocks
Browse files Browse the repository at this point in the history
provide login mock and update action mock
  • Loading branch information
lukasgraf committed May 17, 2016
2 parents f9e2916 + 115dc95 commit adc8a95
Show file tree
Hide file tree
Showing 12 changed files with 165 additions and 52 deletions.
21 changes: 14 additions & 7 deletions docs/source/_json/actions.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,24 +5,31 @@ HTTP 200 OK
content-type: application/json

{
"object_actions": [
"actions": [
{
"@id": "view",
"category": "",
"title": "View"
},
{
"@id": "edit",
"category": "",
"title": "Edit"
},
{
"@id": "Collection",
"category": "factories",
"title": "Collection",
"uri": "http://localhost:8080/Plone/++add++Collection"
"title": "Collection"
},
{
"@id": "Document",
"category": "factories",
"title": "Document",
"uri": "http://localhost:8080/Plone/++add++Document"
"title": "Document"
},
{
"@id": "reject",
"category": "workflow",
"title": "Send back",
"uri": "http://localhost:8080/Plone/content_status_modify?workflow_action=reject"
"title": "Send back"
}
]
}
8 changes: 4 additions & 4 deletions docs/source/_json/components_breadcrumbs.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@ content-type: application/json
"data": {
"items": [
{
"label": "Junk",
"uri": "http://plone/junk"
"title": "Junk",
"url": "http://plone/junk"
},
{
"label": "More Junk",
"uri": "http://plone/junk/more-junk"
"title": "More Junk",
"url": "http://plone/junk/more-junk"
}
]
},
Expand Down
8 changes: 4 additions & 4 deletions docs/source/_json/components_navigation.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@ content-type: application/json
"data": {
"items": [
{
"label": "News",
"uri": "http://plone/news"
"title": "News",
"url": "http://plone/news"
},
{
"label": "Events",
"uri": "http://plone/events"
"title": "Events",
"url": "http://plone/events"
}
]
},
Expand Down
19 changes: 19 additions & 0 deletions docs/source/_json/login.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
POST /plone/login_
Accept: application/json

{"username": "admin", "password": "admin"}

HTTP 200 OK
content-type: application/json

{
"jwt": {
"algorithm": "HS256",
"expires": 1463534055.943888,
"fullname": "Foo bar",
"type": "JWT",
"username": "admin"
},
"signature": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImFkbWluIiwiZnVsbG5hbWUiOiJGb28gYmFyIiwiZXhwaXJlcyI6MTQ2MzUzNDA1NS45NDM4ODgsInR5cGUiOiJKV1QiLCJhbGdvcml0aG0iOiJIUzI1NiJ9.3IafcTKFwcaiSqwuWJ9yxt3iotTYYhLCv7P8_K32hD0",
"success": true
}
20 changes: 19 additions & 1 deletion docs/source/additional-endpoints.rst
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ Examples:


Actions
==========
=======

Get the available actions for the given context
-----------------------------------------------
Expand Down Expand Up @@ -125,3 +125,21 @@ Example:

.. literalinclude:: _json/frame_object.json
:language: js


Authentication
==============

Login
-----

.. code::
POST /:path/login_ HTTP/1.1
Host: localhost:8080
Accept: application/json
Example:

.. literalinclude:: _json/login.json
:language: js
1 change: 1 addition & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
'plone.app.robotframework',
'plone.app.testing [robot] >= 4.2.2',
'requests',
'pyjwt'
]},
entry_points="""
# -*- Entry points: -*-
Expand Down
42 changes: 21 additions & 21 deletions src/plone/restapi/services/actions/get.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,27 +4,27 @@
from zope.publisher.interfaces import IPublishTraverse

MOCKEDRESPONSE = {
'object_actions': [
{
'@id': 'Collection',
'title': 'Collection',
'uri': 'http://localhost:8080/Plone/++add++Collection',
'category': 'factories',
},
{
'@id': 'Document',
'title': 'Document',
'uri': 'http://localhost:8080/Plone/++add++Document',
'category': 'factories',
},
{
'@id': 'reject',
'title': 'Send back',
'uri': 'http://localhost:8080/Plone/content_status_modify?'
'workflow_action=reject',
'category': 'workflow',
},
]
"actions": [{
"@id": "view",
"title": "View",
"category": ""
}, {
"@id": "edit",
"title": "Edit",
"category": ""
}, {
"@id": "Collection",
"title": "Collection",
"category": "factories"
}, {
"@id": "Document",
"title": "Document",
"category": "factories"
}, {
"@id": "reject",
"title": "Send back",
"category": "workflow"
}]
}


Expand Down
39 changes: 39 additions & 0 deletions src/plone/restapi/services/authentication/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# -*- coding: utf-8 -*-
from plone.rest import Service
from zope.interface import implements
from zope.publisher.interfaces import IPublishTraverse
import jwt
import time


class Login(Service):

# should be in keyring...
secret = 'foobar'

implements(IPublishTraverse)

def render(self):
data = {
'algorithm': 'HS256',
'type': 'JWT',
'username': 'admin',
'fullname': 'Foo bar',
'expires': time.time() + (60 * 60 * 12) # 12 hour length?
}
encoded = jwt.encode(data, self.secret, algorithm='HS256')
return {
'success': True,
'jwt': data,
'signature': encoded
}


class Logout(Service):
implements(IPublishTraverse)

def render(self):
# doing nothing right now
return {
'success': True
}
21 changes: 21 additions & 0 deletions src/plone/restapi/services/authentication/configure.zcml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<configure
xmlns="http://namespaces.zope.org/zope"
xmlns:plone="http://namespaces.plone.org/plone">

<plone:service
method="POST"
for="zope.interface.Interface"
factory=".Login"
name="login_"
permission="zope2.View"
/>

<plone:service
method="POST"
for="zope.interface.Interface"
factory=".Logout"
name="logout_"
permission="zope2.View"
/>

</configure>
16 changes: 8 additions & 8 deletions src/plone/restapi/services/components/get.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,17 +34,17 @@ def _frame_component_items(self, items, component_id):
def _render_component(self, component_id):
if component_id == 'navigation':
items = [
{'label': 'News',
'uri': 'http://plone/news'},
{'label': 'Events',
'uri': 'http://plone/events'}
{'title': 'News',
'url': 'http://plone/news'},
{'title': 'Events',
'url': 'http://plone/events'}
]
elif component_id == 'breadcrumbs':
items = [
{'label': 'Junk',
'uri': 'http://plone/junk'},
{'label': 'More Junk',
'uri': 'http://plone/junk/more-junk'}
{'title': 'Junk',
'url': 'http://plone/junk'},
{'title': 'More Junk',
'url': 'http://plone/junk/more-junk'}
]
else:
raise NotImplementedError(
Expand Down
1 change: 1 addition & 0 deletions src/plone/restapi/services/configure.zcml
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,6 @@
<include package=".theme"/>
<include package=".components"/>
<include package=".actions"/>
<include package=".authentication"/>

</configure>
21 changes: 14 additions & 7 deletions src/plone/restapi/tests/test_documentation.py
Original file line number Diff line number Diff line change
@@ -1,25 +1,25 @@
# -*- coding: utf-8 -*-
from DateTime import DateTime
from datetime import datetime
from plone.restapi.testing import PLONE_RESTAPI_DX_FUNCTIONAL_TESTING
from plone.restapi.testing import RelativeSession
from plone.app.testing import setRoles
from plone.app.testing import TEST_USER_ID
from plone.app.testing import SITE_OWNER_NAME
from plone.app.testing import SITE_OWNER_PASSWORD
from plone.app.testing import TEST_USER_ID
from plone.app.textfield.value import RichTextValue
from plone.namedfile.file import NamedBlobImage
from plone.namedfile.file import NamedBlobFile
from plone.namedfile.file import NamedBlobImage
from plone.restapi.testing import PLONE_RESTAPI_DX_FUNCTIONAL_TESTING
from plone.restapi.testing import RelativeSession
from plone.testing.z2 import Browser
from plone.uuid.interfaces import IMutableUUID
from DateTime import DateTime

from z3c.relationfield import RelationValue
from zope.component import getUtility
from zope.intid.interfaces import IIntIds

import json
import os
import unittest2 as unittest

import os

REQUEST_HEADER_KEYS = [
'accept'
Expand Down Expand Up @@ -324,3 +324,10 @@ def test_documentation_frame_object(self):
response = self.api_session.get(
self.document.absolute_url() + '?frame=object')
save_response_for_documentation('frame_object.json', response)

def test_documentation_login(self):
response = self.api_session.post('/login_', data=json.dumps({
'username': 'admin',
'password': 'admin'
}))
save_response_for_documentation('login.json', response)

0 comments on commit adc8a95

Please sign in to comment.