2
0

security-setting.js 46 KB

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