win_root_set.go 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. // package win_root_set -- задаёт рутовый пароль на приложение
  2. package win_root_set
  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_set.html
  15. var strWinHtml string
  16. // WinRootMake -- задаёт рутовый пароль на приложение
  17. type WinRootMake struct {
  18. desktop types.IDesktop
  19. store types.IStore
  20. win lorca.UI
  21. ws types.IWebSocket
  22. rootPass string // Пароль рута из формы
  23. block sync.Mutex
  24. }
  25. // NewWinRootMake -- возвращает новое окно пароля для рута
  26. func NewWinRootMake(desktop types.IDesktop) (*WinRootMake, error) {
  27. if desktop == nil {
  28. return nil, fmt.Errorf("NewWinRootMake(): IDesktop == nil")
  29. }
  30. sf := &WinRootMake{
  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("WinRoot(): in create win, err=\n\t%w", err)
  43. }
  44. go sf.close()
  45. return sf, nil
  46. }
  47. // GetPass -- возвращает полученный пароль из формы
  48. func (sf *WinRootMake) GetPass() string {
  49. fnCheck := func() bool {
  50. sf.block.Lock()
  51. defer sf.block.Unlock()
  52. return len(sf.rootPass) > 7
  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. // SetError -- устанавливает признак ошибки при операциях с паролем
  62. func (sf *WinRootMake) SetError(err error) {
  63. js := fmt.Sprintf(`
  64. function SetErrorSave(){
  65. var _el=document.getElementById("/root/password/err");
  66. _el.innerText="WinRootMake.onSetPass(): ошибка передачи при сохранении пароля, err=\n\t%v"
  67. }
  68. SetErrorSave()`, err)
  69. sf.win.Eval(js)
  70. }
  71. func (sf *WinRootMake) Close() {
  72. sf.win.Close()
  73. }
  74. // Работает в отдельном потоке, главный цикл окна
  75. func (sf *WinRootMake) Run() {
  76. log.Println("WinRootMake.Run()")
  77. sf.win.Bind("close_win", sf.onClose)
  78. sf.win.Bind("set_pass", sf.onSetPass)
  79. <-sf.win.Done() // Ожидание закрытия окна
  80. }
  81. // Сохраняет пароль рута
  82. func (sf *WinRootMake) onSetPass() {
  83. log.Printf("WinRootMake.onSetPass()\n")
  84. sf.block.Lock()
  85. defer sf.block.Unlock()
  86. sf.rootPass = sf.win.Eval(`document.getElementById("/root/password/val").value`).String()
  87. if len(sf.rootPass) < 8 {
  88. js := `
  89. function SetError(){
  90. var _el=document.getElementById("/root/password/err");
  91. _el.innerText="WinRootMake.onSetPass(): пароль слишком короткий"
  92. }
  93. SetError()
  94. `
  95. sf.win.Eval(js)
  96. return
  97. }
  98. js := `
  99. function ResetError(){
  100. var _el=document.getElementById("/root/password/err");
  101. _el.innerText=""
  102. }
  103. ResetError()
  104. `
  105. sf.win.Eval(js)
  106. log.Printf("WinRootMake.onSetPass(): pass=%q\n", sf.rootPass)
  107. }
  108. // Закрывает приложение
  109. func (sf *WinRootMake) onClose() {
  110. log.Println("WinRootMake.onClose()")
  111. sf.win.Close()
  112. }
  113. // close -- ожидает отмены глобального контекста
  114. func (sf *WinRootMake) close() {
  115. <-sf.desktop.CtxApp().Done()
  116. log.Println("WinRootMake.close()")
  117. sf.win.Close()
  118. }