initidp.go 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. // Copyright 2019 Yunion
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package saml
  15. import (
  16. "context"
  17. "fmt"
  18. "yunion.io/x/log"
  19. "yunion.io/x/pkg/appctx"
  20. "yunion.io/x/pkg/errors"
  21. "yunion.io/x/pkg/util/samlutils"
  22. "yunion.io/x/onecloud/pkg/appsrv"
  23. "yunion.io/x/onecloud/pkg/cloudid/models"
  24. "yunion.io/x/onecloud/pkg/cloudid/options"
  25. "yunion.io/x/onecloud/pkg/httperrors"
  26. "yunion.io/x/onecloud/pkg/i18n"
  27. "yunion.io/x/onecloud/pkg/mcclient/auth"
  28. "yunion.io/x/onecloud/pkg/util/samlutils/idp"
  29. )
  30. func initSAMLIdp(app *appsrv.Application, prefix string) error {
  31. spFunc := func(ctx context.Context, idpId string, sp *idp.SSAMLServiceProvider) (samlutils.SSAMLSpInitiatedLoginData, error) {
  32. token := auth.FetchUserCredential(ctx, nil)
  33. log.Debugf("Recive SP initiated Login: %s", sp.GetEntityId())
  34. data := samlutils.SSAMLSpInitiatedLoginData{}
  35. driver := models.FindDriver(sp.GetEntityId())
  36. if driver == nil {
  37. return data, errors.Wrapf(httperrors.ErrResourceNotFound, "entityID %s not found", sp.GetEntityId())
  38. }
  39. data, err := driver.GetSpInitiatedLoginData(ctx, token, idpId, sp)
  40. if err != nil {
  41. return data, errors.Wrap(err, "driver.GetSpInitiatedLoginData")
  42. }
  43. return data, nil
  44. }
  45. idpFunc := func(ctx context.Context, sp *idp.SSAMLServiceProvider, idpId, redirectUrl string) (samlutils.SSAMLIdpInitiatedLoginData, error) {
  46. token := auth.FetchUserCredential(ctx, nil)
  47. log.Debugf("Recive IDP initiated Login: %s", sp.GetEntityId())
  48. data := samlutils.SSAMLIdpInitiatedLoginData{}
  49. driver := models.FindDriver(sp.GetEntityId())
  50. if driver == nil {
  51. return data, errors.Wrapf(httperrors.ErrResourceNotFound, "entityID %s not found", sp.GetEntityId())
  52. }
  53. data, err := driver.GetIdpInitiatedLoginData(ctx, token, idpId, sp, redirectUrl)
  54. if err != nil {
  55. return data, errors.Wrap(err, "driver.GetIdpInitiatedLoginData")
  56. }
  57. return data, nil
  58. }
  59. logoutFunc := func(ctx context.Context, idpId string) string {
  60. switch appctx.AppContextLang(ctx) {
  61. case "zh-CN":
  62. return fmt.Sprintf(`<!DOCTYPE html><html lang="zh_CN"><head><meta charset="utf-8"><meta http-equiv="Content-Type" content="text/html; charset=utf-8"></head><body><h1>成功退出登录,<a href="%s">重新登录</a></h1></body></html>`, options.Options.ApiServer)
  63. default:
  64. return fmt.Sprintf(`<!DOCTYPE html><html lang="zh_CN"><head><meta charset="utf-8"><meta http-equiv="Content-Type" content="text/html; charset=utf-8"></head><body><h1>Log out successfully,<a href="%s">Login again</a></h1></body></html>`, options.Options.ApiServer)
  65. }
  66. }
  67. idpInst := idp.NewIdpInstance(saml, spFunc, idpFunc, logoutFunc)
  68. for _, drvFactory := range models.AllDrivers() {
  69. metaBytes, err := models.GetMetadata(drvFactory)
  70. if err != nil {
  71. return err
  72. }
  73. err = idpInst.AddSPMetadata(metaBytes)
  74. if err != nil {
  75. return errors.Wrapf(err, "AddSPMetadata %s", metaBytes)
  76. }
  77. }
  78. idpInst.AddHandlers(app, prefix, auth.Authenticate)
  79. idpInst.SetHtmlTemplate(i18n.NewTableEntry().CN(`<!DOCTYPE html><html lang="zh"><head><meta charset="utf-8"><meta http-equiv="Content-Type" content="text/html; charset=utf-8"></head><body><h1>正在跳转到云控制台,请等待。。。</h1>$FORM$</body></html>`).EN(`<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta http-equiv="Content-Type" content="text/html; charset=utf-8"></head><body><h1>Login into to the cloud console, please wait。。。</h1>$FORM$</body></html>`))
  80. idpInstance = idpInst
  81. return nil
  82. }