Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/msg/core/executor.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ async def execute(self,request, *, entry='network'):
capacity_writes={'identity.register','identity.temporary','identity.custodial_create','content.topic_create',
'content.post_create','content.post_edit','content.file_put','content.attach',
'content.template_put','discussion.reply','discussion.quote','discussion.repost',
'transfer.part_put','git.create','git.push','git.receive','hosting.deploy','keystore.put'}
'transfer.part_put','git.create','git.push','git.receive','hosting.deploy','hosting.preview','keystore.put'}
if spec.name in capacity_writes:
require(session.setting('runtime_config',{}).get('accept_writes',True),'writes_paused')
for rid,generation in request.expected_generations:
Expand Down
2 changes: 1 addition & 1 deletion src/msg/extensions/hosting.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ async def deploy(ctx,request,tx):
resource=await revise_resource(app,ctx,request,tx,resource,body,'application/json')
return output_for(resource,files=len(entries),url=app.settings.service_url.rstrip('/')+await tx.path(resource.id)+'/')

@op('hosting.preview',obj({'id':IDENTIFIER,'entries':{'type':'array','minItems':1,
@op('hosting.preview',obj({'id':IDENTIFIER,'entries':{'type':'array','minItems':1,'maxItems':128,
'items':obj({'path':STRING,'source':REF},('path','source'))}},('id','entries')),signature=True)
async def preview(ctx,request,tx):
website=await tx.resource(await resolve(tx,request.arguments['id']))
Expand Down
15 changes: 15 additions & 0 deletions tests/test_hosting_same_origin.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,11 @@
import httpx
import pytest
from datetime import timedelta
from types import SimpleNamespace

from msg.application import Application
from msg.core.codec import b64, canonical, loads, wire
from msg.core.errors import Failure
from msg.core.models import ResourceRef
from msg.core.requests import request_for
from msg.transports.http import create_app
Expand All @@ -19,6 +22,18 @@ def isolated(response):
assert response.headers['x-content-type-options']=='nosniff'


def test_preview_entry_count_is_bounded():
settings=SimpleNamespace(server=SimpleNamespace(
plugins=('identity','content','discussion','communication','discovery','achievements',
'recovery','sharing','transfer','extensions','system','batch')))
registry=Application(settings).registry
entries=[{'path':f'{index}.html','source':{'id':'unused','revision':'unused'}}
for index in range(129)]
spec=registry.operation('hosting.preview',1)
with pytest.raises(Failure,match='schema_validation'):
registry.validate(spec.input_schema,{'id':'unused','entries':entries})


@pytest.mark.asyncio
async def test_same_domain_hosted_html_head_304_range_raw_and_no_write_route(installed):
app, _ = installed
Expand Down
8 changes: 7 additions & 1 deletion tests/test_operations_admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from pathlib import Path
import pytest

from msg.core.codec import wire
from msg.core.codec import b64,wire
from msg.core.errors import Failure
from msg.admin.diagnostics import doctor, selftest
from msg.workers.maintenance import run_maintenance
Expand All @@ -16,6 +16,9 @@
async def test_network_system_configuration_cannot_change_root_trust(installed):
app,root=installed
key,uid,base=await register(app,'operator')
site=await call(app,'hosting.create',{'parent':'/@operator','name':'paused-preview'},key=key,subject=uid)
source=await call(app,'content.file_put',{'parent':'/@operator/files','name':'preview.html',
'data':b64(b'preview'),'media_type':'text/html'},key=key,subject=uid)
denied=await call(app,'system.config',{'values':{'accept_writes':False}},key=key,subject=uid)
assert denied.error.code=='capability_required',wire(denied)
cert=await approve(app,root,uid,key,(scoped(app,'system.config','r_root',('system.config@1',)),))
Expand All @@ -27,6 +30,9 @@ async def test_network_system_configuration_cannot_change_root_trust(installed):
assert bad.status=='error'
blocked=await call(app,'content.post_create',{'parent':'/main','body':'capacity is paused'},key=key,subject=uid)
assert blocked.error.code=='writes_paused'
preview=await call(app,'hosting.preview',{'id':site.resources[0].id,
'entries':[{'path':'index.html','source':wire(source.resources[0])}]},key=key,subject=uid)
assert preview.error.code=='writes_paused'
reading=await call(app,'discovery.get',{'id':'/main'})
assert reading.status=='ok'

Expand Down
Loading