admin.py 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. from setux.core.action import Actions, Action
  2. from setux.actions.user import User_
  3. from setux.actions.transfer import Sender
  4. from setux.logger import error
  5. class Sudoer(Action):
  6. '''Add User to sudoers
  7. context:
  8. user : user name
  9. '''
  10. @property
  11. def label(self):
  12. return f'Sudoer {self.user}'
  13. def check(self):
  14. grp = self.target.groups.fetch(self.user)
  15. ok = 'wheel' in grp.get()
  16. ret, out, err = self.target.run(f'sudo -l -U {self.user}')
  17. ok = ok and '(ALL) NOPASSWD: ALL' in (line.strip() for line in out)
  18. return ok
  19. def deploy(self):
  20. grp = self.target.groups.fetch(self.user)
  21. grp.add('wheel')
  22. ok = self.target.write(
  23. f'/etc/sudoers.d/{self.user}',
  24. f'{self.user} ALL=(ALL) NOPASSWD: ALL',
  25. )
  26. return ok
  27. class CopyId(Action):
  28. '''Send Public Key to Target
  29. context:
  30. user : User name
  31. pub : Public key
  32. '''
  33. @property
  34. def label(self):
  35. return f'Copy ID {self.user}'
  36. def check(self):
  37. if not getattr(self, 'pub', None): return True
  38. user = self.target.user.fetch(self.user)
  39. if user.check() is not True: return False
  40. pub = self.local.file(self.pub, verbose=False)
  41. if pub.size == 0:
  42. msg = f' ! {pub.key} is empty'
  43. error(msg)
  44. raise SystemExit(msg)
  45. path = f'/home/{self.user}/.ssh/authorized_keys'
  46. autorized = self.target.file.fetch(
  47. path, mode='600', user=self.user, group=user.group.name
  48. )
  49. ok = autorized.check() is True and autorized.size != 0
  50. if ok:
  51. ok = autorized.hash == pub.hash
  52. return ok
  53. def deploy(self):
  54. user = self.target.user.fetch(self.user)
  55. pub = self.local.file(self.pub, verbose=False)
  56. if pub.size == 0:
  57. msg = f' ! {pub.key} is empty'
  58. error(msg)
  59. raise SystemExit(msg)
  60. path = f'/home/{self.user}/.ssh'
  61. ssh = self.target.dir(
  62. path, mode='700', user=self.user, group=user.group.name
  63. )
  64. if ssh.check() is not True: return False
  65. full = f'{path}/authorized_keys'
  66. self.target.run('rm -f {full}', sudo='root')
  67. sent = Sender(self.target, src=self.pub, dst=full, **self.context)()
  68. if sent is not True: return False
  69. key = self.target.file(
  70. full, mode='600', user=self.user, group=user.group.name
  71. )
  72. return key.check() is True and key.size > 0
  73. class Admin(Actions):
  74. '''Set User as sudoer
  75. context:
  76. user : User name
  77. pub : Public key
  78. - Create User if not present
  79. - Add User to sudoers
  80. - Send User's public key
  81. '''
  82. @property
  83. def label(self):
  84. return f'Admin {self.user}'
  85. @property
  86. def actions(self):
  87. return [
  88. User_,
  89. Sudoer,
  90. CopyId,
  91. ]