Skip to content
Merged
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
6 changes: 1 addition & 5 deletions lib/create-app.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,7 @@ function createApp (argv = {}) {
rootUrl: argv.serverUri,
rootPath: path.resolve(argv.root || process.cwd()),
includeHost: argv.multiuser,
defaultContentType: argv.defaultContentType,
fileSuffixes: [
argv.suffixAcl || '.acl',
argv.suffixMeta || '.meta'
]
defaultContentType: argv.defaultContentType
})

const configPath = config.initConfigDir(argv)
Expand Down
12 changes: 9 additions & 3 deletions lib/handlers/allow.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,15 @@ function allow (mode, checkPermissionsForDirectory) {
if (mode === 'Read' && (resourcePath === '' || resourcePath === '/')) {
// This is a hack to make NSS check the ACL for representation that is served for root (if any)
// See https://github.com/solid/node-solid-server/issues/1063 for more info
const representationUrl = await ldp.resourceMapper.getRepresentationUrlForResource(resourceUrl)
if (representationUrl.endsWith('index.html')) {
// We ONLY want to do this when the representation we return is a HTML file
const representationUrl = `${rootUrl}/index.html`
let representationPath
try {
representationPath = await ldp.resourceMapper.mapUrlToFile({ url: representationUrl })
} catch (err) {
}

// We ONLY want to do this when the HTML representation exists
if (representationPath) {
req.acl = ACL.createFromLDPAndRequest(representationUrl, ldp, req)
const representationIsAllowed = await req.acl.can(userId, mode)
if (representationIsAllowed) {
Expand Down
40 changes: 23 additions & 17 deletions lib/handlers/get.js
Original file line number Diff line number Diff line change
Expand Up @@ -132,19 +132,26 @@ async function handler (req, res, next) {
}

async function globHandler (req, res, next) {
const ldp = req.app.locals.ldp
// TODO: This is a hack, that does not check if the target file exists, as this is quite complex with globbing.
// TODO: Proper support for this is not implemented, as globbing support might be removed in the future.
const filename = ldp.resourceMapper.getFullPath(req)
const requestUri = (await ldp.resourceMapper.mapFileToUrl({ path: filename, hostname: req.hostname })).url
const { ldp } = req.app.locals

// Ensure this is a glob for all files in a single folder
// https://github.com/solid/solid-spec/pull/148
const requestUrl = await ldp.resourceMapper.getRequestUrl(req)
if (!/^[^*]+\/\*$/.test(requestUrl)) {
return next(error(404, 'Unsupported glob pattern'))
}

// Extract the folder on the file system from the URL glob
const folderUrl = requestUrl.substr(0, requestUrl.length - 1)
const folderPath = (await ldp.resourceMapper.mapUrlToFile({ url: folderUrl, searchIndex: false })).path

const globOptions = {
noext: true,
nobrace: true,
nodir: true
}

glob(filename, globOptions, function (err, matches) {
glob(`${folderPath}*`, globOptions, async (err, matches) => {
if (err || matches.length === 0) {
debugGlob('No files matching the pattern')
return next(error(404, 'No files matching glob pattern'))
Expand All @@ -154,7 +161,7 @@ async function globHandler (req, res, next) {
const globGraph = $rdf.graph()

debugGlob('found matches ' + matches)
Promise.all(matches.map(match => new Promise(async (resolve, reject) => {
await Promise.all(matches.map(match => new Promise(async (resolve, reject) => {
const urlData = await ldp.resourceMapper.mapFileToUrl({ path: match, hostname: req.hostname })
fs.readFile(match, {encoding: 'utf8'}, function (err, fileData) {
if (err) {
Expand All @@ -178,15 +185,14 @@ async function globHandler (req, res, next) {
})
})
})))
.then(() => {
const data = $rdf.serialize(undefined, globGraph, requestUri, 'text/turtle')
// TODO this should be added as a middleware in the routes
res.setHeader('Content-Type', 'text/turtle')
debugGlob('returning turtle')

res.send(data)
return next()
})

const data = $rdf.serialize(undefined, globGraph, requestUrl, 'text/turtle')
// TODO this should be added as a middleware in the routes
res.setHeader('Content-Type', 'text/turtle')
debugGlob('returning turtle')

res.send(data)
next()
})
}

Expand All @@ -198,7 +204,7 @@ function hasReadPermissions (file, req, res, callback) {
return callback(true)
}

const root = ldp.resourceMapper.getBasePath(req.hostname)
const root = ldp.resourceMapper.resolveFilePath(req.hostname)
const relativePath = '/' + _path.relative(root, file)
res.locals.path = relativePath
allow('Read')(req, res, err => callback(!err))
Expand Down
2 changes: 1 addition & 1 deletion lib/handlers/patch.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ async function patchHandler (req, res, next) {
const result = await withLock(path, { mustExist: false }, async () => {
const graph = await readGraph(resource)
await applyPatch(patchObject, graph, url)
return writeGraph(graph, resource, ldp.resourceMapper.rootPath, ldp.serverUri)
return writeGraph(graph, resource, ldp.resourceMapper.resolveFilePath(req.hostname), ldp.serverUri)
})

// Send the result to the client
Expand Down
6 changes: 3 additions & 3 deletions lib/handlers/put.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,11 @@ async function putStream (req, res, next, stream = req) {
}
}

async function putAcl (req, res, next) {
function putAcl (req, res, next) {
const ldp = req.app.locals.ldp
const contentType = req.get('content-type')
const path = ldp.resourceMapper.getFullPath(req)
const requestUri = await ldp.resourceMapper.resolveUrl(req.hostname, path)
const requestUri = ldp.resourceMapper.getRequestUrl(req)

if (ldp.isValidRdf(req.body, requestUri, contentType)) {
const stream = stringToStream(req.body)
return putStream(req, res, next, stream)
Expand Down
11 changes: 5 additions & 6 deletions lib/ldp.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ const ldpContainer = require('./ldp-container')
const parse = require('./utils').parse
const fetch = require('node-fetch')
const { promisify } = require('util')
const URL = require('url')
const URI = require('urijs')
const withLock = require('./lock')

Expand Down Expand Up @@ -153,8 +154,7 @@ class LDP {
originalPath += '/'
}
}
const { url: putUrl, contentType } = await this.resourceMapper.mapFileToUrl(
{ path: this.resourceMapper.rootPath + resourcePath, hostname: host })
const { url: putUrl, contentType } = await this.resourceMapper.mapFileToUrl({ path: resourcePath, hostname: host })

// HACK: the middleware in webid-oidc.js uses body-parser, thus ending the stream of data
// for JSON bodies. So, the stream needs to be reset
Expand Down Expand Up @@ -218,7 +218,8 @@ class LDP {
// First check if we are above quota
let isOverQuota
try {
isOverQuota = await overQuota(this.resourceMapper.rootPath, this.serverUri)
const { hostname } = URL.parse(url.url || url)
isOverQuota = await overQuota(this.resourceMapper.resolveFilePath(hostname), this.serverUri)
} catch (err) {
throw error(500, 'Error finding user quota')
}
Expand Down Expand Up @@ -323,9 +324,7 @@ class LDP {
async get (options, searchIndex = true) {
let path, contentType, stats
try {
({ path, contentType } = await this.resourceMapper.mapUrlToFile({
url: options, contentType: options.contentType, searchIndex
}))
({ path, contentType } = await this.resourceMapper.mapUrlToFile({ url: options, searchIndex }))
stats = await this.stat(path)
} catch (err) {
throw error(404, 'Can\'t find file requested: ' + options)
Expand Down
3 changes: 2 additions & 1 deletion lib/models/account-manager.js
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,8 @@ class AccountManager {
* @return {string}
*/
accountDirFor (accountName) {
return this.store.resourceMapper.getBasePath(url.parse(this.accountUriFor(accountName)).hostname)
const { hostname } = url.parse(this.accountUriFor(accountName))
return this.store.resourceMapper.resolveFilePath(hostname)
}

/**
Expand Down
Loading