win_root_login.go 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. // package win_root_login -- запрашивает рутовый пароль при запуске
  2. package win_root_login
  3. import (
  4. _ "embed"
  5. "fmt"
  6. "log"
  7. "net/url"
  8. "runtime"
  9. "sync"
  10. "time"
  11. "github.com/zserge/lorca"
  12. "wartank/pkg/types"
  13. )
  14. //go:embed win_root_login.html
  15. var strWinHtml string
  16. // WinRootLogin -- запрашивает рутовый пароль на приложение
  17. type WinRootLogin struct {
  18. desktop types.IDesktop
  19. store types.IStore
  20. win lorca.UI
  21. ws types.IWebSocket
  22. block sync.Mutex
  23. rootPass string
  24. }
  25. // NewWinRootLogin -- возвращает новое окно запроса пароля для рута
  26. func NewWinRootLogin(desktop types.IDesktop) (*WinRootLogin, error) {
  27. if desktop == nil {
  28. return nil, fmt.Errorf("NewWinRootLogin(): IDesktop == nil")
  29. }
  30. sf := &WinRootLogin{
  31. desktop: desktop,
  32. store: desktop.Store(),
  33. ws: desktop.Ws(),
  34. }
  35. args := []string{}
  36. if runtime.GOOS == "linux" {
  37. args = append(args, "--class=Lorca")
  38. }
  39. var err error
  40. sf.win, err = lorca.New("data:text/html,"+url.PathEscape(strWinHtml), "", 640, 480, args...)
  41. if err != nil {
  42. return nil, fmt.Errorf("NewWinRootLogin(): in create win, err=\n\t%w", err)
  43. }
  44. go sf.close()
  45. return sf, nil
  46. }
  47. // GetPass -- возвращает полученный пароль из формы
  48. func (sf *WinRootLogin) GetPass() string {
  49. fnCheck := func() bool {
  50. sf.block.Lock()
  51. defer sf.block.Unlock()
  52. return sf.rootPass == ""
  53. }
  54. for fnCheck() {
  55. time.Sleep(time.Millisecond * 20)
  56. }
  57. sf.block.Lock()
  58. defer sf.block.Unlock()
  59. return sf.rootPass
  60. }
  61. func (sf *WinRootLogin) SetError(err error) {
  62. js := fmt.Sprintf(`
  63. function SetErrorGet(){
  64. var _el=document.getElementById("/root/password/err");
  65. _el.innerText="WinRootLogin.onCheckPass(): ошибка проверки пароля, err=\n\t%v"
  66. }
  67. SetErrorGet()
  68. `, err)
  69. sf.win.Eval(js)
  70. }
  71. func (sf *WinRootLogin) Close() {
  72. sf.win.Close()
  73. }
  74. // Работает в отдельном потоке, главный цикл окна
  75. func (sf *WinRootLogin) Run() {
  76. log.Println("WinRootLogin.Run()")
  77. sf.win.Bind("check_pass", sf.onCheckPass)
  78. <-sf.win.Done() // Ожидание закрытия окна
  79. }
  80. // Проверяет пароль рута
  81. func (sf *WinRootLogin) onCheckPass() {
  82. log.Printf("WinRootLogin.onCheckPass()\n")
  83. sf.block.Lock()
  84. defer sf.block.Unlock()
  85. sf.rootPass = sf.win.Eval(`document.getElementById("/root/password/val").value`).String()
  86. }
  87. // close -- ожидает отмены глобального контекста
  88. func (sf *WinRootLogin) close() {
  89. <-sf.desktop.CtxApp().Done()
  90. log.Println("WinRoot.close()")
  91. sf.win.Close()
  92. }