UNPKG

7.33 kBJavaScriptView Raw
1"use strict";
2Object.defineProperty(exports, "__esModule", { value: true });
3const axios_1 = require("axios");
4const _ = require("lodash");
5const decorators_1 = require("./decorators");
6const decoratorSupport_1 = require("./internal/metadata/decoratorSupport");
7const constructionUtils_1 = require("./util/constructionUtils");
8const UnAuthorizedResult = Promise.resolve({ code: 403, message: "Access denied" });
9/**
10 * Protect the given HandleCommand by only allowing access for certain slack users
11 * @param {Maker<HandleCommand>} maker
12 * @param {string} users
13 * @returns {() => HandleCommand}
14 */
15function slackUser(maker, ...users) {
16 return () => {
17 const command = constructionUtils_1.toFactory(maker)();
18 decoratorSupport_1.declareMappedParameter(command, "__atomist_slack_user_name", decorators_1.MappedParameters.SlackUserName, true);
19 const handleMethod = command.handle;
20 command.handle = (ctx) => {
21 if (users.indexOf(command.__atomist_slack_user_name) < 0) {
22 return UnAuthorizedResult;
23 }
24 else {
25 return handleMethod.bind(command, ctx)(ctx);
26 }
27 };
28 return command;
29 };
30}
31exports.slackUser = slackUser;
32/**
33 * Protect the given HandleCommand by only allowing members of a certain GitHub Organization
34 * @param {Maker<HandleCommand>} maker
35 * @param {string} team
36 * @returns {() => HandleCommand}
37 */
38function githubOrg(maker, org) {
39 return () => {
40 const command = constructionUtils_1.toFactory(maker)();
41 decoratorSupport_1.declareMappedParameter(command, "__atomist_github_login", decorators_1.MappedParameters.GitHubUserLogin, false);
42 decoratorSupport_1.declareSecret(command, "__atomist_user_token", decorators_1.Secrets.userToken("read:org"));
43 const handleMethod = command.handle;
44 command.handle = (ctx) => {
45 const login = command.__atomist_github_login;
46 const token = command.__atomist_user_token;
47 if (!login) {
48 return sendUnauthorized(ctx);
49 }
50 return isGitHubOrgMember(org, login, token)
51 .then(isOrgMember => {
52 if (isOrgMember === true) {
53 return handleMethod.bind(command, ctx)(ctx);
54 }
55 else {
56 return sendUnauthorized(ctx);
57 }
58 })
59 .catch(err => {
60 return sendUnauthorized(ctx);
61 });
62 };
63 return command;
64 };
65}
66exports.githubOrg = githubOrg;
67function isGitHubOrgMember(org, login, token) {
68 if (login) {
69 const config = {
70 headers: {
71 Authorization: `token ${token}`,
72 Accept: "application/vnd.github.hellcat-preview+json",
73 },
74 };
75 return axios_1.default.get(`https://api.github.com/orgs/${org}/members/${login}`, config)
76 .then(result => {
77 return result.status === 204;
78 })
79 .catch(() => {
80 return false;
81 });
82 }
83 else {
84 return Promise.resolve(false);
85 }
86}
87const ProviderForOrgQuery = `query ProviderForOrg($owner: String!) {
88 Org(owner: $owner) {
89 provider {
90 apiUrl
91 providerType
92 }
93 }
94}
95`;
96/**
97 * Protect the given HandleCommand by only allowing members of a certain GitHub team
98 * @param {Maker<HandleCommand>} maker
99 * @param {string} team
100 * @returns {() => HandleCommand}
101 */
102function githubTeam(maker, gTeam) {
103 return () => {
104 const command = constructionUtils_1.toFactory(maker)();
105 decoratorSupport_1.declareMappedParameter(command, "__atomist_github_owner", decorators_1.MappedParameters.GitHubOwner, false);
106 decoratorSupport_1.declareMappedParameter(command, "__atomist_github_login", decorators_1.MappedParameters.GitHubUserLogin, false);
107 decoratorSupport_1.declareSecret(command, "__atomist_user_token", decorators_1.Secrets.userToken("read:org"));
108 const handleMethod = command.handle;
109 command.handle = (ctx) => {
110 const owner = command.__atomist_github_owner;
111 const login = command.__atomist_github_login;
112 const token = command.__atomist_user_token;
113 if (!owner) {
114 return sendUnauthorized(ctx);
115 }
116 return ctx.graphClient.query({
117 query: ProviderForOrgQuery,
118 variables: {
119 owner,
120 },
121 })
122 .then(providerResult => {
123 const provider = _.get(providerResult, "Org[0].provider.providerType");
124 const apiUrl = _.get(providerResult, "Org[0].provider.apiUrl");
125 if (provider === "github_com" || provider === "ghe") {
126 if (!owner || !login) {
127 return sendUnauthorized(ctx);
128 }
129 return isGitHubTeamMember(owner, login, gTeam, token, apiUrl)
130 .then(isTeamMember => {
131 if (isTeamMember === true) {
132 return handleMethod.bind(command, ctx)(ctx);
133 }
134 else {
135 return sendUnauthorized(ctx);
136 }
137 })
138 .catch(err => {
139 return sendUnauthorized(ctx);
140 });
141 }
142 else {
143 return handleMethod.bind(command, ctx)(ctx);
144 }
145 });
146 };
147 return command;
148 };
149}
150exports.githubTeam = githubTeam;
151function isGitHubTeamMember(owner, login, team, token, apiUrl = "https://api.github.com/") {
152 if (login) {
153 const config = {
154 headers: {
155 Authorization: `token ${token}`,
156 Accept: "application/vnd.github.hellcat-preview+json",
157 },
158 };
159 return axios_1.default.get(`${apiUrl}orgs/${owner}/teams`, config)
160 .then(gitHubTeams => {
161 return gitHubTeams.data.find(t => t.name === team);
162 })
163 .then(gitHubTeam => {
164 if (gitHubTeam) {
165 return axios_1.default.get(`${apiUrl}teams/${gitHubTeam.id}/memberships/${login}`, config)
166 .then(() => {
167 return true;
168 })
169 .catch(() => {
170 return false;
171 });
172 }
173 else {
174 return false;
175 }
176 })
177 .catch(() => {
178 return false;
179 });
180 }
181 else {
182 return Promise.resolve(false);
183 }
184}
185exports.isGitHubTeamMember = isGitHubTeamMember;
186function sendUnauthorized(ctx) {
187 const msg = {
188 attachments: [{
189 author_icon: `https://images.atomist.com/rug/cross-circle.png`,
190 author_name: "Unauthorized to run command",
191 fallback: "Unauthorized",
192 color: "#D94649",
193 footer: `Correlation ID: ${ctx.invocationId}`,
194 }],
195 };
196 return ctx.messageClient.respond(msg)
197 .then(() => UnAuthorizedResult);
198}
199exports.sendUnauthorized = sendUnauthorized;
200//# sourceMappingURL=secured.js.map
\No newline at end of file