security-setting.js 43 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934
  1. /* eslint-disable max-len */
  2. /* eslint-disable no-unused-vars */
  3. const loggerFactory = require('@alias/logger');
  4. const logger = loggerFactory('growi:routes:apiv3:security-setting');
  5. const express = require('express');
  6. const router = express.Router();
  7. const { body } = require('express-validator/check');
  8. const ErrorV3 = require('../../models/vo/error-apiv3');
  9. const validator = {
  10. // TODO correct validator
  11. generalSetting: [
  12. body('restrictGuestMode').isString(),
  13. body('pageCompleteDeletionAuthority').isString(),
  14. body('hideRestrictedByOwner').isBoolean(),
  15. body('hideRestrictedByGroup').isBoolean(),
  16. ],
  17. authenticationSetting: [
  18. body('isEnabled').isBoolean(),
  19. body('auth').isString().isIn([
  20. 'Local', 'Ldap', 'Saml', 'Oidc', 'Basic', 'Google', 'GitHub', 'Twitter',
  21. ]),
  22. ],
  23. localSetting: [
  24. body('isLocalEnabled').isBoolean(),
  25. body('registrationMode').isString(),
  26. body('registrationWhiteList').isArray(),
  27. ],
  28. ldapAuth: [
  29. body('serverUrl').isString(),
  30. body('isUserBind').isBoolean(),
  31. body('ldapBindDN').isString(),
  32. body('ldapBindDNPassword').isString(),
  33. body('ldapSearchFilter').isString(),
  34. body('ldapAttrMapUsername').isString(),
  35. body('isSameUsernameTreatedAsIdenticalUser').isBoolean(),
  36. body('ldapAttrMapMail').isString(),
  37. body('ldapAttrMapName').isString(),
  38. body('ldapGroupSearchBase').isString(),
  39. body('ldapGroupSearchFilter').isString(),
  40. body('ldapGroupDnProperty').isString(),
  41. ],
  42. samlAuth: [
  43. body('samlEntryPoint').isString(),
  44. body('samlIssuer').isString(),
  45. body('samlCert').isString(),
  46. body('samlAttrMapId').isString(),
  47. body('samlAttrMapUserName').isString(),
  48. body('samlAttrMapMail').isString(),
  49. body('samlAttrMapFirstName').isString(),
  50. body('samlAttrMapLastName').isString(),
  51. body('isSameUsernameTreatedAsIdenticalUser').isBoolean(),
  52. body('isSameEmailTreatedAsIdenticalUser').isBoolean(),
  53. ],
  54. oidcAuth: [
  55. body('oidcProviderName').isString(),
  56. body('oidcIssuerHost').isString(),
  57. body('oidcClientId').isString(),
  58. body('oidcClientSecret').isString(),
  59. body('oidcAttrMapId').isString(),
  60. body('oidcAttrMapUserName').isString(),
  61. body('oidcAttrMapEmail').isString(),
  62. body('isSameUsernameTreatedAsIdenticalUser').isBoolean(),
  63. body('isSameEmailTreatedAsIdenticalUser').isBoolean(),
  64. ],
  65. basicAuth: [
  66. body('isSameUsernameTreatedAsIdenticalUser').isBoolean(),
  67. ],
  68. googleOAuth: [
  69. body('googleClientId').isString(),
  70. body('googleClientSecret').isString(),
  71. body('isSameUsernameTreatedAsIdenticalUser').isBoolean(),
  72. ],
  73. githubOAuth: [
  74. body('githubClientId').isString(),
  75. body('githubClientSecret').isString(),
  76. body('isSameUsernameTreatedAsIdenticalUser').isBoolean(),
  77. ],
  78. twitterOAuth: [
  79. body('twitterConsumerKey').isString(),
  80. body('twitterConsumerSecret').isString(),
  81. body('isSameUsernameTreatedAsIdenticalUser').isBoolean(),
  82. ],
  83. };
  84. /**
  85. * @swagger
  86. * tags:
  87. * name: SecuritySetting
  88. */
  89. /**
  90. * @swagger
  91. *
  92. * components:
  93. * schemas:
  94. * GeneralSetting:
  95. * type: object
  96. * properties:
  97. * restrictGuestMode:
  98. * type: string
  99. * description: type of restrictGuestMode
  100. * pageCompleteDeletionAuthority:
  101. * type: string
  102. * description: type of pageDeletionAuthority
  103. * hideRestrictedByOwner:
  104. * type: boolean
  105. * description: enable hide by owner
  106. * hideRestrictedByGroup:
  107. * type: boolean
  108. * description: enable hide by group
  109. * LocalSetting:
  110. * type: object
  111. * properties:
  112. * isLocalEnabled:
  113. * type: boolean
  114. * description: local setting mode
  115. * registrationMode:
  116. * type: string
  117. * description: type of registrationMode
  118. * registrationWhiteList:
  119. * type: array
  120. * description: array of regsitrationList
  121. * items:
  122. * type: string
  123. * description: registration whiteList
  124. * LdapAuthSetting:
  125. * type: object
  126. * properties:
  127. * serverUrl:
  128. * type: string
  129. * description: server url for ldap
  130. * isUserBind:
  131. * type: boolean
  132. * description: enable user bind
  133. * ldapBindDN:
  134. * type: string
  135. * description: the query used to bind with the directory service
  136. * ldapBindDNPassword:
  137. * type: string
  138. * description: the password that is entered in the login page will be used to bind
  139. * ldapSearchFilter:
  140. * type: string
  141. * description: the query used to locate the authenticated user
  142. * ldapAttrMapUsername:
  143. * type: string
  144. * description: specification of mappings for username when creating new users
  145. * isSameUsernameTreatedAsIdenticalUser:
  146. * type: boolean
  147. * description: local account automatically linked the user name matched
  148. * ldapAttrMapMail:
  149. * type: string
  150. * description: specification of mappings for mail address when creating new users
  151. * ldapAttrMapName:
  152. * type: string
  153. * description: Specification of mappings for full name address when creating new users
  154. * ldapGroupSearchBase:
  155. * type: string
  156. * description: the base DN from which to search for groups.
  157. * ldapGroupSearchFilter:
  158. * type: string
  159. * description: the query used to filter for groups
  160. * ldapGroupDnProperty:
  161. * type: string
  162. * description: The property of user object to use in dn interpolation of Group Search Filter
  163. * SamlAuthSetting:
  164. * type: object
  165. * properties:
  166. * samlEntryPoint:
  167. * type: string
  168. * description: entry point for saml
  169. * samlIssuer:
  170. * type: string
  171. * description: issuer for saml
  172. * samlCert:
  173. * type: string
  174. * description: certificate for saml
  175. * samlAttrMapId:
  176. * type: string
  177. * description: attribute mapping id for saml
  178. * samlAttrMapUserName:
  179. * type: string
  180. * description: attribute mapping user name for saml
  181. * samlAttrMapMail:
  182. * type: string
  183. * description: attribute mapping mail for saml
  184. * samlAttrMapFirstName:
  185. * type: string
  186. * description: attribute mapping first name for saml
  187. * samlAttrMapLastName:
  188. * type: string
  189. * description: attribute mapping last name for saml
  190. * isSameUsernameTreatedAsIdenticalUser:
  191. * type: boolean
  192. * description: local account automatically linked the user name matched
  193. * isSameEmailTreatedAsIdenticalUser:
  194. * type: boolean
  195. * description: local account automatically linked the email matched
  196. * OidcAuthSetting:
  197. * type: object
  198. * properties:
  199. * oidcProviderName:
  200. * type: string
  201. * description: provider name for oidc
  202. * oidcIssuerHost:
  203. * type: string
  204. * description: issuer host for oidc
  205. * oidcClientId:
  206. * type: string
  207. * description: client id for oidc
  208. * oidcClientSecret:
  209. * type: string
  210. * description: client secret for oidc
  211. * oidcAttrMapId:
  212. * type: string
  213. * description: attr map id for oidc
  214. * oidcAttrMapUserName:
  215. * type: string
  216. * description: attr map username for oidc
  217. * oidcAttrMapName:
  218. * type: string
  219. * description: attr map name for oidc
  220. * oidcAttrMapMail:
  221. * type: string
  222. * description: attr map mail for oidc
  223. * isSameUsernameTreatedAsIdenticalUser:
  224. * type: boolean
  225. * description: local account automatically linked the user name matched
  226. * isSameEmailTreatedAsIdenticalUser:
  227. * type: boolean
  228. * description: local account automatically linked the email matched
  229. * BasicAuthSetting:
  230. * type: object
  231. * properties:
  232. * isSameUsernameTreatedAsIdenticalUser:
  233. * type: boolean
  234. * description: local account automatically linked the email matched
  235. * GitHubOAuthSetting:
  236. * type: object
  237. * properties:
  238. * githubClientId:
  239. * type: string
  240. * description: key of comsumer
  241. * githubClientSecret:
  242. * type: string
  243. * description: password of comsumer
  244. * isSameUsernameTreatedAsIdenticalUser:
  245. * type: boolean
  246. * description: local account automatically linked the email matched
  247. * GoogleOAuthSetting:
  248. * type: object
  249. * properties:
  250. * googleClientId:
  251. * type: string
  252. * description: key of comsumer
  253. * googleClientSecret:
  254. * type: string
  255. * description: password of comsumer
  256. * isSameUsernameTreatedAsIdenticalUser:
  257. * type: boolean
  258. * description: local account automatically linked the email matched
  259. * TwitterOAuthSetting:
  260. * type: object
  261. * properties:
  262. * twitterConsumerKey:
  263. * type: string
  264. * description: key of comsumer
  265. * twitterConsumerSecret:
  266. * type: string
  267. * description: password of comsumer
  268. * isSameUsernameTreatedAsIdenticalUser:
  269. * type: boolean
  270. * description: local account automatically linked the email matched
  271. */
  272. module.exports = (crowi) => {
  273. const loginRequiredStrictly = require('../../middleware/login-required')(crowi);
  274. const adminRequired = require('../../middleware/admin-required')(crowi);
  275. const csrf = require('../../middleware/csrf')(crowi);
  276. const { ApiV3FormValidator } = crowi.middlewares;
  277. /**
  278. * @swagger
  279. *
  280. * /_api/v3/security-setting/:
  281. * get:
  282. * tags: [SecuritySetting]
  283. * description: Get security paramators
  284. * responses:
  285. * 200:
  286. * description: params of security
  287. * content:
  288. * application/json:
  289. * schema:
  290. * properties:
  291. * securityParams:
  292. * type: object
  293. * description: security params
  294. */
  295. router.get('/', loginRequiredStrictly, adminRequired, async(req, res) => {
  296. const securityParams = {
  297. generalSetting: {
  298. restrictGuestMode: await crowi.configManager.getConfig('crowi', 'security:restrictGuestMode'),
  299. pageCompleteDeletionAuthority: await crowi.configManager.getConfig('crowi', 'security:pageCompleteDeletionAuthority'),
  300. hideRestrictedByOwner: await crowi.configManager.getConfig('crowi', 'security:list-policy:hideRestrictedByOwner'),
  301. hideRestrictedByGroup: await crowi.configManager.getConfig('crowi', 'security:list-policy:hideRestrictedByGroup'),
  302. wikiMode: await crowi.configManager.getConfig('crowi', 'security:wikiMode'),
  303. },
  304. localSetting: {
  305. isLocalEnabled: await crowi.configManager.getConfig('crowi', 'security:passport-local:isEnabled'),
  306. registrationMode: await crowi.configManager.getConfig('crowi', 'security:registrationMode'),
  307. registrationWhiteList: await crowi.configManager.getConfig('crowi', 'security:registrationWhiteList'),
  308. },
  309. generalAuth: {
  310. isLdapEnabled: await crowi.configManager.getConfig('crowi', 'security:passport-ldap:isEnabled'),
  311. isSamlEnabled: await crowi.configManager.getConfig('crowi', 'security:passport-saml:isEnabled'),
  312. isOidcEnabled: await crowi.configManager.getConfig('crowi', 'security:passport-oidc:isEnabled'),
  313. isBasicEnabled: await crowi.configManager.getConfig('crowi', 'security:passport-basic:isEnabled'),
  314. isGoogleOAuthEnabled: await crowi.configManager.getConfig('crowi', 'security:passport-google:isEnabled'),
  315. isGithubOAuthEnabled: await crowi.configManager.getConfig('crowi', 'security:passport-github:isEnabled'),
  316. isTwitterOAuthEnabled: await crowi.configManager.getConfig('crowi', 'security:passport-twitter:isEnabled'),
  317. },
  318. ldapAuth: {
  319. serverUrl: await crowi.configManager.getConfig('crowi', 'security:passport-ldap:serverUrl'),
  320. isUserBind: await crowi.configManager.getConfig('crowi', 'security:passport-ldap:isUserBind'),
  321. ldapBindDN: await crowi.configManager.getConfig('crowi', 'security:passport-ldap:bindDN'),
  322. ldapBindDNPassword: await crowi.configManager.getConfig('crowi', 'security:passport-ldap:bindDNPassword'),
  323. ldapSearchFilter: await crowi.configManager.getConfig('crowi', 'security:passport-ldap:searchFilter'),
  324. ldapAttrMapUsername: await crowi.configManager.getConfig('crowi', 'security:passport-ldap:attrMapUsername'),
  325. isSameUsernameTreatedAsIdenticalUser: await crowi.configManager.getConfig('crowi', 'security:passport-ldap:isSameUsernameTreatedAsIdenticalUser'),
  326. ldapAttrMapMail: await crowi.configManager.getConfig('crowi', 'security:passport-ldap:attrMapMail'),
  327. ldapAttrMapName: await crowi.configManager.getConfig('crowi', 'security:passport-ldap:attrMapName'),
  328. ldapGroupSearchBase: await crowi.configManager.getConfig('crowi', 'security:passport-ldap:groupSearchBase'),
  329. ldapGroupSearchFilter: await crowi.configManager.getConfig('crowi', 'security:passport-ldap:groupSearchFilter'),
  330. ldapGroupDnProperty: await crowi.configManager.getConfig('crowi', 'security:passport-ldap:groupDnProperty'),
  331. },
  332. samlAuth: {
  333. missingMandatoryConfigKeys: await crowi.passportService.getSamlMissingMandatoryConfigKeys(),
  334. samlEntryPoint: await crowi.configManager.getConfigFromDB('crowi', 'security:passport-saml:entryPoint'),
  335. samlEnvVarEntryPoint: await crowi.configManager.getConfigFromEnvVars('crowi', 'security:passport-saml:entryPoint'),
  336. samlIssuer: await crowi.configManager.getConfigFromDB('crowi', 'security:passport-saml:issuer'),
  337. samlEnvVarIssuer: await crowi.configManager.getConfigFromEnvVars('crowi', 'security:passport-saml:issuer'),
  338. samlCert: await crowi.configManager.getConfigFromDB('crowi', 'security:passport-saml:cert'),
  339. samlEnvVarCert: await crowi.configManager.getConfigFromEnvVars('crowi', 'security:passport-saml:cert'),
  340. samlAttrMapId: await crowi.configManager.getConfigFromDB('crowi', 'security:passport-saml:attrMapId'),
  341. samlEnvVarAttrMapId: await crowi.configManager.getConfigFromEnvVars('crowi', 'security:passport-saml:attrMapId'),
  342. samlAttrMapUserName: await crowi.configManager.getConfigFromDB('crowi', 'security:passport-saml:attrMapUsername'),
  343. samlEnvVarAttrMapUserName: await crowi.configManager.getConfigFromEnvVars('crowi', 'security:passport-saml:attrMapUsername'),
  344. samlAttrMapMail: await crowi.configManager.getConfigFromDB('crowi', 'security:passport-saml:attrMapMail'),
  345. samlEnvVarAttrMapMail: await crowi.configManager.getConfigFromEnvVars('crowi', 'security:passport-saml:attrMapMail'),
  346. samlAttrMapFirstName: await crowi.configManager.getConfigFromDB('crowi', 'security:passport-saml:attrMapFirstName'),
  347. samlEnvVarAttrMapFirstName: await crowi.configManager.getConfigFromEnvVars('crowi', 'security:passport-saml:attrMapFirstName'),
  348. samlAttrMapLastName: await crowi.configManager.getConfigFromDB('crowi', 'security:passport-saml:attrMapLastName'),
  349. samlEnvVarAttrMapLastName: await crowi.configManager.getConfigFromEnvVars('crowi', 'security:passport-saml:attrMapLastName'),
  350. isSameUsernameTreatedAsIdenticalUser: await crowi.configManager.getConfig('crowi', 'security:passport-saml:isSameUsernameTreatedAsIdenticalUser'),
  351. isSameEmailTreatedAsIdenticalUser: await crowi.configManager.getConfig('crowi', 'security:passport-saml:isSameEmailTreatedAsIdenticalUser'),
  352. },
  353. oidcAuth: {
  354. oidcProviderName: await crowi.configManager.getConfig('crowi', 'security:passport-oidc:providerName'),
  355. oidcIssuerHost: await crowi.configManager.getConfig('crowi', 'security:passport-oidc:issuerHost'),
  356. oidcClientId: await crowi.configManager.getConfig('crowi', 'security:passport-oidc:clientId'),
  357. oidcClientSecret: await crowi.configManager.getConfig('crowi', 'security:passport-oidc:clientSecret'),
  358. oidcAttrMapId: await crowi.configManager.getConfig('crowi', 'security:passport-oidc:attrMapId'),
  359. oidcAttrMapUserName: await crowi.configManager.getConfig('crowi', 'security:passport-oidc:attrMapUserName'),
  360. oidcAttrMapName: await crowi.configManager.getConfig('crowi', 'security:passport-oidc:attrMapName'),
  361. oidcAttrMapEmail: await crowi.configManager.getConfig('crowi', 'security:passport-oidc:attrMapMail'),
  362. isSameUsernameTreatedAsIdenticalUser: await crowi.configManager.getConfig('crowi', 'security:passport-oidc:isSameUsernameTreatedAsIdenticalUser'),
  363. isSameEmailTreatedAsIdenticalUser: await crowi.configManager.getConfig('crowi', 'security:passport-oidc:isSameEmailTreatedAsIdenticalUser'),
  364. },
  365. basicAuth: {
  366. isSameUsernameTreatedAsIdenticalUser: await crowi.configManager.getConfig('crowi', 'security:passport-basic:isSameUsernameTreatedAsIdenticalUser'),
  367. },
  368. googleOAuth: {
  369. isGoogleStrategySetup: await crowi.passportService.isGoogleStrategySetup,
  370. googleClientId: await crowi.configManager.getConfig('crowi', 'security:passport-google:clientId'),
  371. googleClientSecret: await crowi.configManager.getConfig('crowi', 'security:passport-google:clientSecret'),
  372. isSameUsernameTreatedAsIdenticalUser: await crowi.configManager.getConfig('crowi', 'security:passport-google:isSameUsernameTreatedAsIdenticalUser'),
  373. },
  374. githubOAuth: {
  375. isGitHubStrategySetup: await crowi.passportService.isGitHubStrategySetup,
  376. githubClientId: await crowi.configManager.getConfig('crowi', 'security:passport-github:clientId'),
  377. githubClientSecret: await crowi.configManager.getConfig('crowi', 'security:passport-github:clientSecret'),
  378. isSameUsernameTreatedAsIdenticalUser: await crowi.configManager.getConfig('crowi', 'security:passport-github:isSameUsernameTreatedAsIdenticalUser'),
  379. },
  380. twitterOAuth: {
  381. isTwitterStrategySetup: await crowi.passportService.isTwitterStrategySetup,
  382. twitterConsumerKey: await crowi.configManager.getConfig('crowi', 'security:passport-twitter:consumerKey'),
  383. twitterConsumerSecret: await crowi.configManager.getConfig('crowi', 'security:passport-twitter:consumerSecret'),
  384. isSameUsernameTreatedAsIdenticalUser: await crowi.configManager.getConfig('crowi', 'security:passport-twitter:isSameUsernameTreatedAsIdenticalUser'),
  385. },
  386. };
  387. return res.apiv3({ securityParams });
  388. });
  389. /**
  390. * @swagger
  391. *
  392. * /_api/v3/security-setting/authentication/enabled:
  393. * put:
  394. * tags: [SecuritySetting]
  395. * description: Update authentication isEnabled
  396. * requestBody:
  397. * required: true
  398. * content:
  399. * application/json:
  400. * schema:
  401. * type: object
  402. * properties:
  403. * isEnabled:
  404. * type: boolean
  405. * target:
  406. * type: string
  407. * responses:
  408. * 200:
  409. * description: Succeeded to enable authentication
  410. * content:
  411. * application/json:
  412. * schema:
  413. * type: object
  414. * description: updated param
  415. */
  416. router.put('/authentication/enabled', loginRequiredStrictly, adminRequired, csrf, validator.authenticationSetting, ApiV3FormValidator, async(req, res) => {
  417. const { isEnabled, auth } = req.body;
  418. const authLowerCase = auth.toLowerCase();
  419. let setupStrategies = await crowi.passportService.getSetupStrategies();
  420. // Reflect request param
  421. setupStrategies = setupStrategies.filter(strategy => strategy !== `passport-${authLowerCase}`);
  422. if (setupStrategies.length === 0) {
  423. return res.apiv3Err(new ErrorV3('Can not turn everything off'));
  424. }
  425. const enableParams = { [`security:passport-${authLowerCase}:isEnabled`]: isEnabled };
  426. try {
  427. await crowi.configManager.updateConfigsInTheSameNamespace('crowi', enableParams);
  428. await crowi.passportService.setupStrategyByAuth(auth);
  429. const responseParams = { [`security:passport-${authLowerCase}:isEnabled`]: await crowi.configManager.getConfig('crowi', `security:passport-${authLowerCase}:isEnabled`) };
  430. return res.apiv3({ responseParams });
  431. }
  432. catch (err) {
  433. const msg = 'Error occurred in updating enable setting';
  434. logger.error('Error', err);
  435. return res.apiv3Err(new ErrorV3(msg, 'update-enable-setting failed'));
  436. }
  437. });
  438. /**
  439. * @swagger
  440. *
  441. * /_api/v3/security-setting/general-setting:
  442. * put:
  443. * tags: [SecuritySetting]
  444. * description: Update GeneralSetting
  445. * requestBody:
  446. * required: true
  447. * content:
  448. * application/json:
  449. * schema:
  450. * $ref: '#/components/schemas/GeneralSetting'
  451. * responses:
  452. * 200:
  453. * description: Succeeded to update general Setting
  454. * content:
  455. * application/json:
  456. * schema:
  457. * $ref: '#/components/schemas/GeneralSetting'
  458. */
  459. router.put('/general-setting', loginRequiredStrictly, adminRequired, csrf, validator.generalSetting, ApiV3FormValidator, async(req, res) => {
  460. const requestParams = {
  461. 'security:restrictGuestMode': req.body.restrictGuestMode,
  462. 'security:pageCompleteDeletionAuthority': req.body.pageCompleteDeletionAuthority,
  463. 'security:list-policy:hideRestrictedByOwner': req.body.hideRestrictedByOwner,
  464. 'security:list-policy:hideRestrictedByGroup': req.body.hideRestrictedByGroup,
  465. };
  466. const wikiMode = await crowi.configManager.getConfig('crowi', 'security:wikiMode');
  467. if (wikiMode === 'private') {
  468. logger.debug('security:restrictGuestMode will not be changed because wiki mode is forced to set');
  469. delete requestParams['security:restrictGuestMode'];
  470. }
  471. try {
  472. await crowi.configManager.updateConfigsInTheSameNamespace('crowi', requestParams);
  473. const securitySettingParams = {
  474. restrictGuestMode: await crowi.configManager.getConfig('crowi', 'security:restrictGuestMode'),
  475. pageCompleteDeletionAuthority: await crowi.configManager.getConfig('crowi', 'security:pageCompleteDeletionAuthority'),
  476. hideRestrictedByOwner: await crowi.configManager.getConfig('crowi', 'security:list-policy:hideRestrictedByOwner'),
  477. hideRestrictedByGroup: await crowi.configManager.getConfig('crowi', 'security:list-policy:hideRestrictedByGroup'),
  478. };
  479. return res.apiv3({ securitySettingParams });
  480. }
  481. catch (err) {
  482. const msg = 'Error occurred in updating security setting';
  483. logger.error('Error', err);
  484. return res.apiv3Err(new ErrorV3(msg, 'update-secuirty-setting failed'));
  485. }
  486. });
  487. /**
  488. * @swagger
  489. *
  490. * /_api/v3/security-setting/local-setting:
  491. * put:
  492. * tags: [LocalSetting]
  493. * description: Update LocalSetting
  494. * requestBody:
  495. * required: true
  496. * content:
  497. * application/json:
  498. * schema:
  499. * $ref: '#/components/schemas/LocalSetting'
  500. * responses:
  501. * 200:
  502. * description: Succeeded to update local Setting
  503. * content:
  504. * application/json:
  505. * schema:
  506. * $ref: '#/components/schemas/LocalSetting'
  507. */
  508. router.put('/local-setting', loginRequiredStrictly, adminRequired, csrf, validator.localSetting, ApiV3FormValidator, async(req, res) => {
  509. const requestParams = {
  510. 'security:passport-local:isEnabled': req.body.isLocalEnabled,
  511. 'security:registrationMode': req.body.registrationMode,
  512. 'security:registrationWhiteList': req.body.registrationWhiteList,
  513. };
  514. try {
  515. await crowi.configManager.updateConfigsInTheSameNamespace('crowi', requestParams);
  516. const localSettingParams = {
  517. isLocalEnabled: await crowi.configManager.getConfig('crowi', 'security:passport-local:isEnabled'),
  518. registrationMode: await crowi.configManager.getConfig('crowi', 'security:registrationMode'),
  519. registrationWhiteList: await crowi.configManager.getConfig('crowi', 'security:registrationWhiteList'),
  520. };
  521. return res.apiv3({ localSettingParams });
  522. }
  523. catch (err) {
  524. const msg = 'Error occurred in updating local setting';
  525. logger.error('Error', err);
  526. return res.apiv3Err(new ErrorV3(msg, 'update-local-setting failed'));
  527. }
  528. });
  529. /**
  530. * @swagger
  531. *
  532. * /_api/v3/security-setting/ldap:
  533. * put:
  534. * tags: [SecuritySetting]
  535. * description: Update LDAP setting
  536. * requestBody:
  537. * required: true
  538. * content:
  539. * application/json:
  540. * schema:
  541. * $ref: '#/components/schemas/LdapAuthSetting'
  542. * responses:
  543. * 200:
  544. * description: Succeeded to update LDAP setting
  545. * content:
  546. * application/json:
  547. * schema:
  548. * $ref: '#/components/schemas/LdapAuthSetting'
  549. */
  550. router.put('/ldap', loginRequiredStrictly, adminRequired, csrf, validator.ldapAuth, ApiV3FormValidator, async(req, res) => {
  551. const requestParams = {
  552. 'security:passport-ldap:serverUrl': req.body.serverUrl,
  553. 'security:passport-ldap:isUserBind': req.body.isUserBind,
  554. 'security:passport-ldap:bindDN': req.body.ldapBindDN,
  555. 'security:passport-ldap:bindDNPassword': req.body.ldapBindDNPassword,
  556. 'security:passport-ldap:searchFilter': req.body.ldapSearchFilter,
  557. 'security:passport-ldap:attrMapUsername': req.body.ldapAttrMapUserName,
  558. 'security:passport-ldap:isSameUsernameTreatedAsIdenticalUser': req.body.isSameUsernameTreatedAsIdenticalUser,
  559. 'security:passport-ldap:attrMapMail': req.body.ldapAttrMapMail,
  560. 'security:passport-ldap:attrMapName': req.body.ldapAttrMapName,
  561. 'security:passport-ldap:groupSearchBase': req.body.ldapGroupSearchBase,
  562. 'security:passport-ldap:groupSearchFilter': req.body.ldapGroupSearchFilter,
  563. 'security:passport-ldap:groupDnProperty': req.body.ldapGroupDnProperty,
  564. };
  565. try {
  566. await crowi.configManager.updateConfigsInTheSameNamespace('crowi', requestParams);
  567. const securitySettingParams = {
  568. serverUrl: await crowi.configManager.getConfig('crowi', 'security:passport-ldap:serverUrl'),
  569. isUserBind: await crowi.configManager.getConfig('crowi', 'security:passport-ldap:isUserBind'),
  570. ldapBindDN: await crowi.configManager.getConfig('crowi', 'security:passport-ldap:bindDN'),
  571. ldapBindDNPassword: await crowi.configManager.getConfig('crowi', 'security:passport-ldap:bindDNPassword'),
  572. ldapSearchFilter: await crowi.configManager.getConfig('crowi', 'security:passport-ldap:searchFilter'),
  573. ldapAttrMapUsername: await crowi.configManager.getConfig('crowi', 'security:passport-ldap:attrMapUsername'),
  574. isSameUsernameTreatedAsIdenticalUser: await crowi.configManager.getConfig('crowi', 'security:passport-ldap:isSameUsernameTreatedAsIdenticalUser'),
  575. ldapAttrMapMail: await crowi.configManager.getConfig('crowi', 'security:passport-ldap:attrMapMail'),
  576. ldapAttrMapName: await crowi.configManager.getConfig('crowi', 'security:passport-ldap:attrMapName'),
  577. ldapGroupSearchBase: await crowi.configManager.getConfig('crowi', 'security:passport-ldap:groupSearchBase'),
  578. ldapGroupSearchFilter: await crowi.configManager.getConfig('crowi', 'security:passport-ldap:groupSearchFilter'),
  579. ldapGroupDnProperty: await crowi.configManager.getConfig('crowi', 'security:passport-ldap:groupDnProperty'),
  580. };
  581. return res.apiv3({ securitySettingParams });
  582. }
  583. catch (err) {
  584. const msg = 'Error occurred in updating SAML setting';
  585. logger.error('Error', err);
  586. return res.apiv3Err(new ErrorV3(msg, 'update-SAML-failed'));
  587. }
  588. });
  589. /**
  590. * @swagger
  591. *
  592. * /_api/v3/security-setting/saml:
  593. * put:
  594. * tags: [SecuritySetting]
  595. * description: Update SAML setting
  596. * requestBody:
  597. * required: true
  598. * content:
  599. * application/json:
  600. * schema:
  601. * $ref: '#/components/schemas/SamlAuthSetting'
  602. * responses:
  603. * 200:
  604. * description: Succeeded to update SAML setting
  605. * content:
  606. * application/json:
  607. * schema:
  608. * $ref: '#/components/schemas/SamlAuthSetting'
  609. */
  610. router.put('/saml', loginRequiredStrictly, adminRequired, csrf, validator.samlAuth, ApiV3FormValidator, async(req, res) => {
  611. const requestParams = {
  612. 'security:passport-saml:entryPoint': req.body.samlEntryPoint,
  613. 'security:passport-saml:issuer': req.body.samlIssuer,
  614. 'security:passport-saml:cert': req.body.samlCert,
  615. 'security:passport-saml:attrMapId': req.body.samlAttrMapId,
  616. 'security:passport-saml:attrMapUsername': req.body.samlAttrMapUserName,
  617. 'security:passport-saml:attrMapMail': req.body.samlAttrMapMail,
  618. 'security:passport-saml:attrMapFirstName': req.body.samlAttrMapFirstName,
  619. 'security:passport-saml:attrMapLastName': req.body.samlAttrMapLastName,
  620. 'security:passport-saml:isSameUsernameTreatedAsIdenticalUser': req.body.isSameUsernameTreatedAsIdenticalUser,
  621. 'security:passport-saml:isSameEmailTreatedAsIdenticalUser': req.body.isSameEmailTreatedAsIdenticalUser,
  622. };
  623. try {
  624. await crowi.configManager.updateConfigsInTheSameNamespace('crowi', requestParams);
  625. const securitySettingParams = {
  626. missingMandatoryConfigKeys: await crowi.passportService.getSamlMissingMandatoryConfigKeys(),
  627. samlEntryPoint: await crowi.configManager.getConfigFromDB('crowi', 'security:passport-saml:entryPoint'),
  628. samlIssuer: await crowi.configManager.getConfigFromDB('crowi', 'security:passport-saml:issuer'),
  629. samlCert: await crowi.configManager.getConfigFromDB('crowi', 'security:passport-saml:cert'),
  630. samlAttrMapId: await crowi.configManager.getConfigFromDB('crowi', 'security:passport-saml:attrMapId'),
  631. samlAttrMapUserName: await crowi.configManager.getConfigFromDB('crowi', 'security:passport-saml:attrMapUsername'),
  632. samlAttrMapMail: await crowi.configManager.getConfigFromDB('crowi', 'security:passport-saml:attrMapMail'),
  633. samlAttrMapFirstName: await crowi.configManager.getConfigFromDB('crowi', 'security:passport-saml:attrMapFirstName'),
  634. samlAttrMapLastName: await crowi.configManager.getConfigFromDB('crowi', 'security:passport-saml:attrMapLastName'),
  635. isSameUsernameTreatedAsIdenticalUser: await crowi.configManager.getConfig('crowi', 'security:passport-saml:isSameUsernameTreatedAsIdenticalUser'),
  636. isSameEmailTreatedAsIdenticalUser: await crowi.configManager.getConfig('crowi', 'security:passport-saml:isSameEmailTreatedAsIdenticalUser'),
  637. };
  638. return res.apiv3({ securitySettingParams });
  639. }
  640. catch (err) {
  641. const msg = 'Error occurred in updating SAML setting';
  642. logger.error('Error', err);
  643. return res.apiv3Err(new ErrorV3(msg, 'update-SAML-failed'));
  644. }
  645. });
  646. /**
  647. * @swagger
  648. *
  649. * /_api/v3/security-setting/oidc:
  650. * put:
  651. * tags: [SecuritySetting]
  652. * description: Update OpenID Connect setting
  653. * requestBody:
  654. * required: true
  655. * content:
  656. * application/json:
  657. * schema:
  658. * $ref: '#/components/schemas/OidcAuthSetting'
  659. * responses:
  660. * 200:
  661. * description: Succeeded to update OpenID Connect setting
  662. * content:
  663. * application/json:
  664. * schema:
  665. * $ref: '#/components/schemas/OidcAuthSetting'
  666. */
  667. router.put('/oidc', loginRequiredStrictly, adminRequired, csrf, validator.oidcAuth, ApiV3FormValidator, async(req, res) => {
  668. const requestParams = {
  669. 'security:passport-oidc:providerName': req.body.oidcProviderName,
  670. 'security:passport-oidc:issuerHost': req.body.oidcIssuerHost,
  671. 'security:passport-oidc:clientId': req.body.oidcClientId,
  672. 'security:passport-oidc:clientSecret': req.body.oidcClientSecret,
  673. 'security:passport-oidc:attrMapId': req.body.oidcAttrMapId,
  674. 'security:passport-oidc:attrMapUserName': req.body.oidcAttrMapUserName,
  675. 'security:passport-oidc:attrMapName': req.body.oidcAttrMapName,
  676. 'security:passport-oidc:attrMapMail': req.body.oidcAttrMapEmail,
  677. 'security:passport-oidc:isSameUsernameTreatedAsIdenticalUser': req.body.isSameUsernameTreatedAsIdenticalUser,
  678. 'security:passport-oidc:isSameEmailTreatedAsIdenticalUser': req.body.isSameEmailTreatedAsIdenticalUser,
  679. };
  680. try {
  681. await crowi.configManager.updateConfigsInTheSameNamespace('crowi', requestParams);
  682. const securitySettingParams = {
  683. oidcProviderName: await crowi.configManager.getConfig('crowi', 'security:passport-oidc:providerName'),
  684. oidcIssuerHost: await crowi.configManager.getConfig('crowi', 'security:passport-oidc:issuerHost'),
  685. oidcClientId: await crowi.configManager.getConfig('crowi', 'security:passport-oidc:clientId'),
  686. oidcClientSecret: await crowi.configManager.getConfig('crowi', 'security:passport-oidc:clientSecret'),
  687. oidcAttrMapId: await crowi.configManager.getConfig('crowi', 'security:passport-oidc:attrMapId'),
  688. oidcAttrMapUserName: await crowi.configManager.getConfig('crowi', 'security:passport-oidc:attrMapUserName'),
  689. oidcAttrMapName: await crowi.configManager.getConfig('crowi', 'security:passport-oidc:attrMapName'),
  690. oidcAttrMapEmail: await crowi.configManager.getConfig('crowi', 'security:passport-oidc:attrMapMail'),
  691. isSameUsernameTreatedAsIdenticalUser: await crowi.configManager.getConfig('crowi', 'security:passport-oidc:isSameUsernameTreatedAsIdenticalUser'),
  692. isSameEmailTreatedAsIdenticalUser: await crowi.configManager.getConfig('crowi', 'security:passport-oidc:isSameEmailTreatedAsIdenticalUser'),
  693. };
  694. return res.apiv3({ securitySettingParams });
  695. }
  696. catch (err) {
  697. const msg = 'Error occurred in updating OpenIDConnect';
  698. logger.error('Error', err);
  699. return res.apiv3Err(new ErrorV3(msg, 'update-OpenIDConnect-failed'));
  700. }
  701. });
  702. /**
  703. * @swagger
  704. *
  705. * /_api/v3/security-setting/basic:
  706. * put:
  707. * tags: [SecuritySetting]
  708. * description: Update basic
  709. * requestBody:
  710. * required: true
  711. * content:
  712. * application/json:
  713. * schema:
  714. * $ref: '#/components/schemas/BasicAuthSetting'
  715. * responses:
  716. * 200:
  717. * description: Succeeded to update basic
  718. * content:
  719. * application/json:
  720. * schema:
  721. * $ref: '#/components/schemas/BasicAuthSetting'
  722. */
  723. router.put('/basic', loginRequiredStrictly, adminRequired, csrf, validator.basicAuth, ApiV3FormValidator, async(req, res) => {
  724. const requestParams = {
  725. 'security:passport-basic:isSameUsernameTreatedAsIdenticalUser': req.body.isSameUsernameTreatedAsIdenticalUser,
  726. };
  727. try {
  728. await crowi.configManager.updateConfigsInTheSameNamespace('crowi', requestParams);
  729. const securitySettingParams = {
  730. isSameUsernameTreatedAsIdenticalUser: await crowi.configManager.getConfig('crowi', 'security:passport-basic:isSameUsernameTreatedAsIdenticalUser'),
  731. };
  732. return res.apiv3({ securitySettingParams });
  733. }
  734. catch (err) {
  735. const msg = 'Error occurred in updating basicAuth';
  736. logger.error('Error', err);
  737. return res.apiv3Err(new ErrorV3(msg, 'update-basicOAuth-failed'));
  738. }
  739. });
  740. /**
  741. * @swagger
  742. *
  743. * /_api/v3/security-setting/google-oauth:
  744. * put:
  745. * tags: [SecuritySetting]
  746. * description: Update google OAuth
  747. * requestBody:
  748. * required: true
  749. * content:
  750. * application/json:
  751. * schema:
  752. * $ref: '#/components/schemas/GoogleOAuthSetting'
  753. * responses:
  754. * 200:
  755. * description: Succeeded to google OAuth
  756. * content:
  757. * application/json:
  758. * schema:
  759. * $ref: '#/components/schemas/GoogleOAuthSetting'
  760. */
  761. router.put('/google-oauth', loginRequiredStrictly, adminRequired, csrf, validator.googleOAuth, ApiV3FormValidator, async(req, res) => {
  762. const requestParams = {
  763. 'security:passport-google:clientId': req.body.googleClientId,
  764. 'security:passport-google:clientSecret': req.body.googleClientSecret,
  765. 'security:passport-google:isSameUsernameTreatedAsIdenticalUser': req.body.isSameUsernameTreatedAsIdenticalUser,
  766. };
  767. try {
  768. await crowi.configManager.updateConfigsInTheSameNamespace('crowi', requestParams);
  769. const securitySettingParams = {
  770. isGoogleOAuthEnabled: await crowi.configManager.getConfig('crowi', 'security:passport-google:isEnabled'),
  771. googleClientId: await crowi.configManager.getConfig('crowi', 'security:passport-google:clientId'),
  772. googleClientSecret: await crowi.configManager.getConfig('crowi', 'security:passport-google:clientSecret'),
  773. isSameUsernameTreatedAsIdenticalUser: await crowi.configManager.getConfig('crowi', 'security:passport-google:isSameUsernameTreatedAsIdenticalUser'),
  774. };
  775. // reset strategy
  776. await crowi.passportService.resetGoogleStrategy();
  777. // setup strategy
  778. if (crowi.configManager.getConfig('crowi', 'security:passport-google:isEnabled')) {
  779. await crowi.passportService.setupGoogleStrategy(true);
  780. }
  781. return res.apiv3({ securitySettingParams });
  782. }
  783. catch (err) {
  784. // reset strategy
  785. await crowi.passportService.resetGoogleStrategy();
  786. const msg = 'Error occurred in updating googleOAuth';
  787. logger.error('Error', err);
  788. return res.apiv3Err(new ErrorV3(msg, 'update-googleOAuth-failed'));
  789. }
  790. });
  791. /**
  792. * @swagger
  793. *
  794. * /_api/v3/security-setting/github-oauth:
  795. * put:
  796. * tags: [SecuritySetting]
  797. * description: Update github OAuth
  798. * requestBody:
  799. * required: true
  800. * content:
  801. * application/json:
  802. * schema:
  803. * $ref: '#/components/schemas/GitHubOAuthSetting'
  804. * responses:
  805. * 200:
  806. * description: Succeeded to github OAuth
  807. * content:
  808. * application/json:
  809. * schema:
  810. * $ref: '#/components/schemas/GitHubOAuthSetting'
  811. */
  812. router.put('/github-oauth', loginRequiredStrictly, adminRequired, csrf, validator.githubOAuth, ApiV3FormValidator, async(req, res) => {
  813. const requestParams = {
  814. 'security:passport-github:clientId': req.body.githubClientId,
  815. 'security:passport-github:clientSecret': req.body.githubClientSecret,
  816. 'security:passport-github:isSameUsernameTreatedAsIdenticalUser': req.body.isSameUsernameTreatedAsIdenticalUser,
  817. };
  818. try {
  819. await crowi.configManager.updateConfigsInTheSameNamespace('crowi', requestParams);
  820. const securitySettingParams = {
  821. isGitHubStrategySetup: await crowi.passportService.isGitHubStrategySetup,
  822. githubClientId: await crowi.configManager.getConfig('crowi', 'security:passport-github:clientId'),
  823. githubClientSecret: await crowi.configManager.getConfig('crowi', 'security:passport-github:clientSecret'),
  824. isSameUsernameTreatedAsIdenticalUser: await crowi.configManager.getConfig('crowi', 'security:passport-github:isSameUsernameTreatedAsIdenticalUser'),
  825. };
  826. // reset strategy
  827. await crowi.passportService.resetGitHubStrategy();
  828. // setup strategy
  829. if (crowi.configManager.getConfig('crowi', 'security:passport-github:isEnabled')) {
  830. await crowi.passportService.setupGitHubStrategy(true);
  831. }
  832. return res.apiv3({ securitySettingParams });
  833. }
  834. catch (err) {
  835. // reset strategy
  836. await crowi.passportService.resetGitHubStrategy();
  837. const msg = 'Error occurred in updating githubOAuth';
  838. logger.error('Error', err);
  839. return res.apiv3Err(new ErrorV3(msg, 'update-githubOAuth-failed'));
  840. }
  841. });
  842. /**
  843. * @swagger
  844. *
  845. * /_api/v3/security-setting/twitter-oauth:
  846. * put:
  847. * tags: [SecuritySetting]
  848. * description: Update twitter OAuth
  849. * requestBody:
  850. * required: true
  851. * content:
  852. * application/json:
  853. * schema:
  854. * $ref: '#/components/schemas/TwitterOAuthSetting'
  855. * responses:
  856. * 200:
  857. * description: Succeeded to update twitter OAuth
  858. * content:
  859. * application/json:
  860. * schema:
  861. * $ref: '#/components/schemas/TwitterOAuthSetting'
  862. */
  863. router.put('/twitter-oauth', loginRequiredStrictly, adminRequired, csrf, validator.twitterOAuth, ApiV3FormValidator, async(req, res) => {
  864. const requestParams = {
  865. 'security:passport-twitter:consumerKey': req.body.twitterConsumerKey,
  866. 'security:passport-twitter:consumerSecret': req.body.twitterConsumerSecret,
  867. 'security:passport-twitter:isSameUsernameTreatedAsIdenticalUser': req.body.isSameUsernameTreatedAsIdenticalUser,
  868. };
  869. try {
  870. await crowi.configManager.updateConfigsInTheSameNamespace('crowi', requestParams);
  871. const securitySettingParams = {
  872. isTwitterStrategySetup: await crowi.passportService.isTwitterStrategySetup,
  873. twitterConsumerId: await crowi.configManager.getConfig('crowi', 'security:passport-twitter:consumerKey'),
  874. twitterConsumerSecret: await crowi.configManager.getConfig('crowi', 'security:passport-twitter:consumerSecret'),
  875. isSameUsernameTreatedAsIdenticalUser: await crowi.configManager.getConfig('crowi', 'security:passport-twitter:isSameUsernameTreatedAsIdenticalUser'),
  876. };
  877. // reset strategy
  878. await crowi.passportService.resetTwitterStrategy();
  879. // setup strategy
  880. if (crowi.configManager.getConfig('crowi', 'security:passport-twitter:isEnabled')) {
  881. await crowi.passportService.setupTwitterStrategy(true);
  882. }
  883. return res.apiv3({ securitySettingParams });
  884. }
  885. catch (err) {
  886. // reset strategy
  887. await crowi.passportService.resetTwitterStrategy();
  888. const msg = 'Error occurred in updating twitterOAuth';
  889. logger.error('Error', err);
  890. return res.apiv3Err(new ErrorV3(msg, 'update-twitterOAuth-failed'));
  891. }
  892. });
  893. return router;
  894. };