caldav_init.go 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. package main
  2. /*
  3. caldav_init.go - CalDAV server initialisation
  4. Registers the CalDAV handler at /caldav/ and a /.well-known/caldav
  5. redirect so iOS can auto-discover the calendar service.
  6. Also registers /api/caldav/credentials (authenticated) which returns
  7. the CalDAV URL and auto-generates an auto-login token for the calling
  8. user, giving them a ready-to-use password for iOS Calendar setup.
  9. */
  10. import (
  11. "encoding/json"
  12. "net/http"
  13. "imuslab.com/arozos/mod/caldav"
  14. "imuslab.com/arozos/mod/info/logger"
  15. prout "imuslab.com/arozos/mod/prouter"
  16. "imuslab.com/arozos/mod/utils"
  17. )
  18. // CalDAVHandler is the global CalDAV HTTP handler.
  19. var CalDAVHandler *caldav.Handler
  20. // CalDAVInit initialises the CalDAV server and registers API endpoints.
  21. // It must be called after AuthInit() and UserSystemInit().
  22. func CalDAVInit() {
  23. CalDAVHandler = caldav.NewHandler(caldav.HandlerOptions{
  24. AuthAgent: authAgent,
  25. UserHandler: userHandler,
  26. Prefix: "/caldav",
  27. })
  28. // Credentials helper – authenticated, non-admin endpoint so any logged-in
  29. // user can retrieve their own CalDAV connection details.
  30. router := prout.NewModuleRouter(prout.RouterOption{
  31. ModuleName: "Calendar",
  32. AdminOnly: false,
  33. UserHandler: userHandler,
  34. DeniedHandler: func(w http.ResponseWriter, r *http.Request) {
  35. utils.SendErrorResponse(w, "Permission Denied")
  36. },
  37. })
  38. router.HandleFunc("/api/caldav/credentials", handleCalDAVCredentials)
  39. logger.PrintAndLog("CalDAV", "CalDAV service started at /caldav/", nil)
  40. }
  41. // handleCalDAVCredentials returns the CalDAV server URL, username and an
  42. // auto-login token the caller can use as a CalDAV password on iOS.
  43. func handleCalDAVCredentials(w http.ResponseWriter, r *http.Request) {
  44. username, err := authAgent.GetUserName(w, r)
  45. if err != nil {
  46. utils.SendErrorResponse(w, "Unable to get username")
  47. return
  48. }
  49. // Re-use an existing token if available, otherwise mint a new one.
  50. existing := authAgent.GetTokensFromUsername(username)
  51. var token string
  52. if len(existing) > 0 {
  53. token = existing[0].Token
  54. } else {
  55. token = authAgent.NewAutologinToken(username)
  56. }
  57. scheme := "http"
  58. if r.TLS != nil {
  59. scheme = "https"
  60. }
  61. serverURL := scheme + "://" + r.Host + "/caldav/"
  62. type credResponse struct {
  63. ServerURL string `json:"serverURL"`
  64. Username string `json:"username"`
  65. Token string `json:"token"`
  66. }
  67. w.Header().Set("Content-Type", "application/json")
  68. json.NewEncoder(w).Encode(credResponse{
  69. ServerURL: serverURL,
  70. Username: username,
  71. Token: token,
  72. })
  73. }