security-setting.js 52 KB

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