Gitter migration: Setup redirects (rollout pt. 3)
[gitter.git] / modules / uri-resolver / lib / uri-lookup-service.js
blob407bb822baf8c0f47c11379794e76ef2c81e956f
1 'use strict';
3 /**
4 * URI lookup service is a supersimple service for managing who owns what URIs
6 * It is separate from uri-service as that would create circular dependencies
7 */
9 var persistence = require('gitter-web-persistence');
10 var Promise = require('bluebird');
11 var mongoUtils = require('gitter-web-persistence-utils/lib/mongo-utils');
12 var debug = require('debug')('gitter:app:uri-lookup-service');
13 const mongoReadPrefs = require('gitter-web-persistence-utils/lib/mongo-read-prefs');
14 const discoverMatrixDmUri = require('gitter-web-matrix-bridge/lib/discover-matrix-dm-uri');
16 /**
17 * For exporting things
19 function getCursorByUserId(userId) {
20 const cursor = persistence.UriLookup.find({
21 userId
23 .lean()
24 .read(mongoReadPrefs.secondaryPreferred)
25 .batchSize(100)
26 .cursor();
28 return cursor;
31 function discoverUserUri(uri) {
32 // Double-check the troupe and user tables to find this uri
33 var repoStyle = uri.indexOf('/') >= 0;
35 if (repoStyle) return null;
37 return persistence.User.findOne({ username: uri }, 'username', { lean: true }).exec();
40 function discoverRoomUri(lcUri) {
41 return persistence.Troupe.findOne({ lcUri: lcUri }, 'uri', { lean: true }).exec();
44 function discoverGroupUri(lcUri) {
45 return persistence.Group.findOne(
46 { lcHomeUri: lcUri },
48 homeUri: 1
51 lean: true
53 ).exec();
56 function discoverUri(uri) {
57 var lcUri = uri.toLowerCase();
59 debug('Attempting to search through users and troupes to find %s', uri);
61 return Promise.join(
62 discoverUserUri(uri),
63 discoverRoomUri(lcUri),
64 discoverGroupUri(lcUri),
65 discoverMatrixDmUri(lcUri),
66 function(user, troupe, group, matrixDm) {
67 debug('Found user=%s troupe=%s group=%s', !!user, !!troupe, !!group);
69 /* Found user. Add to cache and continue */
70 if (user) {
71 return reserveUriForUsername(user._id, user.username);
74 if (troupe) {
75 return reserveUriForTroupeId(troupe._id, troupe.uri);
78 if (group) {
79 return reserveUriForGroupId(group._id, group.homeUri);
82 if (matrixDm) {
83 return {
84 uri,
85 virtualUserId: matrixDm.virtualUserId,
86 userId: matrixDm.gitterUserId
90 /* Last ditch attempt. Look for a room that has been renamed */
91 /* TODO: look for users who have been renamed too */
92 return persistence.Troupe.findOne(
93 { renamedLcUris: lcUri },
94 { uri: 1, lcUri: 1 },
95 { lean: true }
97 .exec()
98 .then(function(renamedTroupe) {
99 if (!renamedTroupe) return null;
100 debug('Room %s has been renamed to %s', lcUri, renamedTroupe.lcUri);
102 /* Don't save this lookup */
103 return { uri: renamedTroupe.lcUri, troupeId: renamedTroupe._id };
110 * Lookup the owner of a URI
111 * @return promise of a UriLookup
113 function lookupUri(uri) {
114 var lcUri = uri.toLowerCase();
116 debug('URI lookup: %s', uri);
118 return persistence.UriLookup.findOne({ uri: lcUri })
119 .exec()
120 .then(function(uriLookup) {
121 debug('URI lookup returned a result? %s', !!uriLookup);
123 if (uriLookup && (uriLookup.userId || uriLookup.troupeId || uriLookup.groupId))
124 return uriLookup;
126 return discoverUri(uri);
131 * Remove the username for a user
132 * @return promise of nothing
134 function removeUsernameForUserId(userId) {
135 return persistence.UriLookup.findOneAndRemove({ userId: userId }).exec();
138 function reserveUriForUsername(userId, username) {
139 debug('Reserve URI: userId=%s, username=%s', userId, username);
141 var lcUri = username.toLowerCase();
142 userId = mongoUtils.asObjectID(userId);
144 return persistence.UriLookup.findOneAndUpdate(
146 $or: [
148 uri: lcUri
151 userId: userId
156 $set: {
157 uri: lcUri,
158 userId: userId
160 $unset: {
161 troupeId: true,
162 groupId: true
166 upsert: true,
167 new: true
169 ).exec();
172 function removeBadUri(uri) {
173 var lcUri = uri.toLowerCase();
175 return persistence.UriLookup.remove({ uri: lcUri }).exec();
178 function reserveUriForTroupeId(troupeId, uri) {
179 debug('Reserve URI: troupeId=%s, uri=%s', troupeId, uri);
181 var lcUri = uri.toLowerCase();
182 troupeId = mongoUtils.asObjectID(troupeId);
184 return persistence.UriLookup.findOneAndUpdate(
186 $or: [
188 uri: lcUri
191 troupeId: troupeId
196 $set: {
197 uri: lcUri,
198 troupeId: troupeId
200 $unset: {
201 userId: true,
202 groupId: true
206 upsert: true,
207 new: true
209 ).exec();
212 function reserveUriForGroupId(groupId, uri) {
213 debug('Reserve URI: groupId=%s, uri=%s', groupId, uri);
215 var lcUri = uri.toLowerCase();
216 groupId = mongoUtils.asObjectID(groupId);
218 return persistence.UriLookup.findOneAndUpdate(
220 $or: [
222 uri: lcUri
225 groupId: groupId
230 $set: {
231 uri: lcUri,
232 groupId: groupId
234 $unset: {
235 userId: true,
236 troupeId: true
240 upsert: true,
241 new: true
243 ).exec();
246 module.exports = {
247 getCursorByUserId,
248 reserveUriForTroupeId: reserveUriForTroupeId,
249 reserveUriForGroupId: reserveUriForGroupId,
250 lookupUri: lookupUri,
251 removeUsernameForUserId: removeUsernameForUserId,
252 reserveUriForUsername: reserveUriForUsername,
253 removeBadUri: removeBadUri