Small bugfixes
This commit is contained in:
parent
b1aa79fd0a
commit
f0f1376b7d
|
@ -2,6 +2,7 @@ from distutils.version import StrictVersion
|
||||||
from itertools import chain
|
from itertools import chain
|
||||||
from typing import Set
|
from typing import Set
|
||||||
|
|
||||||
|
import boltons.urlutils
|
||||||
from teal.auth import TokenAuth
|
from teal.auth import TokenAuth
|
||||||
from teal.config import Config
|
from teal.config import Config
|
||||||
from teal.enums import Currency
|
from teal.enums import Currency
|
||||||
|
@ -59,8 +60,14 @@ class DevicehubConfig(Config):
|
||||||
"""
|
"""
|
||||||
Official versions
|
Official versions
|
||||||
"""
|
"""
|
||||||
|
TAG_BASE_URL = None
|
||||||
|
TAG_TOKEN = None
|
||||||
|
"""Access to the tag provider."""
|
||||||
|
|
||||||
def __init__(self, db: str = None) -> None:
|
def __init__(self, db: str = None) -> None:
|
||||||
if not self.ORGANIZATION_NAME or not self.ORGANIZATION_TAX_ID:
|
if not self.ORGANIZATION_NAME or not self.ORGANIZATION_TAX_ID:
|
||||||
raise ValueError('You need to set the main organization parameters.')
|
raise ValueError('You need to set the main organization parameters.')
|
||||||
|
if not self.TAG_BASE_URL or not self.TAG_TOKEN:
|
||||||
|
raise ValueError('You need a tag service.')
|
||||||
|
self.TAG_BASE_URL = boltons.urlutils.URL(self.TAG_BASE_URL)
|
||||||
super().__init__(db)
|
super().__init__(db)
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
from typing import Type
|
from typing import Type
|
||||||
|
|
||||||
|
from ereuse_utils.session import DevicehubClient
|
||||||
from flask_sqlalchemy import SQLAlchemy
|
from flask_sqlalchemy import SQLAlchemy
|
||||||
from sqlalchemy import event
|
from sqlalchemy import event
|
||||||
from teal.config import Config as ConfigClass
|
from teal.config import Config as ConfigClass
|
||||||
|
@ -33,6 +34,7 @@ class Devicehub(Teal):
|
||||||
super().__init__(config, db, import_name, static_url_path, static_folder, static_host,
|
super().__init__(config, db, import_name, static_url_path, static_folder, static_host,
|
||||||
host_matching, subdomain_matching, template_folder, instance_path,
|
host_matching, subdomain_matching, template_folder, instance_path,
|
||||||
instance_relative_config, root_path, Auth)
|
instance_relative_config, root_path, Auth)
|
||||||
|
self.tag_provider = DevicehubClient(**self.config.get_namespace('TAG_'))
|
||||||
self.dummy = Dummy(self)
|
self.dummy = Dummy(self)
|
||||||
self.before_request(self.register_db_events_listeners)
|
self.before_request(self.register_db_events_listeners)
|
||||||
self.cli.command('regenerate-search')(self.regenerate_search)
|
self.cli.command('regenerate-search')(self.regenerate_search)
|
||||||
|
|
|
@ -108,7 +108,7 @@ class Tag(Thing):
|
||||||
Only tags that are from the default organization can be
|
Only tags that are from the default organization can be
|
||||||
printed by the user.
|
printed by the user.
|
||||||
"""
|
"""
|
||||||
return Organization.get_default_org_id == self.org_id
|
return Organization.get_default_org_id() == self.org_id
|
||||||
|
|
||||||
def __repr__(self) -> str:
|
def __repr__(self) -> str:
|
||||||
return '<Tag {0.id} org:{0.org_id} device:{0.device_id}>'.format(self)
|
return '<Tag {0.id} org:{0.org_id} device:{0.device_id}>'.format(self)
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
from flask import Response, current_app as app, redirect, request
|
from ereuse_utils.session import DevicehubClient
|
||||||
|
from flask import Response, current_app, current_app as app, jsonify, redirect, request
|
||||||
from teal.marshmallow import ValidationError
|
from teal.marshmallow import ValidationError
|
||||||
from teal.resource import View, url_for_resource
|
from teal.resource import View, url_for_resource
|
||||||
|
|
||||||
|
@ -10,6 +11,25 @@ from ereuse_devicehub.resources.tag import Tag
|
||||||
class TagView(View):
|
class TagView(View):
|
||||||
def post(self):
|
def post(self):
|
||||||
"""Creates a tag."""
|
"""Creates a tag."""
|
||||||
|
num = request.args.get('num', type=int)
|
||||||
|
if num:
|
||||||
|
res = self._create_many_regular_tags(num)
|
||||||
|
else:
|
||||||
|
res = self._post_one()
|
||||||
|
return res
|
||||||
|
|
||||||
|
def _create_many_regular_tags(self, num: int):
|
||||||
|
tag_provider = current_app.tag_provider # type: DevicehubClient
|
||||||
|
tags_id, _ = tag_provider.post('/', {}, query=[('num', num)])
|
||||||
|
tags = [Tag(id=tag_id, provider=current_app.config['TAG_BASE_URL']) for tag_id in tags_id]
|
||||||
|
db.session.add_all(tags)
|
||||||
|
db.session.commit()
|
||||||
|
response = jsonify(items=self.schema.dump(tags, many=True, nested=1)) # type: Response
|
||||||
|
response.status_code = 201
|
||||||
|
return response
|
||||||
|
|
||||||
|
def _post_one(self):
|
||||||
|
# todo do we use this?
|
||||||
t = request.get_json()
|
t = request.get_json()
|
||||||
tag = Tag(**t)
|
tag = Tag(**t)
|
||||||
if tag.like_etag():
|
if tag.like_etag():
|
||||||
|
|
|
@ -1,9 +1,8 @@
|
||||||
from base64 import b64encode
|
|
||||||
|
|
||||||
from marshmallow import post_dump
|
from marshmallow import post_dump
|
||||||
from marshmallow.fields import Email, String, UUID
|
from marshmallow.fields import Email, String, UUID
|
||||||
from teal.marshmallow import SanitizedStr
|
from teal.marshmallow import SanitizedStr
|
||||||
|
|
||||||
|
from ereuse_devicehub import auth
|
||||||
from ereuse_devicehub.marshmallow import NestedOn
|
from ereuse_devicehub.marshmallow import NestedOn
|
||||||
from ereuse_devicehub.resources.agent.schemas import Individual
|
from ereuse_devicehub.resources.agent.schemas import Individual
|
||||||
from ereuse_devicehub.resources.schemas import Thing
|
from ereuse_devicehub.resources.schemas import Thing
|
||||||
|
@ -42,5 +41,5 @@ class User(Thing):
|
||||||
if 'token' in data:
|
if 'token' in data:
|
||||||
# In many cases we don't dump the token (ex. relationships)
|
# In many cases we don't dump the token (ex. relationships)
|
||||||
# Framework needs ':' at the end
|
# Framework needs ':' at the end
|
||||||
data['token'] = b64encode(str.encode(str(data['token']) + ':')).decode()
|
data['token'] = auth.Auth.encode(data['token'])
|
||||||
return data
|
return data
|
||||||
|
|
2
setup.py
2
setup.py
|
@ -32,7 +32,7 @@ setup(
|
||||||
'teal>=0.2.0a32', # teal always first
|
'teal>=0.2.0a32', # teal always first
|
||||||
'click',
|
'click',
|
||||||
'click-spinner',
|
'click-spinner',
|
||||||
'ereuse-utils[Naming]>=0.4b13',
|
'ereuse-utils[Naming]>=0.4b14',
|
||||||
'hashids',
|
'hashids',
|
||||||
'marshmallow_enum',
|
'marshmallow_enum',
|
||||||
'psycopg2-binary',
|
'psycopg2-binary',
|
||||||
|
|
|
@ -31,6 +31,8 @@ class TestConfig(DevicehubConfig):
|
||||||
ORGANIZATION_NAME = 'FooOrg'
|
ORGANIZATION_NAME = 'FooOrg'
|
||||||
ORGANIZATION_TAX_ID = 'foo-org-id'
|
ORGANIZATION_TAX_ID = 'foo-org-id'
|
||||||
SERVER_NAME = 'localhost'
|
SERVER_NAME = 'localhost'
|
||||||
|
TAG_BASE_URL = 'https://example.com'
|
||||||
|
TAG_TOKEN = 'tagToken'
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(scope='session')
|
@pytest.fixture(scope='session')
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import pathlib
|
import pathlib
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
import requests_mock
|
||||||
from boltons.urlutils import URL
|
from boltons.urlutils import URL
|
||||||
from pytest import raises
|
from pytest import raises
|
||||||
from teal.db import MultipleResourcesFound, ResourceNotFound, UniqueViolation
|
from teal.db import MultipleResourcesFound, ResourceNotFound, UniqueViolation
|
||||||
|
@ -232,3 +233,20 @@ def test_tag_multiple_secondary_org(user: UserClient):
|
||||||
"""Ensures two secondary ids cannot be part of the same Org."""
|
"""Ensures two secondary ids cannot be part of the same Org."""
|
||||||
user.post({'id': 'foo', 'secondary': 'bar'}, res=Tag)
|
user.post({'id': 'foo', 'secondary': 'bar'}, res=Tag)
|
||||||
user.post({'id': 'foo1', 'secondary': 'bar'}, res=Tag, status=UniqueViolation)
|
user.post({'id': 'foo1', 'secondary': 'bar'}, res=Tag, status=UniqueViolation)
|
||||||
|
|
||||||
|
|
||||||
|
def test_crate_num_regular_tags(user: UserClient, requests_mock: requests_mock.mocker.Mocker):
|
||||||
|
"""Create regular tags. This is done using a tag provider that
|
||||||
|
returns IDs. These tags are printable.
|
||||||
|
"""
|
||||||
|
requests_mock.post('https://example.com/',
|
||||||
|
# request
|
||||||
|
request_headers={'Authorization': 'Basic tagToken'},
|
||||||
|
# response
|
||||||
|
json=['tag1id', 'tag2id'],
|
||||||
|
status_code=201)
|
||||||
|
data, _ = user.post({}, res=Tag, query=[('num', 2)])
|
||||||
|
assert data['items'][0]['id'] == 'tag1id'
|
||||||
|
assert data['items'][0]['printable'], 'Tags made this way are printable'
|
||||||
|
assert data['items'][1]['id'] == 'tag2id'
|
||||||
|
assert data['items'][1]['printable']
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
from base64 import b64decode
|
|
||||||
from uuid import UUID
|
from uuid import UUID
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
@ -7,6 +6,7 @@ from teal.enums import Country
|
||||||
from teal.marshmallow import ValidationError
|
from teal.marshmallow import ValidationError
|
||||||
from werkzeug.exceptions import NotFound
|
from werkzeug.exceptions import NotFound
|
||||||
|
|
||||||
|
from ereuse_devicehub import auth
|
||||||
from ereuse_devicehub.client import Client
|
from ereuse_devicehub.client import Client
|
||||||
from ereuse_devicehub.db import db
|
from ereuse_devicehub.db import db
|
||||||
from ereuse_devicehub.devicehub import Devicehub
|
from ereuse_devicehub.devicehub import Devicehub
|
||||||
|
@ -77,7 +77,7 @@ def test_login_success(client: Client, app: Devicehub):
|
||||||
uri='/users/login/',
|
uri='/users/login/',
|
||||||
status=200)
|
status=200)
|
||||||
assert user['email'] == 'foo@foo.com'
|
assert user['email'] == 'foo@foo.com'
|
||||||
assert UUID(b64decode(user['token'].encode()).decode()[:-1])
|
assert UUID(auth.Auth.decode(user['token']))
|
||||||
assert 'password' not in user
|
assert 'password' not in user
|
||||||
assert user['individuals'][0]['name'] == 'Timmy'
|
assert user['individuals'][0]['name'] == 'Timmy'
|
||||||
assert user['individuals'][0]['type'] == 'Person'
|
assert user['individuals'][0]['type'] == 'Person'
|
||||||
|
|
Reference in New Issue