1
0
mirror of https://github.com/laurent22/joplin.git synced 2025-01-23 18:53:36 +02:00

Server: Fixed access control on user list and clean up

This commit is contained in:
Laurent Cozic 2020-12-30 23:50:44 +00:00
parent d2771029a3
commit 20d126b39d
12 changed files with 45 additions and 27 deletions

View File

@ -15,8 +15,9 @@ import modelFactory from './models/factory';
import controllerFactory from './controllers/factory';
import { AppContext, Config, Env } from './utils/types';
import FsDriverNode from '@joplin/lib/fs-driver-node';
import requestProcessor from './middleware/requestProcessor';
import routeHandler from './middleware/routeHandler';
import notificationHandler from './middleware/notificationHandler';
import ownerHandler from './middleware/ownerHandler';
const { shimInit } = require('@joplin/lib/shim-init-node.js');
shimInit();
@ -44,8 +45,13 @@ function appLogger(): LoggerWrapper {
const app = new Koa();
// Note: the order of middlewares is important. For example, ownerHandler
// loads the user, which is then used by notificationHandler. And finally
// routeHandler uses data from both previous middlewares. It would be good to
// layout these dependencies in code but not clear how to do this.
app.use(ownerHandler);
app.use(notificationHandler);
app.use(requestProcessor);
app.use(routeHandler);
async function main() {
const configObject: Config = configs[env];

View File

@ -76,7 +76,7 @@ export default class FileController extends BaseController {
files.push(await fileToViewItem(file, fileFullPaths));
}
const view: View = defaultView('files', owner);
const view: View = defaultView('files');
view.content.paginatedFiles = { ...paginatedFiles, items: files };
view.content.paginationLinks = paginationLinks;
view.content.postUrl = `${baseUrl()}/files`;

View File

@ -5,8 +5,8 @@ import defaultView from '../../utils/defaultView';
export default class HomeController extends BaseController {
public async getIndex(sessionId: string): Promise<View> {
const owner = await this.initSession(sessionId);
return defaultView('home', owner);
await this.initSession(sessionId);
return defaultView('home');
}
}

View File

@ -17,7 +17,7 @@ export default class ProfileController extends BaseController {
public async getIndex(sessionId: string, user: User = null, error: any = null): Promise<View> {
const owner = await this.initSession(sessionId);
const view: View = defaultView('profile', owner);
const view: View = defaultView('profile');
view.content.user = user ? user : owner;
view.content.error = error;
view.partials.push('errorBanner');

View File

@ -7,11 +7,11 @@ import { baseUrl } from '../../config';
export default class UserController extends BaseController {
public async getIndex(sessionId: string): Promise<View> {
const owner = await this.initSession(sessionId);
const owner = await this.initSession(sessionId, true);
const userModel = this.models.user({ userId: owner.id });
const users = await userModel.all();
const view: View = defaultView('users', owner);
const view: View = defaultView('users');
view.content.users = users;
return view;
}
@ -28,7 +28,7 @@ export default class UserController extends BaseController {
user = userIdOrString as User;
}
const view: View = defaultView('user', owner);
const view: View = defaultView('user');
view.content.user = user;
view.content.isNew = isNew;
view.content.buttonTitle = isNew ? 'Create user' : 'Update profile';

View File

@ -1,6 +1,6 @@
import { AppContext, KoaNext, NotificationView } from '../utils/types';
import { isApiRequest, contextSessionId } from '../utils/requestUtils';
import { defaultAdminEmail, defaultAdminPassword, NotificationLevel, User } from '../db';
import { isApiRequest } from '../utils/requestUtils';
import { defaultAdminEmail, defaultAdminPassword, NotificationLevel } from '../db';
import { _ } from '@joplin/lib/locale';
import Logger from '@joplin/lib/Logger';
import * as MarkdownIt from 'markdown-it';
@ -13,8 +13,7 @@ export default async function(ctx: AppContext, next: KoaNext): Promise<void> {
try {
if (isApiRequest(ctx)) return next();
const sessionId = contextSessionId(ctx);
const user: User = await ctx.models.session().sessionUser(sessionId);
const user = ctx.owner;
if (!user) return next();
const notificationModel = ctx.models.notification({ userId: user.id });

View File

@ -0,0 +1,17 @@
import { AppContext, KoaNext } from '../utils/types';
import { isApiRequest, contextSessionId } from '../utils/requestUtils';
import Logger from '@joplin/lib/Logger';
const logger = Logger.create('loggedInUserHandler');
export default async function(ctx: AppContext, next: KoaNext): Promise<void> {
try {
if (isApiRequest(ctx)) return next();
const sessionId = contextSessionId(ctx);
ctx.owner = await ctx.models.session().sessionUser(sessionId);
} catch (error) {
logger.error(error);
}
return next();
}

View File

@ -21,6 +21,7 @@ export default async function(ctx: AppContext) {
ctx.response.status = 200;
ctx.response.body = await mustacheService.renderView(responseObject, {
notifications: ctx.notifications || [],
owner: ctx.owner,
});
} else {
ctx.response.status = 200;

View File

@ -1,14 +1,11 @@
import { User } from '../db';
import { View } from '../services/MustacheService';
// Populate a View object with some good defaults.
export default function(name: string, owner: User = null): View {
export default function(name: string): View {
return {
name: name,
path: `index/${name}`,
content: {
owner,
},
content: {},
partials: [
'navbar',
'notifications',

View File

@ -1,7 +1,7 @@
import { LoggerWrapper } from '@joplin/lib/Logger';
import * as Koa from 'koa';
import { Controllers } from '../controllers/factory';
import { DbConnection, Uuid } from '../db';
import { DbConnection, User, Uuid } from '../db';
import { Models } from '../models/factory';
export enum Env {
@ -24,6 +24,7 @@ export interface AppContext extends Koa.Context {
controllers: Controllers;
appLogger(): LoggerWrapper;
notifications: NotificationView[];
owner: User;
}
export interface DatabaseConfig {

View File

@ -1,6 +1 @@
Welcome {{owner.email}}
<ul>
</ul>
Welcome {{global.owner.email}}

View File

@ -7,11 +7,13 @@
<div class="navbar-menu is-active">
<div class="navbar-start">
<a class="navbar-item" href="{{{global.baseUrl}}}/home">Home</a>
<a class="navbar-item" href="{{{global.baseUrl}}}/users">Users</a>
{{#global.owner.is_admin}}
<a class="navbar-item" href="{{{global.baseUrl}}}/users">Users</a>
{{/global.owner.is_admin}}
<a class="navbar-item" href="{{{global.baseUrl}}}/files">Files</a>
</div>
<div class="navbar-end">
<div class="navbar-item">{{owner.email}}</div>
<div class="navbar-item">{{global.owner.email}}</div>
<a class="navbar-item" href="{{{global.baseUrl}}}/profile">Profile</a>
<div class="navbar-item">
<form method="post" action="{{{global.baseUrl}}}/logout">