From c2f6b099692520548bd4218ae37a4917c60343af Mon Sep 17 00:00:00 2001
From: syuilo <syuilotan@yahoo.co.jp>
Date: Wed, 16 Jan 2019 02:30:55 +0900
Subject: [PATCH] =?UTF-8?q?disableLocalTimeline=E6=A9=9F=E8=83=BD=E3=82=92?=
 =?UTF-8?q?=E5=BC=B7=E5=8C=96?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

* ストリームだけではなくAPIも無効に
* モデレーターは無効の場合でも見れるように
* グローバルタイムラインも無効に(連合数が少ないインスタンスではグローバルタイムラインは実質的にローカルタイムラインと同一なので)
---
 .../api/endpoints/notes/global-timeline.ts     |  8 ++++++++
 .../api/endpoints/notes/hybrid-timeline.ts     |  6 ++++++
 .../api/endpoints/notes/local-timeline.ts      |  8 ++++++++
 .../api/stream/channels/global-timeline.ts     |  6 ++++++
 .../api/stream/channels/hybrid-timeline.ts     |  4 ++++
 .../api/stream/channels/local-timeline.ts      |  6 ++++++
 src/stream.ts                                  | 18 ------------------
 7 files changed, 38 insertions(+), 18 deletions(-)

diff --git a/src/server/api/endpoints/notes/global-timeline.ts b/src/server/api/endpoints/notes/global-timeline.ts
index b7f765f27d..f5fd0d6dd8 100644
--- a/src/server/api/endpoints/notes/global-timeline.ts
+++ b/src/server/api/endpoints/notes/global-timeline.ts
@@ -4,6 +4,7 @@ import Mute from '../../../../models/mute';
 import { packMany } from '../../../../models/note';
 import define from '../../define';
 import { countIf } from '../../../../prelude/array';
+import fetchMeta from '../../../../misc/fetch-meta';
 
 export const meta = {
 	desc: {
@@ -51,6 +52,13 @@ export const meta = {
 };
 
 export default define(meta, (ps, user) => new Promise(async (res, rej) => {
+	const meta = await fetchMeta();
+	if (meta.disableLocalTimeline) {
+		if (user == null || (!user.isAdmin && !user.isModerator)) {
+			return rej('local timeline disabled');
+		}
+	}
+
 	// Check if only one of sinceId, untilId, sinceDate, untilDate specified
 	if (countIf(x => x != null, [ps.sinceId, ps.untilId, ps.sinceDate, ps.untilDate]) > 1) {
 		return rej('only one of sinceId, untilId, sinceDate, untilDate can be specified');
diff --git a/src/server/api/endpoints/notes/hybrid-timeline.ts b/src/server/api/endpoints/notes/hybrid-timeline.ts
index 7cf05cb9a8..20855e5139 100644
--- a/src/server/api/endpoints/notes/hybrid-timeline.ts
+++ b/src/server/api/endpoints/notes/hybrid-timeline.ts
@@ -5,6 +5,7 @@ import { getFriends } from '../../common/get-friends';
 import { packMany } from '../../../../models/note';
 import define from '../../define';
 import { countIf } from '../../../../prelude/array';
+import fetchMeta from '../../../../misc/fetch-meta';
 
 export const meta = {
 	desc: {
@@ -91,6 +92,11 @@ export const meta = {
 };
 
 export default define(meta, (ps, user) => new Promise(async (res, rej) => {
+	const meta = await fetchMeta();
+	if (meta.disableLocalTimeline && !user.isAdmin && !user.isModerator) {
+		return rej('local timeline disabled');
+	}
+
 	// Check if only one of sinceId, untilId, sinceDate, untilDate specified
 	if (countIf(x => x != null, [ps.sinceId, ps.untilId, ps.sinceDate, ps.untilDate]) > 1) {
 		return rej('only one of sinceId, untilId, sinceDate, untilDate can be specified');
diff --git a/src/server/api/endpoints/notes/local-timeline.ts b/src/server/api/endpoints/notes/local-timeline.ts
index 4446f52cdc..30d2762ad5 100644
--- a/src/server/api/endpoints/notes/local-timeline.ts
+++ b/src/server/api/endpoints/notes/local-timeline.ts
@@ -4,6 +4,7 @@ import Mute from '../../../../models/mute';
 import { packMany } from '../../../../models/note';
 import define from '../../define';
 import { countIf } from '../../../../prelude/array';
+import fetchMeta from '../../../../misc/fetch-meta';
 
 export const meta = {
 	desc: {
@@ -66,6 +67,13 @@ export const meta = {
 };
 
 export default define(meta, (ps, user) => new Promise(async (res, rej) => {
+	const meta = await fetchMeta();
+	if (meta.disableLocalTimeline) {
+		if (user == null || (!user.isAdmin && !user.isModerator)) {
+			return rej('local timeline disabled');
+		}
+	}
+
 	// Check if only one of sinceId, untilId, sinceDate, untilDate specified
 	if (countIf(x => x != null, [ps.sinceId, ps.untilId, ps.sinceDate, ps.untilDate]) > 1) {
 		return rej('only one of sinceId, untilId, sinceDate, untilDate can be specified');
diff --git a/src/server/api/stream/channels/global-timeline.ts b/src/server/api/stream/channels/global-timeline.ts
index c5499801ed..611d5a6aef 100644
--- a/src/server/api/stream/channels/global-timeline.ts
+++ b/src/server/api/stream/channels/global-timeline.ts
@@ -3,6 +3,7 @@ import Mute from '../../../../models/mute';
 import { pack } from '../../../../models/note';
 import shouldMuteThisNote from '../../../../misc/should-mute-this-note';
 import Channel from '../channel';
+import fetchMeta from '../../../../misc/fetch-meta';
 
 export default class extends Channel {
 	public readonly chName = 'globalTimeline';
@@ -13,6 +14,11 @@ export default class extends Channel {
 
 	@autobind
 	public async init(params: any) {
+		const meta = await fetchMeta();
+		if (meta.disableLocalTimeline) {
+			if (this.user == null || (!this.user.isAdmin && !this.user.isModerator)) return;
+		}
+
 		// Subscribe events
 		this.subscriber.on('globalTimeline', this.onNote);
 
diff --git a/src/server/api/stream/channels/hybrid-timeline.ts b/src/server/api/stream/channels/hybrid-timeline.ts
index 15a516b0c0..e573d27ee8 100644
--- a/src/server/api/stream/channels/hybrid-timeline.ts
+++ b/src/server/api/stream/channels/hybrid-timeline.ts
@@ -3,6 +3,7 @@ import Mute from '../../../../models/mute';
 import { pack } from '../../../../models/note';
 import shouldMuteThisNote from '../../../../misc/should-mute-this-note';
 import Channel from '../channel';
+import fetchMeta from '../../../../misc/fetch-meta';
 
 export default class extends Channel {
 	public readonly chName = 'hybridTimeline';
@@ -13,6 +14,9 @@ export default class extends Channel {
 
 	@autobind
 	public async init(params: any) {
+		const meta = await fetchMeta();
+		if (meta.disableLocalTimeline && !this.user.isAdmin && !this.user.isModerator) return;
+
 		// Subscribe events
 		this.subscriber.on('hybridTimeline', this.onNewNote);
 		this.subscriber.on(`hybridTimeline:${this.user._id}`, this.onNewNote);
diff --git a/src/server/api/stream/channels/local-timeline.ts b/src/server/api/stream/channels/local-timeline.ts
index a26f71af8e..8e490677d3 100644
--- a/src/server/api/stream/channels/local-timeline.ts
+++ b/src/server/api/stream/channels/local-timeline.ts
@@ -3,6 +3,7 @@ import Mute from '../../../../models/mute';
 import { pack } from '../../../../models/note';
 import shouldMuteThisNote from '../../../../misc/should-mute-this-note';
 import Channel from '../channel';
+import fetchMeta from '../../../../misc/fetch-meta';
 
 export default class extends Channel {
 	public readonly chName = 'localTimeline';
@@ -13,6 +14,11 @@ export default class extends Channel {
 
 	@autobind
 	public async init(params: any) {
+		const meta = await fetchMeta();
+		if (meta.disableLocalTimeline) {
+			if (this.user == null || (!this.user.isAdmin && !this.user.isModerator)) return;
+		}
+
 		// Subscribe events
 		this.subscriber.on('localTimeline', this.onNote);
 
diff --git a/src/stream.ts b/src/stream.ts
index 8ca8c3254c..596cb98e72 100644
--- a/src/stream.ts
+++ b/src/stream.ts
@@ -1,31 +1,17 @@
 import * as mongo from 'mongodb';
 import redis from './db/redis';
 import Xev from 'xev';
-import { IMeta } from './models/meta';
-import fetchMeta from './misc/fetch-meta';
 
 type ID = string | mongo.ObjectID;
 
 class Publisher {
 	private ev: Xev;
-	private meta: IMeta;
 
 	constructor() {
 		// Redisがインストールされてないときはプロセス間通信を使う
 		if (redis == null) {
 			this.ev = new Xev();
 		}
-
-		setInterval(async () => {
-			this.meta = await fetchMeta();
-		}, 5000);
-	}
-
-	public fetchMeta = async () => {
-		if (this.meta != null) return this.meta;
-
-		this.meta = await fetchMeta();
-		return this.meta;
 	}
 
 	private publish = (channel: string, type: string, value?: any): void => {
@@ -83,14 +69,10 @@ class Publisher {
 	}
 
 	public publishLocalTimelineStream = async (note: any): Promise<void> => {
-		const meta = await this.fetchMeta();
-		if (meta.disableLocalTimeline) return;
 		this.publish('localTimeline', null, note);
 	}
 
 	public publishHybridTimelineStream = async (userId: ID, note: any): Promise<void> => {
-		const meta = await this.fetchMeta();
-		if (meta.disableLocalTimeline) return;
 		this.publish(userId ? `hybridTimeline:${userId}` : 'hybridTimeline', null, note);
 	}