user.html 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. {{template "base" .}}
  2. {{define "title"}}{{.Title}}{{end}}
  3. {{define "extra_css"}}
  4. <link href="/static/vendor/tempusdominus/css/tempusdominus-bootstrap-4.min.css" rel="stylesheet">
  5. {{end}}
  6. {{define "page_body"}}
  7. <!-- Page Heading -->
  8. <h1 class="h5 mb-4 text-gray-800">{{if .IsAdd}}Add a new user{{else}}Edit user{{end}}</h1>
  9. {{if .Error}}
  10. <div class="card mb-4 border-left-warning">
  11. <div class="card-body text-form-error">{{.Error}}</div>
  12. </div>
  13. {{end}}
  14. <form id="user_form" action="{{.CurrentURL}}" method="POST" autocomplete="off">
  15. <div class="form-group row">
  16. <label for="idUsername" class="col-sm-2 col-form-label">Username</label>
  17. <div class="col-sm-10">
  18. <input type="text" class="form-control" id="idUsername" name="username" placeholder=""
  19. value="{{.User.Username}}" maxlength="255" autocomplete="nope" required
  20. {{if not .IsAdd}}readonly{{end}}>
  21. </div>
  22. </div>
  23. <div class="form-group row">
  24. <label for="idStatus" class="col-sm-2 col-form-label">Status</label>
  25. <div class="col-sm-10">
  26. <select class="form-control" id="idStatus" name="status">
  27. <option value="1" {{if eq .User.Status 1 }}selected{{end}}>Active</option>
  28. <option value="0" {{if eq .User.Status 0 }}selected{{end}}>Inactive</option>
  29. </select>
  30. </div>
  31. </div>
  32. <div class="form-group row">
  33. <label for="idExpirationDate" class="col-sm-2 col-form-label">Expiration Date</label>
  34. <div class="col-sm-10 input-group date" id="expirationDatePicker" data-target-input="nearest">
  35. <input type="text" class="form-control datetimepicker-input" id="idExpirationDate"
  36. data-target="#expirationDatePicker">
  37. <div class="input-group-append" data-target="#expirationDatePicker" data-toggle="datetimepicker">
  38. <div class="input-group-text"><i class="fas fa-calendar"></i></div>
  39. </div>
  40. </div>
  41. </div>
  42. <div class="form-group row">
  43. <label for="idPassword" class="col-sm-2 col-form-label">Password</label>
  44. <div class="col-sm-10">
  45. <input type="password" class="form-control" id="idPassword" name="password" placeholder="" maxlength="255"
  46. autocomplete="new-password" {{if not .IsAdd}}aria-describedby="pwdHelpBlock" {{end}}>
  47. {{if not .IsAdd}}
  48. <small id="pwdHelpBlock" class="form-text text-muted">
  49. If empty the current password will not be changed
  50. </small>
  51. {{end}}
  52. </div>
  53. </div>
  54. <div class="form-group row">
  55. <label for="idPublicKeys" class="col-sm-2 col-form-label">Public keys</label>
  56. <div class="col-sm-10">
  57. <textarea class="form-control" id="idPublicKeys" name="public_keys" rows="3"
  58. aria-describedby="pkHelpBlock">{{range .User.PublicKeys}}{{.}}&#10;{{end}}</textarea>
  59. <small id="pkHelpBlock" class="form-text text-muted">
  60. One public key per line
  61. </small>
  62. </div>
  63. </div>
  64. <div class="form-group row">
  65. <label for="idPermissions" class="col-sm-2 col-form-label">Permissions</label>
  66. <div class="col-sm-10">
  67. <select class="form-control" id="idPermissions" name="permissions" required multiple>
  68. {{range $validPerm := .ValidPerms}}
  69. <option value="{{$validPerm}}"
  70. {{range $perm := $.RootDirPerms }}{{if eq $perm $validPerm}}selected{{end}}{{end}}>{{$validPerm}}
  71. </option>
  72. {{end}}
  73. </select>
  74. </div>
  75. </div>
  76. <div class="form-group row">
  77. <label for="idSubDirsPermissions" class="col-sm-2 col-form-label">Sub dirs permissions</label>
  78. <div class="col-sm-10">
  79. <textarea class="form-control" id="idSubDirsPermissions" name="sub_dirs_permissions" rows="3"
  80. aria-describedby="subDirsHelpBlock">{{range $dir, $perms := .User.Permissions -}}
  81. {{if ne $dir "/" -}}
  82. {{$dir}}:{{range $index, $p := $perms}}{{if $index}},{{end}}{{$p}}{{end}}&#10;
  83. {{- end}}
  84. {{- end}}</textarea>
  85. <small id="subDirsHelpBlock" class="form-text text-muted">
  86. One directory per line as dir:perms, for example /somedir:list,download
  87. </small>
  88. </div>
  89. </div>
  90. <div class="form-group row">
  91. <label for="idHomeDir" class="col-sm-2 col-form-label">Home Dir</label>
  92. <div class="col-sm-10">
  93. <input type="text" class="form-control" id="idHomeDir" name="home_dir" placeholder=""
  94. value="{{.User.HomeDir}}" maxlength="255">
  95. </div>
  96. </div>
  97. <div class="form-group row">
  98. <label for="idQuotaFiles" class="col-sm-2 col-form-label">Quota files</label>
  99. <div class="col-sm-3">
  100. <input type="number" class="form-control" id="idQuotaFiles" name="quota_files" placeholder=""
  101. value="{{.User.QuotaFiles}}" min="0" aria-describedby="qfHelpBlock">
  102. <small id="qfHelpBlock" class="form-text text-muted">
  103. 0 means no limit
  104. </small>
  105. </div>
  106. <div class="col-sm-2"></div>
  107. <label for="idQuotaSize" class="col-sm-2 col-form-label">Quota size (bytes)</label>
  108. <div class="col-sm-3">
  109. <input type="number" class="form-control" id="idQuotaSize" name="quota_size" placeholder=""
  110. value="{{.User.QuotaSize}}" min="0" aria-describedby="qsHelpBlock">
  111. <small id="qsHelpBlock" class="form-text text-muted">
  112. 0 means no limit
  113. </small>
  114. </div>
  115. </div>
  116. <div class="form-group row">
  117. <label for="idUploadBandwidth" class="col-sm-2 col-form-label">Bandwidth UL (KB/s)</label>
  118. <div class="col-sm-3">
  119. <input type="number" class="form-control" id="idUploadBandwidth" name="upload_bandwidth" placeholder=""
  120. value="{{.User.UploadBandwidth}}" min="0" aria-describedby="ulHelpBlock">
  121. <small id="ulHelpBlock" class="form-text text-muted">
  122. 0 means no limit
  123. </small>
  124. </div>
  125. <div class="col-sm-2"></div>
  126. <label for="idDownloadBandwidth" class="col-sm-2 col-form-label">Bandwidth DL (KB/s)</label>
  127. <div class="col-sm-3">
  128. <input type="number" class="form-control" id="idDownloadBandwidth" name="download_bandwidth" placeholder=""
  129. value="{{.User.DownloadBandwidth}}" min="0" aria-describedby="dlHelpBlock">
  130. <small id="dlHelpBlock" class="form-text text-muted">
  131. 0 means no limit
  132. </small>
  133. </div>
  134. </div>
  135. <div class="form-group row">
  136. <label for="idMaxSessions" class="col-sm-2 col-form-label">Max sessions</label>
  137. <div class="col-sm-2">
  138. <input type="number" class="form-control" id="idMaxSessions" name="max_sessions" placeholder=""
  139. value="{{.User.MaxSessions}}" min="0" aria-describedby="sessionsHelpBlock">
  140. <small id="sessionsHelpBlock" class="form-text text-muted">
  141. 0 means no limit
  142. </small>
  143. </div>
  144. <div class="col-sm-1"></div>
  145. <label for="idUID" class="col-sm-1 col-form-label">UID</label>
  146. <div class="col-sm-2">
  147. <input type="number" class="form-control" id="idUID" name="uid" placeholder="" value="{{.User.UID}}" min="0"
  148. max="65535">
  149. </div>
  150. <div class="col-sm-1"></div>
  151. <label for="idGID" class="col-sm-1 col-form-label">GID</label>
  152. <div class="col-sm-2">
  153. <input type="number" class="form-control" id="idGID" name="gid" placeholder="" value="{{.User.GID}}" min="0"
  154. max="65535">
  155. </div>
  156. </div>
  157. <div class="form-group row">
  158. <label for="idDeniedIP" class="col-sm-2 col-form-label">Denied IP/Mask</label>
  159. <div class="col-sm-10">
  160. <input type="text" class="form-control" id="idDeniedIP" name="denied_ip" placeholder=""
  161. value="{{.User.GetDeniedIPAsString}}" maxlength="255" aria-describedby="deniedIPHelpBlock">
  162. <small id="deniedIPHelpBlock" class="form-text text-muted">
  163. Comma separated IP/Mask in CIDR format, for example "192.168.1.0/24,10.8.0.100/32"
  164. </small>
  165. </div>
  166. </div>
  167. <div class="form-group row">
  168. <label for="idAllowedIP" class="col-sm-2 col-form-label">Allowed IP/Mask</label>
  169. <div class="col-sm-10">
  170. <input type="text" class="form-control" id="idAllowedIP" name="allowed_ip" placeholder=""
  171. value="{{.User.GetAllowedIPAsString}}" maxlength="255" aria-describedby="allowedIPHelpBlock">
  172. <small id="allowedIPHelpBlock" class="form-text text-muted">
  173. Comma separated IP/Mask in CIDR format, for example "192.168.1.0/24,10.8.0.100/32"
  174. </small>
  175. </div>
  176. </div>
  177. <input type="hidden" name="expiration_date" id="hidden_start_datetime" value="">
  178. <button type="submit" class="btn btn-primary float-right mt-3 mb-5 px-5 px-3">Submit</button>
  179. </form>
  180. {{end}}
  181. {{define "extra_js"}}
  182. <script src="/static/vendor/moment/js/moment.min.js"></script>
  183. <script src="/static/vendor/tempusdominus/js/tempusdominus-bootstrap-4.min.js"></script>
  184. <script type="text/javascript">
  185. $(document).ready(function () {
  186. $('#expirationDatePicker').datetimepicker({
  187. format: 'YYYY-MM-DD',
  188. buttons: {
  189. showClear: false,
  190. showClose: true,
  191. showToday: false
  192. }
  193. });
  194. { { if gt.User.ExpirationDate 0 } }
  195. var input_dt = moment({{.User.ExpirationDate }}).format('YYYY-MM-DD');
  196. $('#idExpirationDate').val(input_dt);
  197. $('#expirationDatePicker').datetimepicker('viewDate', input_dt);
  198. { { end } }
  199. $("#user_form").submit(function (event) {
  200. var dt = $('#idExpirationDate').val();
  201. if (dt) {
  202. var d = $('#expirationDatePicker').datetimepicker('viewDate');
  203. if (d) {
  204. var dateString = moment(d).format('YYYY-MM-DD HH:mm:ss');
  205. $('#hidden_start_datetime').val(dateString);
  206. } else {
  207. $('#hidden_start_datetime').val("");
  208. }
  209. } else {
  210. $('#hidden_start_datetime').val("");
  211. }
  212. return true;
  213. });
  214. });
  215. </script>
  216. {{end}}