security-setting.js 55 KB

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