security-setting.js 47 KB

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