user.go 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263
  1. package sdk
  2. import (
  3. "strings"
  4. "github.com/drakkan/sftpgo/v2/kms"
  5. "github.com/drakkan/sftpgo/v2/util"
  6. )
  7. // Web Client/user REST API restrictions
  8. const (
  9. WebClientPubKeyChangeDisabled = "publickey-change-disabled"
  10. WebClientWriteDisabled = "write-disabled"
  11. WebClientMFADisabled = "mfa-disabled"
  12. WebClientPasswordChangeDisabled = "password-change-disabled"
  13. WebClientAPIKeyAuthChangeDisabled = "api-key-auth-change-disabled"
  14. WebClientInfoChangeDisabled = "info-change-disabled"
  15. WebClientSharesDisabled = "shares-disabled"
  16. WebClientPasswordResetDisabled = "password-reset-disabled"
  17. )
  18. var (
  19. // WebClientOptions defines the available options for the web client interface/user REST API
  20. WebClientOptions = []string{WebClientWriteDisabled, WebClientPasswordChangeDisabled, WebClientPasswordResetDisabled,
  21. WebClientPubKeyChangeDisabled, WebClientMFADisabled, WebClientAPIKeyAuthChangeDisabled, WebClientInfoChangeDisabled,
  22. WebClientSharesDisabled}
  23. // UserTypes defines the supported user type hints for auth plugins
  24. UserTypes = []string{string(UserTypeLDAP), string(UserTypeOS)}
  25. )
  26. // TLSUsername defines the TLS certificate attribute to use as username
  27. type TLSUsername string
  28. // Supported certificate attributes to use as username
  29. const (
  30. TLSUsernameNone TLSUsername = "None"
  31. TLSUsernameCN TLSUsername = "CommonName"
  32. )
  33. // UserType defines the supported user types.
  34. // This is an hint for external auth plugins, is not used in SFTPGo directly
  35. type UserType string
  36. // User types, auth plugins could use this info to choose the correct authentication backend
  37. const (
  38. UserTypeLDAP UserType = "LDAPUser"
  39. UserTypeOS UserType = "OSUser"
  40. )
  41. // DirectoryPermissions defines permissions for a directory virtual path
  42. type DirectoryPermissions struct {
  43. Path string
  44. Permissions []string
  45. }
  46. // HasPerm returns true if the directory has the specified permissions
  47. func (d *DirectoryPermissions) HasPerm(perm string) bool {
  48. return util.IsStringInSlice(perm, d.Permissions)
  49. }
  50. // PatternsFilter defines filters based on shell like patterns.
  51. // These restrictions do not apply to files listing for performance reasons, so
  52. // a denied file cannot be downloaded/overwritten/renamed but will still be
  53. // in the list of files.
  54. // System commands such as Git and rsync interacts with the filesystem directly
  55. // and they are not aware about these restrictions so they are not allowed
  56. // inside paths with extensions filters
  57. type PatternsFilter struct {
  58. // Virtual path, if no other specific filter is defined, the filter applies for
  59. // sub directories too.
  60. // For example if filters are defined for the paths "/" and "/sub" then the
  61. // filters for "/" are applied for any file outside the "/sub" directory
  62. Path string `json:"path"`
  63. // files with these, case insensitive, patterns are allowed.
  64. // Denied file patterns are evaluated before the allowed ones
  65. AllowedPatterns []string `json:"allowed_patterns,omitempty"`
  66. // files with these, case insensitive, patterns are not allowed.
  67. // Denied file patterns are evaluated before the allowed ones
  68. DeniedPatterns []string `json:"denied_patterns,omitempty"`
  69. }
  70. // GetCommaSeparatedPatterns returns the first non empty patterns list comma separated
  71. func (p *PatternsFilter) GetCommaSeparatedPatterns() string {
  72. if len(p.DeniedPatterns) > 0 {
  73. return strings.Join(p.DeniedPatterns, ",")
  74. }
  75. return strings.Join(p.AllowedPatterns, ",")
  76. }
  77. // IsDenied returns true if the patterns has one or more denied patterns
  78. func (p *PatternsFilter) IsDenied() bool {
  79. return len(p.DeniedPatterns) > 0
  80. }
  81. // IsAllowed returns true if the patterns has one or more allowed patterns
  82. func (p *PatternsFilter) IsAllowed() bool {
  83. return len(p.AllowedPatterns) > 0
  84. }
  85. // HooksFilter defines user specific overrides for global hooks
  86. type HooksFilter struct {
  87. ExternalAuthDisabled bool `json:"external_auth_disabled"`
  88. PreLoginDisabled bool `json:"pre_login_disabled"`
  89. CheckPasswordDisabled bool `json:"check_password_disabled"`
  90. }
  91. // RecoveryCode defines a 2FA recovery code
  92. type RecoveryCode struct {
  93. Secret *kms.Secret `json:"secret"`
  94. Used bool `json:"used,omitempty"`
  95. }
  96. // TOTPConfig defines the time-based one time password configuration
  97. type TOTPConfig struct {
  98. Enabled bool `json:"enabled,omitempty"`
  99. ConfigName string `json:"config_name,omitempty"`
  100. Secret *kms.Secret `json:"secret,omitempty"`
  101. // TOTP will be required for the specified protocols.
  102. // SSH protocol (SFTP/SCP/SSH commands) will ask for the TOTP passcode if the client uses keyboard interactive
  103. // authentication.
  104. // FTP have no standard way to support two factor authentication, if you
  105. // enable the support for this protocol you have to add the TOTP passcode after the password.
  106. // For example if your password is "password" and your one time passcode is
  107. // "123456" you have to use "password123456" as password.
  108. Protocols []string `json:"protocols,omitempty"`
  109. }
  110. // BandwidthLimit defines a per-source bandwidth limit
  111. type BandwidthLimit struct {
  112. // Source networks in CIDR notation as defined in RFC 4632 and RFC 4291
  113. // for example "192.0.2.0/24" or "2001:db8::/32". The limit applies if the
  114. // defined networks contain the client IP
  115. Sources []string `json:"sources"`
  116. // Maximum upload bandwidth as KB/s
  117. UploadBandwidth int64 `json:"upload_bandwidth,omitempty"`
  118. // Maximum download bandwidth as KB/s
  119. DownloadBandwidth int64 `json:"download_bandwidth,omitempty"`
  120. }
  121. // GetSourcesAsString returns the sources as comma separated string
  122. func (l *BandwidthLimit) GetSourcesAsString() string {
  123. return strings.Join(l.Sources, ",")
  124. }
  125. // UserFilters defines additional restrictions for a user
  126. // TODO: rename to UserOptions in v3
  127. type UserFilters struct {
  128. // only clients connecting from these IP/Mask are allowed.
  129. // IP/Mask must be in CIDR notation as defined in RFC 4632 and RFC 4291
  130. // for example "192.0.2.0/24" or "2001:db8::/32"
  131. AllowedIP []string `json:"allowed_ip,omitempty"`
  132. // clients connecting from these IP/Mask are not allowed.
  133. // Denied rules will be evaluated before allowed ones
  134. DeniedIP []string `json:"denied_ip,omitempty"`
  135. // these login methods are not allowed.
  136. // If null or empty any available login method is allowed
  137. DeniedLoginMethods []string `json:"denied_login_methods,omitempty"`
  138. // these protocols are not allowed.
  139. // If null or empty any available protocol is allowed
  140. DeniedProtocols []string `json:"denied_protocols,omitempty"`
  141. // filter based on shell patterns.
  142. // Please note that these restrictions can be easily bypassed.
  143. FilePatterns []PatternsFilter `json:"file_patterns,omitempty"`
  144. // max size allowed for a single upload, 0 means unlimited
  145. MaxUploadFileSize int64 `json:"max_upload_file_size,omitempty"`
  146. // TLS certificate attribute to use as username.
  147. // For FTP clients it must match the name provided using the
  148. // "USER" command
  149. TLSUsername TLSUsername `json:"tls_username,omitempty"`
  150. // user specific hook overrides
  151. Hooks HooksFilter `json:"hooks,omitempty"`
  152. // Disable checks for existence and automatic creation of home directory
  153. // and virtual folders.
  154. // SFTPGo requires that the user's home directory, virtual folder root,
  155. // and intermediate paths to virtual folders exist to work properly.
  156. // If you already know that the required directories exist, disabling
  157. // these checks will speed up login.
  158. // You could, for example, disable these checks after the first login
  159. DisableFsChecks bool `json:"disable_fs_checks,omitempty"`
  160. // WebClient related configuration options
  161. WebClient []string `json:"web_client,omitempty"`
  162. // API key auth allows to impersonate this user with an API key
  163. AllowAPIKeyAuth bool `json:"allow_api_key_auth,omitempty"`
  164. // Time-based one time passwords configuration
  165. TOTPConfig TOTPConfig `json:"totp_config,omitempty"`
  166. // Recovery codes to use if the user loses access to their second factor auth device.
  167. // Each code can only be used once, you should use these codes to login and disable or
  168. // reset 2FA for your account
  169. RecoveryCodes []RecoveryCode `json:"recovery_codes,omitempty"`
  170. // UserType is an hint for authentication plugins.
  171. // It is ignored when using SFTPGo internal authentication
  172. UserType string `json:"user_type,omitempty"`
  173. // Per-source bandwidth limits
  174. BandwidthLimits []BandwidthLimit `json:"bandwidth_limits,omitempty"`
  175. }
  176. // BaseUser defines the shared user fields
  177. type BaseUser struct {
  178. // Data provider unique identifier
  179. ID int64 `json:"id"`
  180. // 1 enabled, 0 disabled (login is not allowed)
  181. Status int `json:"status"`
  182. // Username
  183. Username string `json:"username"`
  184. // Email
  185. Email string `json:"email,omitempty"`
  186. // Account expiration date as unix timestamp in milliseconds. An expired account cannot login.
  187. // 0 means no expiration
  188. ExpirationDate int64 `json:"expiration_date"`
  189. // Password used for password authentication.
  190. // For users created using SFTPGo REST API the password is be stored using bcrypt or argon2id hashing algo.
  191. // Checking passwords stored with pbkdf2, md5crypt and sha512crypt is supported too.
  192. Password string `json:"password,omitempty"`
  193. // PublicKeys used for public key authentication. At least one between password and a public key is mandatory
  194. PublicKeys []string `json:"public_keys,omitempty"`
  195. // The user cannot upload or download files outside this directory. Must be an absolute path
  196. HomeDir string `json:"home_dir"`
  197. // If sftpgo runs as root system user then the created files and directories will be assigned to this system UID
  198. UID int `json:"uid"`
  199. // If sftpgo runs as root system user then the created files and directories will be assigned to this system GID
  200. GID int `json:"gid"`
  201. // Maximum concurrent sessions. 0 means unlimited
  202. MaxSessions int `json:"max_sessions"`
  203. // Maximum size allowed as bytes. 0 means unlimited
  204. QuotaSize int64 `json:"quota_size"`
  205. // Maximum number of files allowed. 0 means unlimited
  206. QuotaFiles int `json:"quota_files"`
  207. // List of the granted permissions
  208. Permissions map[string][]string `json:"permissions"`
  209. // Used quota as bytes
  210. UsedQuotaSize int64 `json:"used_quota_size,omitempty"`
  211. // Used quota as number of files
  212. UsedQuotaFiles int `json:"used_quota_files,omitempty"`
  213. // Last quota update as unix timestamp in milliseconds
  214. LastQuotaUpdate int64 `json:"last_quota_update,omitempty"`
  215. // Maximum upload bandwidth as KB/s, 0 means unlimited.
  216. // This is the default if no per-source limit match
  217. UploadBandwidth int64 `json:"upload_bandwidth,omitempty"`
  218. // Maximum download bandwidth as KB/s, 0 means unlimited.
  219. // This is the default if no per-source limit match
  220. DownloadBandwidth int64 `json:"download_bandwidth,omitempty"`
  221. // Last login as unix timestamp in milliseconds
  222. LastLogin int64 `json:"last_login,omitempty"`
  223. // Creation time as unix timestamp in milliseconds. It will be 0 for admins created before v2.2.0
  224. CreatedAt int64 `json:"created_at"`
  225. // last update time as unix timestamp in milliseconds
  226. UpdatedAt int64 `json:"updated_at"`
  227. // Additional restrictions
  228. Filters UserFilters `json:"filters"`
  229. // optional description, for example full name
  230. Description string `json:"description,omitempty"`
  231. // free form text field for external systems
  232. AdditionalInfo string `json:"additional_info,omitempty"`
  233. }
  234. // User defines a SFTPGo user
  235. type User struct {
  236. BaseUser
  237. // Mapping between virtual paths and virtual folders
  238. VirtualFolders []VirtualFolder `json:"virtual_folders,omitempty"`
  239. // Filesystem configuration details
  240. FsConfig Filesystem `json:"filesystem"`
  241. }