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