mirror of
https://github.com/moul/sshportal.git
synced 2024-11-10 17:26:41 +08:00
Merge pull request #196 from moul/dev/moul/pr-194
This commit is contained in:
commit
9d2badf253
7 changed files with 109 additions and 31 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -8,4 +8,5 @@ dist/
|
|||
/sshportal
|
||||
*.db
|
||||
/data
|
||||
sshportal.history
|
||||
sshportal.history
|
||||
.idea
|
||||
|
|
9
go.sum
generated
9
go.sum
generated
|
@ -6,11 +6,9 @@ github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFI
|
|||
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4=
|
||||
github.com/asaskevich/govalidator v0.0.0-20200428143746-21a406dcc535 h1:4daAzAu0S6Vi7/lbWECcX0j45yZReDZ56BQsrVBOEEY=
|
||||
github.com/asaskevich/govalidator v0.0.0-20200428143746-21a406dcc535/go.mod h1:oGkLhpf+kjZl6xBf758TQhh5XrAeiJv/7FRz/2spLIg=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d h1:U+s90UTSYgptZMwQh2aRr3LuazLJIa+Pg3Kc1ylSYVY=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0 h1:EoUDS0afbrsXAZ9YQ9jdu/mZ2sXgT1/2yyNng4PGlyM=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||
github.com/creack/pty v1.1.7 h1:6pwm8kMQKCmgUg0ZHTm5+/YvRK0s3THD/28+T6/kk4A=
|
||||
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
|
||||
github.com/creack/pty v1.1.11 h1:07n33Z8lZxZ2qwegKbObQohDhXDQxiMMz1NOUGYlesw=
|
||||
github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
|
@ -28,11 +26,9 @@ github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5 h1:Yzb9+7DP
|
|||
github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5/go.mod h1:a2zkGnVExMxdzMo3M0Hi/3sEU+cWnZpSni0O6/Yb/P0=
|
||||
github.com/gliderlabs/ssh v0.3.0 h1:7GcKy4erEljCE/QeQ2jTVpu+3f3zkpZOxOJjFYkMqYU=
|
||||
github.com/gliderlabs/ssh v0.3.0/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0=
|
||||
github.com/go-sql-driver/mysql v1.4.1 h1:g24URVg0OFbNUTx9qqY1IRZ9D9z3iPyi5zKhQZpNwpA=
|
||||
github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
|
||||
github.com/go-sql-driver/mysql v1.5.0 h1:ozyZYNQW3x3HtqT1jira07DN2PArx2v7/mN66gGcHOs=
|
||||
github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
|
||||
github.com/gofrs/uuid v3.2.0+incompatible h1:y12jRkkFxsd7GpqdSZ+/KCs/fJbqpEXSGd4+jfEaewE=
|
||||
github.com/gofrs/uuid v3.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
|
||||
github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe h1:lXe2qZdvpiX5WZkZR4hgp4KJVfY3nMkvmwbVkpv1rVY=
|
||||
github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0=
|
||||
|
@ -41,15 +37,12 @@ github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5a
|
|||
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
||||
github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e h1:JKmoR8x90Iww1ks85zJ1lfDGgIiMDuIptTOhJq+zKyg=
|
||||
github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
||||
github.com/jinzhu/gorm v1.9.2 h1:lCvgEaqe/HVE+tjAR2mt4HbbHAZsQOv3XAZiEZV37iw=
|
||||
github.com/jinzhu/gorm v1.9.2/go.mod h1:Vla75njaFJ8clLU1W44h34PjIkijhjHIYnZxMqCdxqo=
|
||||
github.com/jinzhu/gorm v1.9.15 h1:OdR1qFvtXktlxk73XFYMiYn9ywzTwytqe4QkuMRqc38=
|
||||
github.com/jinzhu/gorm v1.9.15/go.mod h1:G3LB3wezTOWM2ITLzPxEXgSkOXAntiLHS7UdBefADcs=
|
||||
github.com/jinzhu/inflection v0.0.0-20180308033659-04140366298a h1:eeaG9XMUvRBYXJi4pg1ZKM7nxc5AfXfojeLLW7O5J3k=
|
||||
github.com/jinzhu/inflection v0.0.0-20180308033659-04140366298a/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
|
||||
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
|
||||
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
|
||||
github.com/jinzhu/now v0.0.0-20181116074157-8ec929ed50c3 h1:xvj06l8iSwiWpYgm8MbPp+naBg+pwfqmdXabzqPCn/8=
|
||||
github.com/jinzhu/now v0.0.0-20181116074157-8ec929ed50c3/go.mod h1:oHTiXerJ20+SfYcrdlBO7rzZRJWGwSTQ0iUY2jI6Gfc=
|
||||
github.com/jinzhu/now v1.0.1 h1:HjfetcXq097iXP0uoPCdnM4Efp5/9MsM0/M+XOTeR3M=
|
||||
github.com/jinzhu/now v1.0.1/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
|
||||
|
@ -59,7 +52,6 @@ github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7
|
|||
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
|
||||
github.com/kr/pty v1.1.8 h1:AkaSdXYQOWeaO3neb8EM634ahkXXe3jYbVh/F9lq+GI=
|
||||
github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw=
|
||||
github.com/lib/pq v1.0.0 h1:X5PMW56eZitiTeO7tKzZxFCSpbFZJtkMMooicw2us9A=
|
||||
github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
github.com/lib/pq v1.1.1 h1:sJZmqHoEaY7f+NPP8pgLB/WxulyR3fewgCM2qaSlBb4=
|
||||
github.com/lib/pq v1.1.1/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
|
@ -70,7 +62,6 @@ github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Ky
|
|||
github.com/mattn/go-runewidth v0.0.7/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
|
||||
github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0=
|
||||
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
|
||||
github.com/mattn/go-sqlite3 v1.10.0 h1:jbhqpg7tQe4SupckyijYiy0mJJ/pRyHvXf7JdWK860o=
|
||||
github.com/mattn/go-sqlite3 v1.10.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
|
||||
github.com/mattn/go-sqlite3 v1.14.0/go.mod h1:JIl7NbARA7phWnGvh0LKTyg7S9BA+6gx71ShQilpsus=
|
||||
github.com/mattn/go-sqlite3 v2.0.3+incompatible h1:gXHsfypPkaMZrKbD5209QV9jbUTJKjyR5WD3HYQSd+U=
|
||||
|
|
1
main.go
1
main.go
|
@ -8,6 +8,7 @@ import (
|
|||
|
||||
_ "github.com/go-sql-driver/mysql"
|
||||
_ "github.com/jinzhu/gorm/dialects/mysql"
|
||||
_ "github.com/jinzhu/gorm/dialects/postgres"
|
||||
_ "github.com/jinzhu/gorm/dialects/sqlite"
|
||||
"github.com/urfave/cli"
|
||||
"moul.io/srand"
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
package bastion // import "moul.io/sshportal/pkg/bastion"
|
||||
package bastion
|
||||
|
||||
import (
|
||||
"sort"
|
||||
"time"
|
||||
|
||||
"moul.io/sshportal/pkg/dbmodels"
|
||||
)
|
||||
|
@ -13,6 +14,8 @@ func (a byWeight) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
|
|||
func (a byWeight) Less(i, j int) bool { return a[i].Weight < a[j].Weight }
|
||||
|
||||
func checkACLs(user dbmodels.User, host dbmodels.Host) string {
|
||||
currentTime := time.Now()
|
||||
|
||||
// shared ACLs between user and host
|
||||
aclMap := map[uint]*dbmodels.ACL{}
|
||||
for _, userGroup := range user.Groups {
|
||||
|
@ -20,7 +23,10 @@ func checkACLs(user dbmodels.User, host dbmodels.Host) string {
|
|||
for _, hostGroup := range host.Groups {
|
||||
for _, hostGroupACL := range hostGroup.ACLs {
|
||||
if userGroupACL.ID == hostGroupACL.ID {
|
||||
aclMap[userGroupACL.ID] = userGroupACL
|
||||
if (userGroupACL.Inception == nil || currentTime.After(*userGroupACL.Inception)) &&
|
||||
(userGroupACL.Expiration == nil || currentTime.Before(*userGroupACL.Expiration)) {
|
||||
aclMap[userGroupACL.ID] = userGroupACL
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -45,8 +45,8 @@ func DBInit(db *gorm.DB) error {
|
|||
Type string
|
||||
Length uint
|
||||
Fingerprint string
|
||||
PrivKey string `sql:"size:10000"`
|
||||
PubKey string `sql:"size:10000"`
|
||||
PrivKey string `sql:"size:5000"`
|
||||
PubKey string `sql:"size:1000"`
|
||||
Hosts []*dbmodels.Host `gorm:"ForeignKey:SSHKeyID"`
|
||||
Comment string
|
||||
}
|
||||
|
@ -80,7 +80,7 @@ func DBInit(db *gorm.DB) error {
|
|||
Migrate: func(tx *gorm.DB) error {
|
||||
type UserKey struct {
|
||||
gorm.Model
|
||||
Key []byte `sql:"size:10000"`
|
||||
Key []byte `sql:"size:1000"`
|
||||
UserID uint ``
|
||||
User *dbmodels.User `gorm:"ForeignKey:UserID"`
|
||||
Comment string
|
||||
|
@ -341,8 +341,8 @@ func DBInit(db *gorm.DB) error {
|
|||
Migrate: func(tx *gorm.DB) error {
|
||||
type UserKey struct {
|
||||
gorm.Model
|
||||
Key []byte `sql:"size:10000" valid:"required,length(1|10000)"`
|
||||
AuthorizedKey string `sql:"size:10000" valid:"required,length(1|10000)"`
|
||||
Key []byte `sql:"size:1000" valid:"required,length(1|1000)"`
|
||||
AuthorizedKey string `sql:"size:1000" valid:"required,length(1|1000)"`
|
||||
UserID uint ``
|
||||
User *dbmodels.User `gorm:"ForeignKey:UserID"`
|
||||
Comment string `valid:"optional"`
|
||||
|
@ -386,7 +386,7 @@ func DBInit(db *gorm.DB) error {
|
|||
Password string `valid:"optional"`
|
||||
SSHKey *dbmodels.SSHKey `gorm:"ForeignKey:SSHKeyID"`
|
||||
SSHKeyID uint `gorm:"index"`
|
||||
HostKey []byte `sql:"size:10000" valid:"optional"`
|
||||
HostKey []byte `sql:"size:1000" valid:"optional"`
|
||||
Groups []*dbmodels.HostGroup `gorm:"many2many:host_host_groups;"`
|
||||
Fingerprint string `valid:"optional"`
|
||||
Comment string `valid:"optional"`
|
||||
|
@ -447,7 +447,7 @@ func DBInit(db *gorm.DB) error {
|
|||
URL string
|
||||
SSHKey *dbmodels.SSHKey `gorm:"ForeignKey:SSHKeyID"`
|
||||
SSHKeyID uint `gorm:"index"`
|
||||
HostKey []byte `sql:"size:10000"`
|
||||
HostKey []byte `sql:"size:1000"`
|
||||
Groups []*dbmodels.HostGroup `gorm:"many2many:host_host_groups;"`
|
||||
Comment string
|
||||
}
|
||||
|
@ -468,7 +468,7 @@ func DBInit(db *gorm.DB) error {
|
|||
URL string
|
||||
SSHKey *dbmodels.SSHKey `gorm:"ForeignKey:SSHKeyID"`
|
||||
SSHKeyID uint `gorm:"index"`
|
||||
HostKey []byte `sql:"size:10000"`
|
||||
HostKey []byte `sql:"size:1000"`
|
||||
Groups []*dbmodels.HostGroup `gorm:"many2many:host_host_groups;"`
|
||||
Comment string
|
||||
Hop *dbmodels.Host
|
||||
|
@ -500,17 +500,30 @@ func DBInit(db *gorm.DB) error {
|
|||
}
|
||||
return tx.AutoMigrate(&Host{}).Error
|
||||
},
|
||||
Rollback: func(tx *gorm.DB) error {
|
||||
return fmt.Errorf("not implemented")
|
||||
},
|
||||
Rollback: func(tx *gorm.DB) error { return fmt.Errorf("not implemented") },
|
||||
}, {
|
||||
ID: "31",
|
||||
Migrate: func(tx *gorm.DB) error {
|
||||
return tx.Model(&dbmodels.Host{}).Updates(&dbmodels.Host{Logging: "everything"}).Error
|
||||
},
|
||||
Rollback: func(tx *gorm.DB) error {
|
||||
return fmt.Errorf("not implemented")
|
||||
Rollback: func(tx *gorm.DB) error { return fmt.Errorf("not implemented") },
|
||||
}, {
|
||||
ID: "32",
|
||||
Migrate: func(tx *gorm.DB) error {
|
||||
type ACL struct {
|
||||
gorm.Model
|
||||
HostGroups []*dbmodels.HostGroup `gorm:"many2many:host_group_acls;"`
|
||||
UserGroups []*dbmodels.UserGroup `gorm:"many2many:user_group_acls;"`
|
||||
HostPattern string `valid:"optional"`
|
||||
Action string `valid:"required"`
|
||||
Weight uint ``
|
||||
Comment string `valid:"optional"`
|
||||
Inception *time.Time
|
||||
Expiration *time.Time
|
||||
}
|
||||
return tx.AutoMigrate(&ACL{}).Error
|
||||
},
|
||||
Rollback: func(tx *gorm.DB) error { return fmt.Errorf("not implemented") },
|
||||
},
|
||||
})
|
||||
if err := m.Migrate(); err != nil {
|
||||
|
|
|
@ -90,17 +90,31 @@ GLOBAL OPTIONS:
|
|||
cli.StringFlag{Name: "comment", Usage: "Adds a comment"},
|
||||
cli.StringFlag{Name: "action", Usage: "Assigns the ACL action (allow,deny)", Value: string(dbmodels.ACLActionAllow)},
|
||||
cli.UintFlag{Name: "weight, w", Usage: "Assigns the ACL weight (priority)"},
|
||||
cli.StringFlag{Name: "inception, i", Usage: "Assigns inception date-time"},
|
||||
cli.StringFlag{Name: "expiration, e", Usage: "Assigns expiration date-time"},
|
||||
},
|
||||
Action: func(c *cli.Context) error {
|
||||
if err := myself.CheckRoles([]string{"admin"}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
inception, err := parseOptionalTime(c.String("inception"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
expiration, err := parseOptionalTime(c.String("expiration"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
acl := dbmodels.ACL{
|
||||
Comment: c.String("comment"),
|
||||
HostPattern: c.String("pattern"),
|
||||
UserGroups: []*dbmodels.UserGroup{},
|
||||
HostGroups: []*dbmodels.HostGroup{},
|
||||
Weight: c.Uint("weight"),
|
||||
Inception: inception,
|
||||
Expiration: expiration,
|
||||
Action: c.String("action"),
|
||||
}
|
||||
if acl.Action != string(dbmodels.ACLActionAllow) && acl.Action != string(dbmodels.ACLActionDeny) {
|
||||
|
@ -186,7 +200,7 @@ GLOBAL OPTIONS:
|
|||
}
|
||||
|
||||
table := tablewriter.NewWriter(s)
|
||||
table.SetHeader([]string{"ID", "Weight", "User groups", "Host groups", "Host pattern", "Action", "Updated", "Created", "Comment"})
|
||||
table.SetHeader([]string{"ID", "Weight", "User groups", "Host groups", "Host pattern", "Action", "Inception", "Expiration", "Updated", "Created", "Comment"})
|
||||
table.SetBorder(false)
|
||||
table.SetCaption(true, fmt.Sprintf("Total: %d ACLs.", len(acls)))
|
||||
for _, acl := range acls {
|
||||
|
@ -199,6 +213,15 @@ GLOBAL OPTIONS:
|
|||
hostGroups = append(hostGroups, entity.Name)
|
||||
}
|
||||
|
||||
inception := ""
|
||||
if acl.Inception != nil {
|
||||
inception = acl.Inception.Format("2006-01-02 15:04 MST")
|
||||
}
|
||||
expiration := ""
|
||||
if acl.Expiration != nil {
|
||||
expiration = acl.Expiration.Format("2006-01-02 15:04 MST")
|
||||
}
|
||||
|
||||
table.Append([]string{
|
||||
fmt.Sprintf("%d", acl.ID),
|
||||
fmt.Sprintf("%d", acl.Weight),
|
||||
|
@ -206,6 +229,8 @@ GLOBAL OPTIONS:
|
|||
strings.Join(hostGroups, ", "),
|
||||
acl.HostPattern,
|
||||
acl.Action,
|
||||
inception,
|
||||
expiration,
|
||||
humanize.Time(acl.UpdatedAt),
|
||||
humanize.Time(acl.CreatedAt),
|
||||
acl.Comment,
|
||||
|
@ -236,6 +261,10 @@ GLOBAL OPTIONS:
|
|||
cli.StringFlag{Name: "action, a", Usage: "Update action"},
|
||||
cli.StringFlag{Name: "pattern, p", Usage: "Update host-pattern"},
|
||||
cli.UintFlag{Name: "weight, w", Usage: "Update weight"},
|
||||
cli.StringFlag{Name: "inception, i", Usage: "Update inception date-time"},
|
||||
cli.BoolFlag{Name: "unset-inception", Usage: "Unset inception date-time"},
|
||||
cli.BoolFlag{Name: "unset-expiration", Usage: "Unset expiration date-time"},
|
||||
cli.StringFlag{Name: "expiration, e", Usage: "Update expiration date-time"},
|
||||
cli.StringFlag{Name: "comment, c", Usage: "Update comment"},
|
||||
cli.StringSliceFlag{Name: "assign-usergroup, ug", Usage: "Assign the ACL to new `USERGROUPS`"},
|
||||
cli.StringSliceFlag{Name: "unassign-usergroup", Usage: "Unassign the ACL from `USERGROUPS`"},
|
||||
|
@ -258,10 +287,21 @@ GLOBAL OPTIONS:
|
|||
tx := db.Begin()
|
||||
for _, acl := range acls {
|
||||
model := tx.Model(acl)
|
||||
inception, err := parseOptionalTime(c.String("inception"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
expiration, err := parseOptionalTime(c.String("expiration"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
update := dbmodels.ACL{
|
||||
Action: c.String("action"),
|
||||
HostPattern: c.String("pattern"),
|
||||
Weight: c.Uint("weight"),
|
||||
Inception: inception,
|
||||
Expiration: expiration,
|
||||
Comment: c.String("comment"),
|
||||
}
|
||||
if err := model.Updates(update).Error; err != nil {
|
||||
|
@ -269,6 +309,19 @@ GLOBAL OPTIONS:
|
|||
return err
|
||||
}
|
||||
|
||||
if c.Bool("unset-inception") {
|
||||
if err := model.Update("inception", nil).Error; err != nil {
|
||||
tx.Rollback()
|
||||
return err
|
||||
}
|
||||
}
|
||||
if c.Bool("unset-expiration") {
|
||||
if err := model.Update("expiration", nil).Error; err != nil {
|
||||
tx.Rollback()
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// associations
|
||||
var appendUserGroups []dbmodels.UserGroup
|
||||
var deleteUserGroups []dbmodels.UserGroup
|
||||
|
@ -2262,3 +2315,14 @@ func parseInputURL(input string) (*url.URL, error) {
|
|||
}
|
||||
return u, nil
|
||||
}
|
||||
|
||||
func parseOptionalTime(input string) (*time.Time, error) {
|
||||
if input != "" {
|
||||
parsed, err := time.ParseInLocation("2006-01-02 15:04", input, time.Local)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &parsed, nil
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
|
|
@ -42,8 +42,8 @@ type SSHKey struct {
|
|||
Type string `valid:"required"`
|
||||
Length uint `valid:"required"`
|
||||
Fingerprint string `valid:"optional"`
|
||||
PrivKey string `sql:"size:10000" valid:"required"`
|
||||
PubKey string `sql:"size:10000" valid:"optional"`
|
||||
PrivKey string `sql:"size:5000" valid:"required"`
|
||||
PubKey string `sql:"size:1000" valid:"optional"`
|
||||
Hosts []*Host `gorm:"ForeignKey:SSHKeyID"`
|
||||
Comment string `valid:"optional"`
|
||||
}
|
||||
|
@ -58,7 +58,7 @@ type Host struct {
|
|||
URL string `valid:"optional"`
|
||||
SSHKey *SSHKey `gorm:"ForeignKey:SSHKeyID"` // SSHKey used to connect by the client
|
||||
SSHKeyID uint `gorm:"index"`
|
||||
HostKey []byte `sql:"size:10000" valid:"optional"`
|
||||
HostKey []byte `sql:"size:1000" valid:"optional"`
|
||||
Groups []*HostGroup `gorm:"many2many:host_host_groups;"`
|
||||
Comment string `valid:"optional"`
|
||||
Logging string `valid:"optional,host_logging_mode"`
|
||||
|
@ -69,8 +69,8 @@ type Host struct {
|
|||
// UserKey defines a user public key used by sshportal to identify the user
|
||||
type UserKey struct {
|
||||
gorm.Model
|
||||
Key []byte `sql:"size:10000" valid:"length(1|10000)"`
|
||||
AuthorizedKey string `sql:"size:10000" valid:"required,length(1|10000)"`
|
||||
Key []byte `sql:"size:1000" valid:"length(1|1000)"`
|
||||
AuthorizedKey string `sql:"size:1000" valid:"required,length(1|1000)"`
|
||||
UserID uint ``
|
||||
User *User `gorm:"ForeignKey:UserID"`
|
||||
Comment string `valid:"optional"`
|
||||
|
@ -118,6 +118,8 @@ type ACL struct {
|
|||
Action string `valid:"required"`
|
||||
Weight uint ``
|
||||
Comment string `valid:"optional"`
|
||||
Inception *time.Time
|
||||
Expiration *time.Time
|
||||
}
|
||||
|
||||
type Session struct {
|
||||
|
|
Loading…
Reference in a new issue