security-setting.js 52 KB

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