Gitter migration: Setup redirects (rollout pt. 3)
[gitter.git] / modules / groups / lib / group-uri-checker.js
blob3679ce260ec491a295650737c939f16cf51f9029
1 'use strict';
3 var Promise = require('bluebird');
4 var StatusError = require('statuserror');
5 var Group = require('gitter-web-persistence').Group;
6 var validateGithubUri = require('gitter-web-github').GitHubUriValidator;
7 var validateGroupUri = require('gitter-web-validators/lib/validate-group-uri');
8 var debug = require('debug')('gitter:app:groups:group-uri-checker');
9 var policyFactory = require('gitter-web-permissions/lib/policy-factory');
11 function checkLocalUri(uri) {
13 NOTE: When adding a repo room and we're upserting group, then that
14 user probably already exists locally, but we should be able to add a
15 group for that user anyway. This is how upserting user groups for repo
16 rooms has been working for some time and the new create community flow
17 isn't live yet, so safe to just disable this for now.
20 return Promise.join(
21 User.findOne({ username: uri }).exec(),
22 Group.findOne({ lcUri: uri.toLowerCase() }).exec(),
23 function(user, group) {
24 debug("user: %s, group: %s", !!user, !!group);
25 return !!(user || group);
29 return Group.findOne({ lcUri: uri.toLowerCase() })
30 .exec()
31 .then(function(group) {
32 debug('group for %s: %s', uri.toLowerCase(), !!group);
33 return !!group;
34 });
37 function checkGitHubUri(user, uri, obtainAccessFromGitHubRepo) {
38 // check gh orgs and users
39 return validateGithubUri(user, uri).then(function(githubInfo) {
40 var policy;
41 if (githubInfo && githubInfo.type === 'ORG') {
42 // also check if you can actually admin the org.
45 NOTE: This checks the uri which might not be the same as the group's
46 eventual linkPath. Once we drop the extra checks after we split from
47 GitHub this canAdmin check will fall away and the only one left will
48 be the one inside groupService.createGroup that will test if you're
49 allowed to access linkPath.
51 policy = policyFactory.getPreCreationPolicyEvaluatorWithRepoFallback(
52 user,
53 'GH_ORG',
54 uri,
55 obtainAccessFromGitHubRepo
57 return policy.canAdmin().then(function(access) {
58 return {
59 githubInfo: githubInfo,
60 canAdmin: access
62 });
63 } else if (githubInfo && githubInfo.type === 'USER') {
65 When adding a repo room we have to upsert the group for now. In that
66 case you could be adding a repo under your own name, so we have to
67 check for that and allow that too. At least for now.
69 policy = policyFactory.getPreCreationPolicyEvaluatorWithRepoFallback(
70 user,
71 'GH_USER',
72 uri,
73 obtainAccessFromGitHubRepo
75 return policy
76 .canAdmin()
77 .then(function(access) {
78 return {
79 githubInfo: githubInfo,
80 canAdmin: access
83 .catch(StatusError, function(err) {
84 debug('StatusError', err.message);
85 // User and group do not match, and obtainAccessFromGitHubRepo
86 // not provided, denying access
87 return {
88 githubInfo: githubInfo,
89 canAdmin: false
91 });
92 } else {
93 // either not found or not an org, so no reason to check permission
94 return {
95 githubInfo: githubInfo,
96 canAdmin: false // more like N/A
99 });
102 function checkIfGroupUriExists(user, uri, obtainAccessFromGitHubRepo) {
103 // check length, chars, reserved namespaces, slashes..
104 if (!validateGroupUri(uri)) throw new StatusError(400);
106 debug('checking %s', uri);
108 return Promise.join(
109 checkLocalUri(uri),
110 // TODO: Remove after we split from GitHub URIs (#github-uri-split)
111 checkGitHubUri(user, uri, obtainAccessFromGitHubRepo),
112 function(localUriExists, info) {
113 var githubInfo = info && info.githubInfo;
114 var githubUriExists = !!githubInfo;
116 debug('localUriExists: %s, githubUriExists: %s', localUriExists, githubUriExists);
118 var allowCreate = false;
119 if (localUriExists) {
120 allowCreate = false;
121 } else if (githubUriExists) {
122 // Until we split from GitHub: If it is a github uri it can only be an
123 // org or user and you have to have admin rights for you to be able to
124 // create a community for it.
125 debug('github type: %s, canAdmin: %s', githubInfo.type, info.canAdmin);
126 allowCreate = info.canAdmin;
127 } else {
128 // if it doesn't exist locally AND it doesn't exist on github, then
129 // the user is definitely allowed to create it.
130 allowCreate = true;
133 let type = null;
134 switch (githubInfo && githubInfo.type) {
135 case 'ORG':
136 type = 'GH_ORG';
137 break;
138 case 'REPO':
139 type = 'GH_REPO';
140 break;
141 case 'USER':
142 type = 'GH_USER';
143 break;
146 return {
147 // The future group will either be org-based or of type null which
148 // is just the new types that aren't backed by GitHub.
149 type,
150 allowCreate: allowCreate,
151 localUriExists: localUriExists
157 module.exports = Promise.method(checkIfGroupUriExists);