mirror of
https://github.com/go-gitea/gitea.git
synced 2025-11-03 08:02:36 +09:00
Compare commits
21 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
84a5b81d27 | ||
|
|
84f41d9d92 | ||
|
|
acb9ae4c4d | ||
|
|
b76d899f7a | ||
|
|
9f33aa61bd | ||
|
|
d0bbfd835f | ||
|
|
c7bbfd8f5e | ||
|
|
59a64c0e1d | ||
|
|
6a86a82368 | ||
|
|
8ab107c2dd | ||
|
|
cbfc7f52b9 | ||
|
|
d602ba564f | ||
|
|
55063f2524 | ||
|
|
585dd13cce | ||
|
|
12d883412f | ||
|
|
597a30b727 | ||
|
|
b5ae8945e5 | ||
|
|
5cca840bb8 | ||
|
|
f4c7e87fc9 | ||
|
|
fe99c9901d | ||
|
|
2e1540e827 |
29
CHANGELOG.md
29
CHANGELOG.md
@@ -4,6 +4,35 @@ This changelog goes through all the changes that have been made in each release
|
|||||||
without substantial changes to our git log; to see the highlights of what has
|
without substantial changes to our git log; to see the highlights of what has
|
||||||
been added to each release, please refer to the [blog](https://blog.gitea.io).
|
been added to each release, please refer to the [blog](https://blog.gitea.io).
|
||||||
|
|
||||||
|
## [1.7.5](https://github.com/go-gitea/gitea/releases/tag/v1.7.5) - 2019-03-27
|
||||||
|
* BUGFIXES
|
||||||
|
* Fix unitTypeCode not being used in accessLevelUnit (#6419) (#6423)
|
||||||
|
* Fix bug where manifest.json was being requested without cookies and continuously creating new sessions (#6372) (#6383)
|
||||||
|
* Fix ParsePatch function to work with quoted diff --git strings (#6323) (#6332)
|
||||||
|
|
||||||
|
## [1.7.4](https://github.com/go-gitea/gitea/releases/tag/v1.7.4) - 2019-03-12
|
||||||
|
* SECURITY
|
||||||
|
* Fix potential XSS vulnerability in repository description. (#6306) (#6308)
|
||||||
|
* BUGFIXES
|
||||||
|
* Fix wrong release commit id (#6224) (#6300)
|
||||||
|
* Fix panic on empty signed commits (#6292) (#6300)
|
||||||
|
* Fix organization dropdown not being scrollable when using mouse wheel (#5988) (#6246)
|
||||||
|
* Fix displaying dashboard even if required to change password (#6214) (#6215)
|
||||||
|
|
||||||
|
## [1.7.3](https://github.com/go-gitea/gitea/releases/tag/v1.7.3) - 2019-02-27
|
||||||
|
* BUGFIXES
|
||||||
|
* Fix server 500 when trying to migrate to an already existing repository (#6188) (#6197)
|
||||||
|
* Load Issue attributes for API /repos/{owner}/{repo}/issues/{index} (#6122) (#6185)
|
||||||
|
* Fix bug whereby user could change private repository to public when force private enabled. (#6156) (#6165)
|
||||||
|
* Fix bug when update owner team then visit team's repo return 404 (#6119) (#6166)
|
||||||
|
* Fix heatmap and repository menu display in Internet Explorer 9+ (#6117) (#6137)
|
||||||
|
* Fix prohibit login check on authorization (#6106) (#6115)
|
||||||
|
* Fix LDAP protocol error regression by moving to ldap.v3 (#6105) (#6107)
|
||||||
|
* Fix deadlock in webhook PullRequest (#6102) (#6104)
|
||||||
|
* Fix redirect loop when password change is required and Gitea is installed as a suburl (#5965) (#6101)
|
||||||
|
* Fix compare button regression (#5929) (#6098)
|
||||||
|
* Recover panic in orgmode.Render if bad orgfile (#4982) (#5903) (#6097)
|
||||||
|
|
||||||
## [1.7.2](https://github.com/go-gitea/gitea/releases/tag/v1.7.2) - 2019-02-14
|
## [1.7.2](https://github.com/go-gitea/gitea/releases/tag/v1.7.2) - 2019-02-14
|
||||||
* BUGFIXES
|
* BUGFIXES
|
||||||
* Remove all CommitStatus when a repo is deleted (#5940) (#5941)
|
* Remove all CommitStatus when a repo is deleted (#5940) (#5941)
|
||||||
|
|||||||
15
Gopkg.lock
generated
15
Gopkg.lock
generated
@@ -3,11 +3,11 @@
|
|||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
branch = "master"
|
branch = "master"
|
||||||
digest = "1:ab875622908a804a327a95a1701002b150806a3c5406df51ec231eac16d3a1ca"
|
digest = "1:e1fa64238b0a2dbf1edf98c4af8d1b8cb65179e286d7f28006b50fa9f508ee9d"
|
||||||
name = "code.gitea.io/git"
|
name = "code.gitea.io/git"
|
||||||
packages = ["."]
|
packages = ["."]
|
||||||
pruneopts = "NUT"
|
pruneopts = "NUT"
|
||||||
revision = "389d3c803e12a30dffcbb54a15c2242521bc4333"
|
revision = "74d7c14dd4a3ed9c5def0dc3c1aeede399ddc5c5"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
branch = "master"
|
branch = "master"
|
||||||
@@ -1005,12 +1005,12 @@
|
|||||||
version = "v1.31.1"
|
version = "v1.31.1"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
digest = "1:7e1c00b9959544fa1ccca7cf0407a5b29ac6d5201059c4fac6f599cb99bfd24d"
|
digest = "1:8a502dedecf5b6d56e36f0d0e6196392baf616634af2c23108b6e8bb89ec57fc"
|
||||||
name = "gopkg.in/ldap.v2"
|
name = "gopkg.in/ldap.v3"
|
||||||
packages = ["."]
|
packages = ["."]
|
||||||
pruneopts = "NUT"
|
pruneopts = "NUT"
|
||||||
revision = "bb7a9ca6e4fbc2129e3db588a34bc970ffe811a9"
|
revision = "214f299a0ecb2a6c6f6d2b0f13977032b207dc58"
|
||||||
version = "v2.5.1"
|
version = "v3.0.1"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
digest = "1:cfe1730a152ff033ad7d9c115d22e36b19eec6d5928c06146b9119be45d39dc0"
|
digest = "1:cfe1730a152ff033ad7d9c115d22e36b19eec6d5928c06146b9119be45d39dc0"
|
||||||
@@ -1173,7 +1173,6 @@
|
|||||||
"github.com/keybase/go-crypto/openpgp",
|
"github.com/keybase/go-crypto/openpgp",
|
||||||
"github.com/keybase/go-crypto/openpgp/armor",
|
"github.com/keybase/go-crypto/openpgp/armor",
|
||||||
"github.com/keybase/go-crypto/openpgp/packet",
|
"github.com/keybase/go-crypto/openpgp/packet",
|
||||||
"github.com/klauspost/compress/gzip",
|
|
||||||
"github.com/lafriks/xormstore",
|
"github.com/lafriks/xormstore",
|
||||||
"github.com/lib/pq",
|
"github.com/lib/pq",
|
||||||
"github.com/lunny/dingtalk_webhook",
|
"github.com/lunny/dingtalk_webhook",
|
||||||
@@ -1215,7 +1214,7 @@
|
|||||||
"gopkg.in/editorconfig/editorconfig-core-go.v1",
|
"gopkg.in/editorconfig/editorconfig-core-go.v1",
|
||||||
"gopkg.in/gomail.v2",
|
"gopkg.in/gomail.v2",
|
||||||
"gopkg.in/ini.v1",
|
"gopkg.in/ini.v1",
|
||||||
"gopkg.in/ldap.v2",
|
"gopkg.in/ldap.v3",
|
||||||
"gopkg.in/macaron.v1",
|
"gopkg.in/macaron.v1",
|
||||||
"gopkg.in/testfixtures.v2",
|
"gopkg.in/testfixtures.v2",
|
||||||
"strk.kbt.io/projects/go/libravatar",
|
"strk.kbt.io/projects/go/libravatar",
|
||||||
|
|||||||
@@ -97,8 +97,8 @@ ignored = ["google.golang.org/appengine*"]
|
|||||||
version = "1.31.1"
|
version = "1.31.1"
|
||||||
|
|
||||||
[[constraint]]
|
[[constraint]]
|
||||||
name = "gopkg.in/ldap.v2"
|
name = "gopkg.in/ldap.v3"
|
||||||
version = "2.4.1"
|
version = "3.0.1"
|
||||||
|
|
||||||
[[constraint]]
|
[[constraint]]
|
||||||
name = "gopkg.in/macaron.v1"
|
name = "gopkg.in/macaron.v1"
|
||||||
|
|||||||
@@ -112,7 +112,7 @@ func TestCreateReleasePaging(t *testing.T) {
|
|||||||
|
|
||||||
checkLatestReleaseAndCount(t, session, "/user2/repo1", "v0.0.12", i18n.Tr("en", "repo.release.draft"), 10)
|
checkLatestReleaseAndCount(t, session, "/user2/repo1", "v0.0.12", i18n.Tr("en", "repo.release.draft"), 10)
|
||||||
|
|
||||||
// Check that user3 does not see draft and still see 10 latest releases
|
// Check that user4 does not see draft and still see 10 latest releases
|
||||||
session2 := loginUser(t, "user3")
|
session2 := loginUser(t, "user4")
|
||||||
checkLatestReleaseAndCount(t, session2, "/user2/repo1", "v0.0.11", i18n.Tr("en", "repo.release.stable"), 10)
|
checkLatestReleaseAndCount(t, session2, "/user2/repo1", "v0.0.11", i18n.Tr("en", "repo.release.stable"), 10)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -90,6 +90,38 @@ func (err ErrUserNotExist) Error() string {
|
|||||||
return fmt.Sprintf("user does not exist [uid: %d, name: %s, keyid: %d]", err.UID, err.Name, err.KeyID)
|
return fmt.Sprintf("user does not exist [uid: %d, name: %s, keyid: %d]", err.UID, err.Name, err.KeyID)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ErrUserProhibitLogin represents a "ErrUserProhibitLogin" kind of error.
|
||||||
|
type ErrUserProhibitLogin struct {
|
||||||
|
UID int64
|
||||||
|
Name string
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsErrUserProhibitLogin checks if an error is a ErrUserProhibitLogin
|
||||||
|
func IsErrUserProhibitLogin(err error) bool {
|
||||||
|
_, ok := err.(ErrUserProhibitLogin)
|
||||||
|
return ok
|
||||||
|
}
|
||||||
|
|
||||||
|
func (err ErrUserProhibitLogin) Error() string {
|
||||||
|
return fmt.Sprintf("user is not allowed login [uid: %d, name: %s]", err.UID, err.Name)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ErrUserInactive represents a "ErrUserInactive" kind of error.
|
||||||
|
type ErrUserInactive struct {
|
||||||
|
UID int64
|
||||||
|
Name string
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsErrUserInactive checks if an error is a ErrUserInactive
|
||||||
|
func IsErrUserInactive(err error) bool {
|
||||||
|
_, ok := err.(ErrUserInactive)
|
||||||
|
return ok
|
||||||
|
}
|
||||||
|
|
||||||
|
func (err ErrUserInactive) Error() string {
|
||||||
|
return fmt.Sprintf("user is inactive [uid: %d, name: %s]", err.UID, err.Name)
|
||||||
|
}
|
||||||
|
|
||||||
// ErrEmailAlreadyUsed represents a "EmailAlreadyUsed" kind of error.
|
// ErrEmailAlreadyUsed represents a "EmailAlreadyUsed" kind of error.
|
||||||
type ErrEmailAlreadyUsed struct {
|
type ErrEmailAlreadyUsed struct {
|
||||||
Email string
|
Email string
|
||||||
|
|||||||
@@ -550,7 +550,12 @@ func ParsePatch(maxLines, maxLineCharacters, maxFiles int, reader io.Reader) (*D
|
|||||||
beg := len(cmdDiffHead)
|
beg := len(cmdDiffHead)
|
||||||
a := line[beg+2 : middle]
|
a := line[beg+2 : middle]
|
||||||
b := line[middle+3:]
|
b := line[middle+3:]
|
||||||
|
|
||||||
if hasQuote {
|
if hasQuote {
|
||||||
|
// Keep the entire string in double quotes for now
|
||||||
|
a = line[beg:middle]
|
||||||
|
b = line[middle+1:]
|
||||||
|
|
||||||
var err error
|
var err error
|
||||||
a, err = strconv.Unquote(a)
|
a, err = strconv.Unquote(a)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -560,6 +565,10 @@ func ParsePatch(maxLines, maxLineCharacters, maxFiles int, reader io.Reader) (*D
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("Unquote: %v", err)
|
return nil, fmt.Errorf("Unquote: %v", err)
|
||||||
}
|
}
|
||||||
|
// Now remove the /a /b
|
||||||
|
a = a[2:]
|
||||||
|
b = b[2:]
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
curFile = &DiffFile{
|
curFile = &DiffFile{
|
||||||
@@ -637,6 +646,7 @@ func ParsePatch(maxLines, maxLineCharacters, maxFiles int, reader io.Reader) (*D
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return diff, nil
|
return diff, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,8 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"code.gitea.io/gitea/modules/setting"
|
||||||
|
|
||||||
dmp "github.com/sergi/go-diff/diffmatchpatch"
|
dmp "github.com/sergi/go-diff/diffmatchpatch"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
@@ -99,6 +101,59 @@ func ExampleCutDiffAroundLine() {
|
|||||||
println(result)
|
println(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestParsePatch(t *testing.T) {
|
||||||
|
var diff = `diff --git "a/README.md" "b/README.md"
|
||||||
|
--- a/README.md
|
||||||
|
+++ b/README.md
|
||||||
|
@@ -1,3 +1,6 @@
|
||||||
|
# gitea-github-migrator
|
||||||
|
+
|
||||||
|
+ Build Status
|
||||||
|
- Latest Release
|
||||||
|
Docker Pulls
|
||||||
|
+ cut off
|
||||||
|
+ cut off`
|
||||||
|
result, err := ParsePatch(setting.Git.MaxGitDiffLines, setting.Git.MaxGitDiffLineCharacters, setting.Git.MaxGitDiffFiles, strings.NewReader(diff))
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("ParsePatch failed: %s", err)
|
||||||
|
}
|
||||||
|
println(result)
|
||||||
|
|
||||||
|
var diff2 = `diff --git "a/A \\ B" "b/A \\ B"
|
||||||
|
--- "a/A \\ B"
|
||||||
|
+++ "b/A \\ B"
|
||||||
|
@@ -1,3 +1,6 @@
|
||||||
|
# gitea-github-migrator
|
||||||
|
+
|
||||||
|
+ Build Status
|
||||||
|
- Latest Release
|
||||||
|
Docker Pulls
|
||||||
|
+ cut off
|
||||||
|
+ cut off`
|
||||||
|
result, err = ParsePatch(setting.Git.MaxGitDiffLines, setting.Git.MaxGitDiffLineCharacters, setting.Git.MaxGitDiffFiles, strings.NewReader(diff2))
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("ParsePatch failed: %s", err)
|
||||||
|
}
|
||||||
|
println(result)
|
||||||
|
|
||||||
|
var diff3 = `diff --git a/README.md b/README.md
|
||||||
|
--- a/README.md
|
||||||
|
+++ b/README.md
|
||||||
|
@@ -1,3 +1,6 @@
|
||||||
|
# gitea-github-migrator
|
||||||
|
+
|
||||||
|
+ Build Status
|
||||||
|
- Latest Release
|
||||||
|
Docker Pulls
|
||||||
|
+ cut off
|
||||||
|
+ cut off`
|
||||||
|
result, err = ParsePatch(setting.Git.MaxGitDiffLines, setting.Git.MaxGitDiffLineCharacters, setting.Git.MaxGitDiffFiles, strings.NewReader(diff3))
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("ParsePatch failed: %s", err)
|
||||||
|
}
|
||||||
|
println(result)
|
||||||
|
}
|
||||||
|
|
||||||
func setupDefaultDiff() *Diff {
|
func setupDefaultDiff() *Diff {
|
||||||
return &Diff{
|
return &Diff{
|
||||||
Files: []*DiffFile{
|
Files: []*DiffFile{
|
||||||
|
|||||||
@@ -600,16 +600,29 @@ func ExternalUserLogin(user *User, login, password string, source *LoginSource,
|
|||||||
return nil, ErrLoginSourceNotActived
|
return nil, ErrLoginSourceNotActived
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var err error
|
||||||
switch source.Type {
|
switch source.Type {
|
||||||
case LoginLDAP, LoginDLDAP:
|
case LoginLDAP, LoginDLDAP:
|
||||||
return LoginViaLDAP(user, login, password, source, autoRegister)
|
user, err = LoginViaLDAP(user, login, password, source, autoRegister)
|
||||||
case LoginSMTP:
|
case LoginSMTP:
|
||||||
return LoginViaSMTP(user, login, password, source.ID, source.Cfg.(*SMTPConfig), autoRegister)
|
user, err = LoginViaSMTP(user, login, password, source.ID, source.Cfg.(*SMTPConfig), autoRegister)
|
||||||
case LoginPAM:
|
case LoginPAM:
|
||||||
return LoginViaPAM(user, login, password, source.ID, source.Cfg.(*PAMConfig), autoRegister)
|
user, err = LoginViaPAM(user, login, password, source.ID, source.Cfg.(*PAMConfig), autoRegister)
|
||||||
|
default:
|
||||||
|
return nil, ErrUnsupportedLoginType
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil, ErrUnsupportedLoginType
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if !user.IsActive {
|
||||||
|
return nil, ErrUserInactive{user.ID, user.Name}
|
||||||
|
} else if user.ProhibitLogin {
|
||||||
|
return nil, ErrUserProhibitLogin{user.ID, user.Name}
|
||||||
|
}
|
||||||
|
|
||||||
|
return user, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// UserSignIn validates user name and password.
|
// UserSignIn validates user name and password.
|
||||||
@@ -645,6 +658,12 @@ func UserSignIn(username, password string) (*User, error) {
|
|||||||
switch user.LoginType {
|
switch user.LoginType {
|
||||||
case LoginNoType, LoginPlain, LoginOAuth2:
|
case LoginNoType, LoginPlain, LoginOAuth2:
|
||||||
if user.IsPasswordSet() && user.ValidatePassword(password) {
|
if user.IsPasswordSet() && user.ValidatePassword(password) {
|
||||||
|
if !user.IsActive {
|
||||||
|
return nil, ErrUserInactive{user.ID, user.Name}
|
||||||
|
} else if user.ProhibitLogin {
|
||||||
|
return nil, ErrUserProhibitLogin{user.ID, user.Name}
|
||||||
|
}
|
||||||
|
|
||||||
return user, nil
|
return user, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -719,10 +719,12 @@ var (
|
|||||||
|
|
||||||
// DescriptionHTML does special handles to description and return HTML string.
|
// DescriptionHTML does special handles to description and return HTML string.
|
||||||
func (repo *Repository) DescriptionHTML() template.HTML {
|
func (repo *Repository) DescriptionHTML() template.HTML {
|
||||||
sanitize := func(s string) string {
|
desc, err := markup.RenderDescriptionHTML([]byte(repo.Description), repo.HTMLURL(), repo.ComposeMetas())
|
||||||
return fmt.Sprintf(`<a href="%[1]s" target="_blank" rel="noopener noreferrer">%[1]s</a>`, s)
|
if err != nil {
|
||||||
|
log.Error(4, "Failed to render description for %s (ID: %d): %v", repo.Name, repo.ID, err)
|
||||||
|
return template.HTML(markup.Sanitize(repo.Description))
|
||||||
}
|
}
|
||||||
return template.HTML(descPattern.ReplaceAllStringFunc(markup.Sanitize(repo.Description), sanitize))
|
return template.HTML(markup.Sanitize(string(desc)))
|
||||||
}
|
}
|
||||||
|
|
||||||
// LocalCopyPath returns the local repository copy path.
|
// LocalCopyPath returns the local repository copy path.
|
||||||
|
|||||||
@@ -70,10 +70,6 @@ func (repo *Repository) CheckBranchName(name string) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, err := gitRepo.GetTag(name); err == nil {
|
|
||||||
return ErrTagAlreadyExists{name}
|
|
||||||
}
|
|
||||||
|
|
||||||
branches, err := repo.GetBranches()
|
branches, err := repo.GetBranches()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -87,6 +83,11 @@ func (repo *Repository) CheckBranchName(name string) error {
|
|||||||
return ErrBranchNameConflict{branch.Name}
|
return ErrBranchNameConflict{branch.Name}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if _, err := gitRepo.GetTag(name); err == nil {
|
||||||
|
return ErrTagAlreadyExists{name}
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -151,6 +151,15 @@ func getUserRepoPermission(e Engine, repo *Repository, user *User) (perm Permiss
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// if user in an owner team
|
||||||
|
for _, team := range teams {
|
||||||
|
if team.Authorize >= AccessModeOwner {
|
||||||
|
perm.AccessMode = AccessModeOwner
|
||||||
|
perm.UnitsMode = nil
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for _, u := range repo.Units {
|
for _, u := range repo.Units {
|
||||||
var found bool
|
var found bool
|
||||||
for _, team := range teams {
|
for _, team := range teams {
|
||||||
@@ -229,7 +238,7 @@ func accessLevelUnit(e Engine, user *User, repo *Repository, unitType UnitType)
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return AccessModeNone, err
|
return AccessModeNone, err
|
||||||
}
|
}
|
||||||
return perm.UnitAccessMode(UnitTypeCode), nil
|
return perm.UnitAccessMode(unitType), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func hasAccessUnit(e Engine, user *User, repo *Repository, unitType UnitType, testMode AccessMode) (bool, error) {
|
func hasAccessUnit(e Engine, user *User, repo *Repository, unitType UnitType, testMode AccessMode) (bool, error) {
|
||||||
|
|||||||
@@ -219,6 +219,17 @@ func TestRepoPermissionPrivateOrgRepo(t *testing.T) {
|
|||||||
assert.True(t, perm.CanWrite(unit.Type))
|
assert.True(t, perm.CanWrite(unit.Type))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// update team information and then check permission
|
||||||
|
team := AssertExistsAndLoadBean(t, &Team{ID: 5}).(*Team)
|
||||||
|
err = UpdateTeamUnits(team, nil)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
perm, err = GetUserRepoPermission(repo, owner)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
for _, unit := range repo.Units {
|
||||||
|
assert.True(t, perm.CanRead(unit.Type))
|
||||||
|
assert.True(t, perm.CanWrite(unit.Type))
|
||||||
|
}
|
||||||
|
|
||||||
// org member team tester
|
// org member team tester
|
||||||
tester := AssertExistsAndLoadBean(t, &User{ID: 2}).(*User)
|
tester := AssertExistsAndLoadBean(t, &User{ID: 2}).(*User)
|
||||||
perm, err = GetUserRepoPermission(repo, tester)
|
perm, err = GetUserRepoPermission(repo, tester)
|
||||||
|
|||||||
@@ -230,12 +230,13 @@ func getDingtalkPullRequestPayload(p *api.PullRequestPayload) (*DingtalkPayload,
|
|||||||
title = fmt.Sprintf("[%s] Pull request edited: #%d %s", p.Repository.FullName, p.Index, p.PullRequest.Title)
|
title = fmt.Sprintf("[%s] Pull request edited: #%d %s", p.Repository.FullName, p.Index, p.PullRequest.Title)
|
||||||
text = p.PullRequest.Body
|
text = p.PullRequest.Body
|
||||||
case api.HookIssueAssigned:
|
case api.HookIssueAssigned:
|
||||||
list, err := MakeAssigneeList(&Issue{ID: p.PullRequest.ID})
|
list := make([]string, len(p.PullRequest.Assignees))
|
||||||
if err != nil {
|
for i, user := range p.PullRequest.Assignees {
|
||||||
return &DingtalkPayload{}, err
|
list[i] = user.UserName
|
||||||
}
|
}
|
||||||
title = fmt.Sprintf("[%s] Pull request assigned to %s: #%d %s", p.Repository.FullName,
|
title = fmt.Sprintf("[%s] Pull request assigned to %s: #%d %s", p.Repository.FullName,
|
||||||
list, p.Index, p.PullRequest.Title)
|
strings.Join(list, ", "),
|
||||||
|
p.Index, p.PullRequest.Title)
|
||||||
text = p.PullRequest.Body
|
text = p.PullRequest.Body
|
||||||
case api.HookIssueUnassigned:
|
case api.HookIssueUnassigned:
|
||||||
title = fmt.Sprintf("[%s] Pull request unassigned: #%d %s", p.Repository.FullName, p.Index, p.PullRequest.Title)
|
title = fmt.Sprintf("[%s] Pull request unassigned: #%d %s", p.Repository.FullName, p.Index, p.PullRequest.Title)
|
||||||
|
|||||||
@@ -347,12 +347,13 @@ func getDiscordPullRequestPayload(p *api.PullRequestPayload, meta *DiscordMeta)
|
|||||||
text = p.PullRequest.Body
|
text = p.PullRequest.Body
|
||||||
color = warnColor
|
color = warnColor
|
||||||
case api.HookIssueAssigned:
|
case api.HookIssueAssigned:
|
||||||
list, err := MakeAssigneeList(&Issue{ID: p.PullRequest.ID})
|
list := make([]string, len(p.PullRequest.Assignees))
|
||||||
if err != nil {
|
for i, user := range p.PullRequest.Assignees {
|
||||||
return &DiscordPayload{}, err
|
list[i] = user.UserName
|
||||||
}
|
}
|
||||||
title = fmt.Sprintf("[%s] Pull request assigned to %s: #%d %s", p.Repository.FullName,
|
title = fmt.Sprintf("[%s] Pull request assigned to %s: #%d by %s", p.Repository.FullName,
|
||||||
list, p.Index, p.PullRequest.Title)
|
strings.Join(list, ", "),
|
||||||
|
p.Index, p.PullRequest.Title)
|
||||||
text = p.PullRequest.Body
|
text = p.PullRequest.Body
|
||||||
color = successColor
|
color = successColor
|
||||||
case api.HookIssueUnassigned:
|
case api.HookIssueUnassigned:
|
||||||
|
|||||||
@@ -301,12 +301,12 @@ func getSlackPullRequestPayload(p *api.PullRequestPayload, slack *SlackMeta) (*S
|
|||||||
text = fmt.Sprintf("[%s] Pull request edited: %s by %s", p.Repository.FullName, titleLink, senderLink)
|
text = fmt.Sprintf("[%s] Pull request edited: %s by %s", p.Repository.FullName, titleLink, senderLink)
|
||||||
attachmentText = SlackTextFormatter(p.PullRequest.Body)
|
attachmentText = SlackTextFormatter(p.PullRequest.Body)
|
||||||
case api.HookIssueAssigned:
|
case api.HookIssueAssigned:
|
||||||
list, err := MakeAssigneeList(&Issue{ID: p.PullRequest.ID})
|
list := make([]string, len(p.PullRequest.Assignees))
|
||||||
if err != nil {
|
for i, user := range p.PullRequest.Assignees {
|
||||||
return &SlackPayload{}, err
|
list[i] = SlackLinkFormatter(setting.AppURL+user.UserName, user.UserName)
|
||||||
}
|
}
|
||||||
text = fmt.Sprintf("[%s] Pull request assigned to %s: %s by %s", p.Repository.FullName,
|
text = fmt.Sprintf("[%s] Pull request assigned to %s: %s by %s", p.Repository.FullName,
|
||||||
SlackLinkFormatter(setting.AppURL+list, list),
|
strings.Join(list, ", "),
|
||||||
titleLink, senderLink)
|
titleLink, senderLink)
|
||||||
case api.HookIssueUnassigned:
|
case api.HookIssueUnassigned:
|
||||||
text = fmt.Sprintf("[%s] Pull request unassigned: %s by %s", p.Repository.FullName, titleLink, senderLink)
|
text = fmt.Sprintf("[%s] Pull request unassigned: %s by %s", p.Repository.FullName, titleLink, senderLink)
|
||||||
|
|||||||
@@ -11,9 +11,9 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"gopkg.in/ldap.v2"
|
|
||||||
|
|
||||||
"code.gitea.io/gitea/modules/log"
|
"code.gitea.io/gitea/modules/log"
|
||||||
|
|
||||||
|
ldap "gopkg.in/ldap.v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
// SecurityProtocol protocol type
|
// SecurityProtocol protocol type
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import (
|
|||||||
"net/url"
|
"net/url"
|
||||||
|
|
||||||
"code.gitea.io/gitea/modules/auth"
|
"code.gitea.io/gitea/modules/auth"
|
||||||
|
"code.gitea.io/gitea/modules/log"
|
||||||
"code.gitea.io/gitea/modules/setting"
|
"code.gitea.io/gitea/modules/setting"
|
||||||
"github.com/go-macaron/csrf"
|
"github.com/go-macaron/csrf"
|
||||||
macaron "gopkg.in/macaron.v1"
|
macaron "gopkg.in/macaron.v1"
|
||||||
@@ -32,30 +33,30 @@ func Toggle(options *ToggleOptions) macaron.Handler {
|
|||||||
|
|
||||||
// Check prohibit login users.
|
// Check prohibit login users.
|
||||||
if ctx.IsSigned {
|
if ctx.IsSigned {
|
||||||
|
if !ctx.User.IsActive && setting.Service.RegisterEmailConfirm {
|
||||||
if ctx.User.ProhibitLogin {
|
ctx.Data["Title"] = ctx.Tr("auth.active_your_account")
|
||||||
|
ctx.HTML(200, "user/auth/activate")
|
||||||
|
return
|
||||||
|
} else if !ctx.User.IsActive || ctx.User.ProhibitLogin {
|
||||||
|
log.Info("Failed authentication attempt for %s from %s", ctx.User.Name, ctx.RemoteAddr())
|
||||||
ctx.Data["Title"] = ctx.Tr("auth.prohibit_login")
|
ctx.Data["Title"] = ctx.Tr("auth.prohibit_login")
|
||||||
ctx.HTML(200, "user/auth/prohibit_login")
|
ctx.HTML(200, "user/auth/prohibit_login")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// prevent infinite redirection
|
|
||||||
// also make sure that the form cannot be accessed by
|
|
||||||
// users who don't need this
|
|
||||||
if ctx.Req.URL.Path == setting.AppSubURL+"/user/settings/change_password" {
|
|
||||||
if !ctx.User.MustChangePassword {
|
|
||||||
ctx.Redirect(setting.AppSubURL + "/")
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if ctx.User.MustChangePassword {
|
if ctx.User.MustChangePassword {
|
||||||
|
if ctx.Req.URL.Path != "/user/settings/change_password" {
|
||||||
ctx.Data["Title"] = ctx.Tr("auth.must_change_password")
|
ctx.Data["Title"] = ctx.Tr("auth.must_change_password")
|
||||||
ctx.Data["ChangePasscodeLink"] = setting.AppSubURL + "/user/change_password"
|
ctx.Data["ChangePasscodeLink"] = setting.AppSubURL + "/user/change_password"
|
||||||
ctx.SetCookie("redirect_to", url.QueryEscape(setting.AppSubURL+ctx.Req.RequestURI), 0, setting.AppSubURL)
|
ctx.SetCookie("redirect_to", url.QueryEscape(setting.AppSubURL+ctx.Req.RequestURI), 0, setting.AppSubURL)
|
||||||
ctx.Redirect(setting.AppSubURL + "/user/settings/change_password")
|
ctx.Redirect(setting.AppSubURL + "/user/settings/change_password")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
} else if ctx.Req.URL.Path == "/user/settings/change_password" {
|
||||||
|
// make sure that the form cannot be accessed by users who don't need this
|
||||||
|
ctx.Redirect(setting.AppSubURL + "/")
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Redirect to dashboard if user tries to visit any non-login page.
|
// Redirect to dashboard if user tries to visit any non-login page.
|
||||||
|
|||||||
@@ -234,6 +234,23 @@ func RenderCommitMessage(
|
|||||||
return ctx.postProcess(rawHTML)
|
return ctx.postProcess(rawHTML)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// RenderDescriptionHTML will use similar logic as PostProcess, but will
|
||||||
|
// use a single special linkProcessor.
|
||||||
|
func RenderDescriptionHTML(
|
||||||
|
rawHTML []byte,
|
||||||
|
urlPrefix string,
|
||||||
|
metas map[string]string,
|
||||||
|
) ([]byte, error) {
|
||||||
|
ctx := &postProcessCtx{
|
||||||
|
metas: metas,
|
||||||
|
urlPrefix: urlPrefix,
|
||||||
|
procs: []processor{
|
||||||
|
descriptionLinkProcessor,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
return ctx.postProcess(rawHTML)
|
||||||
|
}
|
||||||
|
|
||||||
var byteBodyTag = []byte("<body>")
|
var byteBodyTag = []byte("<body>")
|
||||||
var byteBodyTagClosing = []byte("</body>")
|
var byteBodyTagClosing = []byte("</body>")
|
||||||
|
|
||||||
@@ -668,3 +685,34 @@ func genDefaultLinkProcessor(defaultLink string) processor {
|
|||||||
node.FirstChild, node.LastChild = ch, ch
|
node.FirstChild, node.LastChild = ch, ch
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// descriptionLinkProcessor creates links for DescriptionHTML
|
||||||
|
func descriptionLinkProcessor(ctx *postProcessCtx, node *html.Node) {
|
||||||
|
m := linkRegex.FindStringIndex(node.Data)
|
||||||
|
if m == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
uri := node.Data[m[0]:m[1]]
|
||||||
|
replaceContent(node, m[0], m[1], createDescriptionLink(uri, uri))
|
||||||
|
}
|
||||||
|
|
||||||
|
func createDescriptionLink(href, content string) *html.Node {
|
||||||
|
textNode := &html.Node{
|
||||||
|
Type: html.TextNode,
|
||||||
|
Data: content,
|
||||||
|
}
|
||||||
|
linkNode := &html.Node{
|
||||||
|
FirstChild: textNode,
|
||||||
|
LastChild: textNode,
|
||||||
|
Type: html.ElementNode,
|
||||||
|
Data: "a",
|
||||||
|
DataAtom: atom.A,
|
||||||
|
Attr: []html.Attribute{
|
||||||
|
{Key: "href", Val: href},
|
||||||
|
{Key: "target", Val: "_blank"},
|
||||||
|
{Key: "rel", Val: "noopener noreferrer"},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
textNode.Parent = linkNode
|
||||||
|
return linkNode
|
||||||
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
package markup
|
package markup
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"code.gitea.io/gitea/modules/log"
|
||||||
"code.gitea.io/gitea/modules/markup"
|
"code.gitea.io/gitea/modules/markup"
|
||||||
"code.gitea.io/gitea/modules/markup/markdown"
|
"code.gitea.io/gitea/modules/markup/markdown"
|
||||||
|
|
||||||
@@ -31,7 +32,13 @@ func (Parser) Extensions() []string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Render renders orgmode rawbytes to HTML
|
// Render renders orgmode rawbytes to HTML
|
||||||
func Render(rawBytes []byte, urlPrefix string, metas map[string]string, isWiki bool) []byte {
|
func Render(rawBytes []byte, urlPrefix string, metas map[string]string, isWiki bool) (result []byte) {
|
||||||
|
defer func() {
|
||||||
|
if err := recover(); err != nil {
|
||||||
|
log.Error(4, "Panic in orgmode.Render: %v Just returning the rawBytes", err)
|
||||||
|
result = rawBytes
|
||||||
|
}
|
||||||
|
}()
|
||||||
htmlFlags := blackfriday.HTML_USE_XHTML
|
htmlFlags := blackfriday.HTML_USE_XHTML
|
||||||
htmlFlags |= blackfriday.HTML_SKIP_STYLE
|
htmlFlags |= blackfriday.HTML_SKIP_STYLE
|
||||||
htmlFlags |= blackfriday.HTML_OMIT_CONTENTS
|
htmlFlags |= blackfriday.HTML_OMIT_CONTENTS
|
||||||
@@ -40,9 +47,8 @@ func Render(rawBytes []byte, urlPrefix string, metas map[string]string, isWiki b
|
|||||||
URLPrefix: urlPrefix,
|
URLPrefix: urlPrefix,
|
||||||
IsWiki: isWiki,
|
IsWiki: isWiki,
|
||||||
}
|
}
|
||||||
|
result = goorgeous.Org(rawBytes, renderer)
|
||||||
result := goorgeous.Org(rawBytes, renderer)
|
return
|
||||||
return result
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// RenderString reners orgmode string to HTML string
|
// RenderString reners orgmode string to HTML string
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -7,6 +7,115 @@ function htmlEncode(text) {
|
|||||||
var csrf;
|
var csrf;
|
||||||
var suburl;
|
var suburl;
|
||||||
|
|
||||||
|
// Polyfill for IE9+ support (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/from)
|
||||||
|
if (!Array.from) {
|
||||||
|
Array.from = (function () {
|
||||||
|
var toStr = Object.prototype.toString;
|
||||||
|
var isCallable = function (fn) {
|
||||||
|
return typeof fn === 'function' || toStr.call(fn) === '[object Function]';
|
||||||
|
};
|
||||||
|
var toInteger = function (value) {
|
||||||
|
var number = Number(value);
|
||||||
|
if (isNaN(number)) { return 0; }
|
||||||
|
if (number === 0 || !isFinite(number)) { return number; }
|
||||||
|
return (number > 0 ? 1 : -1) * Math.floor(Math.abs(number));
|
||||||
|
};
|
||||||
|
var maxSafeInteger = Math.pow(2, 53) - 1;
|
||||||
|
var toLength = function (value) {
|
||||||
|
var len = toInteger(value);
|
||||||
|
return Math.min(Math.max(len, 0), maxSafeInteger);
|
||||||
|
};
|
||||||
|
|
||||||
|
// The length property of the from method is 1.
|
||||||
|
return function from(arrayLike/*, mapFn, thisArg */) {
|
||||||
|
// 1. Let C be the this value.
|
||||||
|
var C = this;
|
||||||
|
|
||||||
|
// 2. Let items be ToObject(arrayLike).
|
||||||
|
var items = Object(arrayLike);
|
||||||
|
|
||||||
|
// 3. ReturnIfAbrupt(items).
|
||||||
|
if (arrayLike == null) {
|
||||||
|
throw new TypeError("Array.from requires an array-like object - not null or undefined");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. If mapfn is undefined, then let mapping be false.
|
||||||
|
var mapFn = arguments.length > 1 ? arguments[1] : void undefined;
|
||||||
|
var T;
|
||||||
|
if (typeof mapFn !== 'undefined') {
|
||||||
|
// 5. else
|
||||||
|
// 5. a If IsCallable(mapfn) is false, throw a TypeError exception.
|
||||||
|
if (!isCallable(mapFn)) {
|
||||||
|
throw new TypeError('Array.from: when provided, the second argument must be a function');
|
||||||
|
}
|
||||||
|
|
||||||
|
// 5. b. If thisArg was supplied, let T be thisArg; else let T be undefined.
|
||||||
|
if (arguments.length > 2) {
|
||||||
|
T = arguments[2];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 10. Let lenValue be Get(items, "length").
|
||||||
|
// 11. Let len be ToLength(lenValue).
|
||||||
|
var len = toLength(items.length);
|
||||||
|
|
||||||
|
// 13. If IsConstructor(C) is true, then
|
||||||
|
// 13. a. Let A be the result of calling the [[Construct]] internal method of C with an argument list containing the single item len.
|
||||||
|
// 14. a. Else, Let A be ArrayCreate(len).
|
||||||
|
var A = isCallable(C) ? Object(new C(len)) : new Array(len);
|
||||||
|
|
||||||
|
// 16. Let k be 0.
|
||||||
|
var k = 0;
|
||||||
|
// 17. Repeat, while k < len… (also steps a - h)
|
||||||
|
var kValue;
|
||||||
|
while (k < len) {
|
||||||
|
kValue = items[k];
|
||||||
|
if (mapFn) {
|
||||||
|
A[k] = typeof T === 'undefined' ? mapFn(kValue, k) : mapFn.call(T, kValue, k);
|
||||||
|
} else {
|
||||||
|
A[k] = kValue;
|
||||||
|
}
|
||||||
|
k += 1;
|
||||||
|
}
|
||||||
|
// 18. Let putStatus be Put(A, "length", len, true).
|
||||||
|
A.length = len;
|
||||||
|
// 20. Return A.
|
||||||
|
return A;
|
||||||
|
};
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign
|
||||||
|
if (typeof Object.assign != 'function') {
|
||||||
|
// Must be writable: true, enumerable: false, configurable: true
|
||||||
|
Object.defineProperty(Object, "assign", {
|
||||||
|
value: function assign(target, varArgs) { // .length of function is 2
|
||||||
|
'use strict';
|
||||||
|
if (target == null) { // TypeError if undefined or null
|
||||||
|
throw new TypeError('Cannot convert undefined or null to object');
|
||||||
|
}
|
||||||
|
|
||||||
|
var to = Object(target);
|
||||||
|
|
||||||
|
for (var index = 1; index < arguments.length; index++) {
|
||||||
|
var nextSource = arguments[index];
|
||||||
|
|
||||||
|
if (nextSource != null) { // Skip over if undefined or null
|
||||||
|
for (var nextKey in nextSource) {
|
||||||
|
// Avoid bugs when hasOwnProperty is shadowed
|
||||||
|
if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) {
|
||||||
|
to[nextKey] = nextSource[nextKey];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return to;
|
||||||
|
},
|
||||||
|
writable: true,
|
||||||
|
configurable: true
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function initCommentPreviewTab($form) {
|
function initCommentPreviewTab($form) {
|
||||||
var $tabMenu = $form.find('.tabular.menu');
|
var $tabMenu = $form.find('.tabular.menu');
|
||||||
$tabMenu.find('.item').tab();
|
$tabMenu.find('.item').tab();
|
||||||
@@ -2348,7 +2457,6 @@ function initHeatmap(appElementId, heatmapUser, locale) {
|
|||||||
this.getColor(4),
|
this.getColor(4),
|
||||||
this.getColor(5)
|
this.getColor(5)
|
||||||
];
|
];
|
||||||
console.log(this.colorRange);
|
|
||||||
this.endDate = new Date();
|
this.endDate = new Date();
|
||||||
this.loadHeatmap(this.user);
|
this.loadHeatmap(this.user);
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -384,33 +384,12 @@ pre, code {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.ui.floating.dropdown {
|
||||||
.overflow.menu {
|
.overflow.menu {
|
||||||
.items {
|
.scrolling.menu.items {
|
||||||
max-height: 300px;
|
border-radius: 0px !important;
|
||||||
overflow-y: auto;
|
box-shadow: none !important;
|
||||||
.item {
|
border-bottom: 1px solid rgba(34, 36, 38, 0.15);
|
||||||
position: relative;
|
|
||||||
cursor: pointer;
|
|
||||||
display: block;
|
|
||||||
border: none;
|
|
||||||
height: auto;
|
|
||||||
border-top: none;
|
|
||||||
line-height: 1em;
|
|
||||||
color: rgba(0,0,0,.8);
|
|
||||||
padding: .71428571em 1.14285714em !important;
|
|
||||||
font-size: 1rem;
|
|
||||||
text-transform: none;
|
|
||||||
font-weight: 400;
|
|
||||||
box-shadow: none;
|
|
||||||
-webkit-touch-callout: none;
|
|
||||||
&.active {
|
|
||||||
font-weight: 700;
|
|
||||||
}
|
|
||||||
&:hover {
|
|
||||||
background: rgba(0,0,0,.05);
|
|
||||||
color: rgba(0,0,0,.8);
|
|
||||||
z-index: 13;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
9
public/vendor/librejs.html
vendored
9
public/vendor/librejs.html
vendored
@@ -48,7 +48,7 @@
|
|||||||
<tr>
|
<tr>
|
||||||
<td><a href="./plugins/vue/vue.min.js">vue.min.js</a></td>
|
<td><a href="./plugins/vue/vue.min.js">vue.min.js</a></td>
|
||||||
<td><a href="https://github.com/vuejs/vue/blob/dev/LICENSE">Expat</a></td>
|
<td><a href="https://github.com/vuejs/vue/blob/dev/LICENSE">Expat</a></td>
|
||||||
<td><a href="https://github.com/vuejs/vue/archive/v2.1.10.tar.gz">vue.js-v2.1.10.tar.gz</a></td>
|
<td><a href="https://github.com/vuejs/vue/archive/v2.6.6.tar.gz">vue.js-v2.6.6.tar.gz</a></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td><a href="./plugins/emojify/emojify.min.js">emojify.min.js</a></td>
|
<td><a href="./plugins/emojify/emojify.min.js">emojify.min.js</a></td>
|
||||||
@@ -136,7 +136,7 @@
|
|||||||
<td><a href="https://github.com/swagger-api/swagger-ui/archive/v3.0.4.tar.gz">swagger-ui-v3.0.4.tar.gz</a></td>
|
<td><a href="https://github.com/swagger-api/swagger-ui/archive/v3.0.4.tar.gz">swagger-ui-v3.0.4.tar.gz</a></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td><a href="./plugins/vue-calendar-heatmap">vue-calendar-heatmap</a></td>
|
<td><a href="./plugins/vue-calendar-heatmap/">vue-calendar-heatmap</a></td>
|
||||||
<td><a href="https://github.com/WildCodeSchool/vue-calendar-heatmap/blob/master/README.md">MIT</a></td>
|
<td><a href="https://github.com/WildCodeSchool/vue-calendar-heatmap/blob/master/README.md">MIT</a></td>
|
||||||
<td><a href="https://github.com/WildCodeSchool/vue-calendar-heatmap/archive/master.zip">7f48b20.zip</a></td>
|
<td><a href="https://github.com/WildCodeSchool/vue-calendar-heatmap/archive/master.zip">7f48b20.zip</a></td>
|
||||||
</tr>
|
</tr>
|
||||||
@@ -145,6 +145,11 @@
|
|||||||
<td><a href="https://github.com/moment/moment/blob/develop/LICENSE">MIT</a></td>
|
<td><a href="https://github.com/moment/moment/blob/develop/LICENSE">MIT</a></td>
|
||||||
<td><a href="https://github.com/moment/moment/archive/2.22.2.tar.gz">0.4.1.tar.gz</a></td>
|
<td><a href="https://github.com/moment/moment/archive/2.22.2.tar.gz">0.4.1.tar.gz</a></td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><a href="./plugins/es6-promise/">es6-promise</a></td>
|
||||||
|
<td><a href="https://github.com/stefanpenner/es6-promise/blob/master/LICENSE">MIT</a></td>
|
||||||
|
<td><a href="https://github.com/stefanpenner/es6-promise/archive/v4.2.6.tar.gz">4.2.6.tar.gz</a></td>
|
||||||
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</body>
|
</body>
|
||||||
|
|||||||
1
public/vendor/plugins/es6-promise/es6-promise.auto.min.js
vendored
Normal file
1
public/vendor/plugins/es6-promise/es6-promise.auto.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
8
public/vendor/plugins/vue/vue.min.js
vendored
8
public/vendor/plugins/vue/vue.min.js
vendored
File diff suppressed because one or more lines are too long
@@ -129,7 +129,7 @@ func GetIssue(ctx *context.APIContext) {
|
|||||||
// responses:
|
// responses:
|
||||||
// "200":
|
// "200":
|
||||||
// "$ref": "#/responses/Issue"
|
// "$ref": "#/responses/Issue"
|
||||||
issue, err := models.GetIssueByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index"))
|
issue, err := models.GetIssueWithAttrsByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if models.IsErrIssueNotExist(err) {
|
if models.IsErrIssueNotExist(err) {
|
||||||
ctx.Status(404)
|
ctx.Status(404)
|
||||||
|
|||||||
@@ -668,8 +668,8 @@ func parseCompareInfo(ctx *context.APIContext, form api.CreatePullRequestOption)
|
|||||||
ctx.ServerError("GetUserRepoPermission", err)
|
ctx.ServerError("GetUserRepoPermission", err)
|
||||||
return nil, nil, nil, nil, "", ""
|
return nil, nil, nil, nil, "", ""
|
||||||
}
|
}
|
||||||
if !perm.CanWrite(models.UnitTypeCode) {
|
if !perm.CanReadIssuesOrPulls(true) {
|
||||||
log.Trace("ParseCompareInfo[%d]: does not have write access or site admin", baseRepo.ID)
|
log.Trace("ParseCompareInfo[%d]: cannot create/read pull requests", baseRepo.ID)
|
||||||
ctx.Status(404)
|
ctx.Status(404)
|
||||||
return nil, nil, nil, nil, "", ""
|
return nil, nil, nil, nil, "", ""
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -400,6 +400,11 @@ func Migrate(ctx *context.APIContext, form auth.MigrateRepoForm) {
|
|||||||
RemoteAddr: remoteAddr,
|
RemoteAddr: remoteAddr,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
if models.IsErrRepoAlreadyExist(err) {
|
||||||
|
ctx.Error(409, "", "The repository with the same name already exists.")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
err = util.URLSanitizedError(err, remoteAddr)
|
err = util.URLSanitizedError(err, remoteAddr)
|
||||||
if repo != nil {
|
if repo != nil {
|
||||||
if errDelete := models.DeleteRepository(ctx.User, ctxUser.ID, repo.ID); errDelete != nil {
|
if errDelete := models.DeleteRepository(ctx.User, ctxUser.ID, repo.ID); errDelete != nil {
|
||||||
|
|||||||
@@ -6,11 +6,13 @@ package routers
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"net/url"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"code.gitea.io/gitea/models"
|
"code.gitea.io/gitea/models"
|
||||||
"code.gitea.io/gitea/modules/base"
|
"code.gitea.io/gitea/modules/base"
|
||||||
"code.gitea.io/gitea/modules/context"
|
"code.gitea.io/gitea/modules/context"
|
||||||
|
"code.gitea.io/gitea/modules/log"
|
||||||
"code.gitea.io/gitea/modules/search"
|
"code.gitea.io/gitea/modules/search"
|
||||||
"code.gitea.io/gitea/modules/setting"
|
"code.gitea.io/gitea/modules/setting"
|
||||||
"code.gitea.io/gitea/modules/util"
|
"code.gitea.io/gitea/modules/util"
|
||||||
@@ -38,6 +40,15 @@ func Home(ctx *context.Context) {
|
|||||||
if !ctx.User.IsActive && setting.Service.RegisterEmailConfirm {
|
if !ctx.User.IsActive && setting.Service.RegisterEmailConfirm {
|
||||||
ctx.Data["Title"] = ctx.Tr("auth.active_your_account")
|
ctx.Data["Title"] = ctx.Tr("auth.active_your_account")
|
||||||
ctx.HTML(200, user.TplActivate)
|
ctx.HTML(200, user.TplActivate)
|
||||||
|
} else if !ctx.User.IsActive || ctx.User.ProhibitLogin {
|
||||||
|
log.Info("Failed authentication attempt for %s from %s", ctx.User.Name, ctx.RemoteAddr())
|
||||||
|
ctx.Data["Title"] = ctx.Tr("auth.prohibit_login")
|
||||||
|
ctx.HTML(200, "user/auth/prohibit_login")
|
||||||
|
} else if ctx.User.MustChangePassword {
|
||||||
|
ctx.Data["Title"] = ctx.Tr("auth.must_change_password")
|
||||||
|
ctx.Data["ChangePasscodeLink"] = setting.AppSubURL + "/user/change_password"
|
||||||
|
ctx.SetCookie("redirect_to", url.QueryEscape(setting.AppSubURL+ctx.Req.RequestURI), 0, setting.AppSubURL)
|
||||||
|
ctx.Redirect(setting.AppSubURL + "/user/settings/change_password")
|
||||||
} else {
|
} else {
|
||||||
user.Dashboard(ctx)
|
user.Dashboard(ctx)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -288,8 +288,6 @@ func EditTeamPost(ctx *context.Context, form auth.CreateTeamForm) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
models.UpdateTeamUnits(t, units)
|
models.UpdateTeamUnits(t, units)
|
||||||
} else {
|
|
||||||
models.UpdateTeamUnits(t, nil)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ctx.HasError() {
|
if ctx.HasError() {
|
||||||
|
|||||||
@@ -684,8 +684,8 @@ func ParseCompareInfo(ctx *context.Context) (*models.User, *models.Repository, *
|
|||||||
ctx.ServerError("GetUserRepoPermission", err)
|
ctx.ServerError("GetUserRepoPermission", err)
|
||||||
return nil, nil, nil, nil, "", ""
|
return nil, nil, nil, nil, "", ""
|
||||||
}
|
}
|
||||||
if !perm.CanWrite(models.UnitTypeCode) {
|
if !perm.CanReadIssuesOrPulls(true) {
|
||||||
log.Trace("ParseCompareInfo[%d]: does not have write access or site admin", baseRepo.ID)
|
log.Trace("ParseCompareInfo[%d]: cannot create/read pull requests", baseRepo.ID)
|
||||||
ctx.NotFound("ParseCompareInfo", nil)
|
ctx.NotFound("ParseCompareInfo", nil)
|
||||||
return nil, nil, nil, nil, "", ""
|
return nil, nil, nil, nil, "", ""
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -256,6 +256,11 @@ func MigratePost(ctx *context.Context, form auth.MigrateRepoForm) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if models.IsErrRepoAlreadyExist(err) {
|
||||||
|
ctx.RenderWithErr(ctx.Tr("form.repo_name_been_taken"), tplMigrate, &form)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// remoteAddr may contain credentials, so we sanitize it
|
// remoteAddr may contain credentials, so we sanitize it
|
||||||
err = util.URLSanitizedError(err, remoteAddr)
|
err = util.URLSanitizedError(err, remoteAddr)
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
package repo
|
package repo
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@@ -36,6 +37,7 @@ const (
|
|||||||
func Settings(ctx *context.Context) {
|
func Settings(ctx *context.Context) {
|
||||||
ctx.Data["Title"] = ctx.Tr("repo.settings")
|
ctx.Data["Title"] = ctx.Tr("repo.settings")
|
||||||
ctx.Data["PageIsSettingsOptions"] = true
|
ctx.Data["PageIsSettingsOptions"] = true
|
||||||
|
ctx.Data["ForcePrivate"] = setting.Repository.ForcePrivate
|
||||||
ctx.HTML(200, tplSettingsOptions)
|
ctx.HTML(200, tplSettingsOptions)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -94,6 +96,12 @@ func SettingsPost(ctx *context.Context, form auth.RepoSettingForm) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
visibilityChanged := repo.IsPrivate != form.Private
|
visibilityChanged := repo.IsPrivate != form.Private
|
||||||
|
// when ForcePrivate enabled, you could change public repo to private, but could not change private to public
|
||||||
|
if visibilityChanged && setting.Repository.ForcePrivate && !form.Private {
|
||||||
|
ctx.ServerError("Force Private enabled", errors.New("cannot change private repository to public"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
repo.IsPrivate = form.Private
|
repo.IsPrivate = form.Private
|
||||||
if err := models.UpdateRepository(repo, visibilityChanged); err != nil {
|
if err := models.UpdateRepository(repo, visibilityChanged); err != nil {
|
||||||
ctx.ServerError("UpdateRepository", err)
|
ctx.ServerError("UpdateRepository", err)
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ func renderDirectory(ctx *context.Context, treeLink string) {
|
|||||||
}
|
}
|
||||||
entries.CustomSort(base.NaturalSortLess)
|
entries.CustomSort(base.NaturalSortLess)
|
||||||
|
|
||||||
ctx.Data["Files"], err = entries.GetCommitsInfo(ctx.Repo.Commit, ctx.Repo.TreePath)
|
ctx.Data["Files"], err = entries.GetCommitsInfo(ctx.Repo.Commit, ctx.Repo.TreePath, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctx.ServerError("GetCommitsInfo", err)
|
ctx.ServerError("GetCommitsInfo", err)
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -161,6 +161,19 @@ func SignInPost(ctx *context.Context, form auth.SignInForm) {
|
|||||||
} else if models.IsErrEmailAlreadyUsed(err) {
|
} else if models.IsErrEmailAlreadyUsed(err) {
|
||||||
ctx.RenderWithErr(ctx.Tr("form.email_been_used"), tplSignIn, &form)
|
ctx.RenderWithErr(ctx.Tr("form.email_been_used"), tplSignIn, &form)
|
||||||
log.Info("Failed authentication attempt for %s from %s", form.UserName, ctx.RemoteAddr())
|
log.Info("Failed authentication attempt for %s from %s", form.UserName, ctx.RemoteAddr())
|
||||||
|
} else if models.IsErrUserProhibitLogin(err) {
|
||||||
|
log.Info("Failed authentication attempt for %s from %s", form.UserName, ctx.RemoteAddr())
|
||||||
|
ctx.Data["Title"] = ctx.Tr("auth.prohibit_login")
|
||||||
|
ctx.HTML(200, "user/auth/prohibit_login")
|
||||||
|
} else if models.IsErrUserInactive(err) {
|
||||||
|
if setting.Service.RegisterEmailConfirm {
|
||||||
|
ctx.Data["Title"] = ctx.Tr("auth.active_your_account")
|
||||||
|
ctx.HTML(200, TplActivate)
|
||||||
|
} else {
|
||||||
|
log.Info("Failed authentication attempt for %s from %s", form.UserName, ctx.RemoteAddr())
|
||||||
|
ctx.Data["Title"] = ctx.Tr("auth.prohibit_login")
|
||||||
|
ctx.HTML(200, "user/auth/prohibit_login")
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
ctx.ServerError("UserSignIn", err)
|
ctx.ServerError("UserSignIn", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -112,6 +112,7 @@
|
|||||||
<script src="{{AppSubUrl}}/vendor/plugins/semantic/semantic.min.js"></script>
|
<script src="{{AppSubUrl}}/vendor/plugins/semantic/semantic.min.js"></script>
|
||||||
<script src="{{AppSubUrl}}/js/index.js?v={{MD5 AppVer}}"></script>
|
<script src="{{AppSubUrl}}/js/index.js?v={{MD5 AppVer}}"></script>
|
||||||
{{if .EnableHeatmap}}
|
{{if .EnableHeatmap}}
|
||||||
|
<script src="{{AppSubUrl}}/vendor/plugins/es6-promise/es6-promise.auto.min.js" charset="utf-8"></script>
|
||||||
<script src="{{AppSubUrl}}/vendor/plugins/moment/moment.min.js" charset="utf-8"></script>
|
<script src="{{AppSubUrl}}/vendor/plugins/moment/moment.min.js" charset="utf-8"></script>
|
||||||
<script src="{{AppSubUrl}}/vendor/plugins/vue-calendar-heatmap/vue-calendar-heatmap.browser.js" charset="utf-8"></script>
|
<script src="{{AppSubUrl}}/vendor/plugins/vue-calendar-heatmap/vue-calendar-heatmap.browser.js" charset="utf-8"></script>
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
<meta http-equiv="x-ua-compatible" content="ie=edge">
|
<meta http-equiv="x-ua-compatible" content="ie=edge">
|
||||||
<title>{{if .Title}}{{.Title}} - {{end}}{{AppName}}</title>
|
<title>{{if .Title}}{{.Title}} - {{end}}{{AppName}}</title>
|
||||||
<link rel="manifest" href="{{AppSubUrl}}/manifest.json">
|
<link rel="manifest" href="{{AppSubUrl}}/manifest.json" crossorigin="use-credentials">
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
if ('serviceWorker' in navigator) {
|
if ('serviceWorker' in navigator) {
|
||||||
|
|||||||
@@ -54,7 +54,7 @@
|
|||||||
<div class="ui stackable secondary menu mobile--margin-between-items mobile--no-negative-margins">
|
<div class="ui stackable secondary menu mobile--margin-between-items mobile--no-negative-margins">
|
||||||
{{if and .PullRequestCtx.Allowed .IsViewBranch}}
|
{{if and .PullRequestCtx.Allowed .IsViewBranch}}
|
||||||
<div class="fitted item">
|
<div class="fitted item">
|
||||||
<a href="{{.BaseRepo.Link}}/compare/{{.BaseRepo.DefaultBranch | EscapePound}}...{{ if .Repository.IsFork }}{{.Repository.Owner.Name}}{{ else }}{{ .SignedUserName }}{{ end }}:{{.BranchName | EscapePound}}">
|
<a href="{{.BaseRepo.Link}}/compare/{{.BaseRepo.DefaultBranch | EscapePound}}...{{if ne .Repository.Owner.Name .BaseRepo.Owner.Name}}{{.Repository.Owner.Name}}:{{end}}{{.BranchName | EscapePound}}">
|
||||||
<button class="ui green tiny compact button"><i class="octicon octicon-git-compare"></i></button>
|
<button class="ui green tiny compact button"><i class="octicon octicon-git-compare"></i></button>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
<div class="inline field">
|
<div class="inline field">
|
||||||
<label>{{.i18n.Tr "repo.visibility"}}</label>
|
<label>{{.i18n.Tr "repo.visibility"}}</label>
|
||||||
<div class="ui checkbox">
|
<div class="ui checkbox">
|
||||||
<input name="private" type="checkbox" {{if .Repository.IsPrivate}}checked{{end}}>
|
<input name="private" type="checkbox" {{if .Repository.IsPrivate}}checked{{end}}{{if and $.ForcePrivate .Repository.IsPrivate}} readonly{{end}}>
|
||||||
<label>{{.i18n.Tr "repo.visibility_helper" | Safe}} {{if .Repository.NumForks}}<span class="text red">{{.i18n.Tr "repo.visibility_fork_helper"}}</span>{{end}}</label>
|
<label>{{.i18n.Tr "repo.visibility_helper" | Safe}} {{if .Repository.NumForks}}<span class="text red">{{.i18n.Tr "repo.visibility_fork_helper"}}</span>{{end}}</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
<div class="ui header">
|
<div class="ui header">
|
||||||
{{.i18n.Tr "home.switch_dashboard_context"}}
|
{{.i18n.Tr "home.switch_dashboard_context"}}
|
||||||
</div>
|
</div>
|
||||||
<div class="items">
|
<div class="scrolling menu items">
|
||||||
<a class="{{if eq .ContextUser.ID .SignedUser.ID}}active selected{{end}} item" href="{{AppSubUrl}}/{{if .PageIsIssues}}issues{{else if .PageIsPulls}}pulls{{end}}">
|
<a class="{{if eq .ContextUser.ID .SignedUser.ID}}active selected{{end}} item" href="{{AppSubUrl}}/{{if .PageIsIssues}}issues{{else if .PageIsPulls}}pulls{{end}}">
|
||||||
<img class="ui avatar image" src="{{.SignedUser.RelAvatarLink}}">
|
<img class="ui avatar image" src="{{.SignedUser.RelAvatarLink}}">
|
||||||
{{.SignedUser.Name}}
|
{{.SignedUser.Name}}
|
||||||
|
|||||||
11
vendor/code.gitea.io/git/cache.go
generated
vendored
Normal file
11
vendor/code.gitea.io/git/cache.go
generated
vendored
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
// Copyright 2019 The Gitea Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a MIT-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package git
|
||||||
|
|
||||||
|
// LastCommitCache cache
|
||||||
|
type LastCommitCache interface {
|
||||||
|
Get(repoPath, ref, entryPath string) (*Commit, error)
|
||||||
|
Put(repoPath, ref, entryPath string, commit *Commit) error
|
||||||
|
}
|
||||||
53
vendor/code.gitea.io/git/commit.go
generated
vendored
53
vendor/code.gitea.io/git/commit.go
generated
vendored
@@ -1,4 +1,5 @@
|
|||||||
// Copyright 2015 The Gogs Authors. All rights reserved.
|
// Copyright 2015 The Gogs Authors. All rights reserved.
|
||||||
|
// Copyright 2018 The Gitea Authors. All rights reserved.
|
||||||
// Use of this source code is governed by a MIT-style
|
// Use of this source code is governed by a MIT-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
@@ -9,6 +10,7 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"container/list"
|
"container/list"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
@@ -16,6 +18,7 @@ import (
|
|||||||
|
|
||||||
// Commit represents a git commit.
|
// Commit represents a git commit.
|
||||||
type Commit struct {
|
type Commit struct {
|
||||||
|
Branch string // Branch this commit belongs to
|
||||||
Tree
|
Tree
|
||||||
ID SHA1 // The ID of this commit object
|
ID SHA1 // The ID of this commit object
|
||||||
Author *Signature
|
Author *Signature
|
||||||
@@ -279,6 +282,56 @@ func (c *Commit) GetSubModule(entryname string) (*SubModule, error) {
|
|||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CommitFileStatus represents status of files in a commit.
|
||||||
|
type CommitFileStatus struct {
|
||||||
|
Added []string
|
||||||
|
Removed []string
|
||||||
|
Modified []string
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewCommitFileStatus creates a CommitFileStatus
|
||||||
|
func NewCommitFileStatus() *CommitFileStatus {
|
||||||
|
return &CommitFileStatus{
|
||||||
|
[]string{}, []string{}, []string{},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetCommitFileStatus returns file status of commit in given repository.
|
||||||
|
func GetCommitFileStatus(repoPath, commitID string) (*CommitFileStatus, error) {
|
||||||
|
stdout, w := io.Pipe()
|
||||||
|
done := make(chan struct{})
|
||||||
|
fileStatus := NewCommitFileStatus()
|
||||||
|
go func() {
|
||||||
|
scanner := bufio.NewScanner(stdout)
|
||||||
|
for scanner.Scan() {
|
||||||
|
fields := strings.Fields(scanner.Text())
|
||||||
|
if len(fields) < 2 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
switch fields[0][0] {
|
||||||
|
case 'A':
|
||||||
|
fileStatus.Added = append(fileStatus.Added, fields[1])
|
||||||
|
case 'D':
|
||||||
|
fileStatus.Removed = append(fileStatus.Removed, fields[1])
|
||||||
|
case 'M':
|
||||||
|
fileStatus.Modified = append(fileStatus.Modified, fields[1])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
done <- struct{}{}
|
||||||
|
}()
|
||||||
|
|
||||||
|
stderr := new(bytes.Buffer)
|
||||||
|
err := NewCommand("show", "--name-status", "--pretty=format:''", commitID).RunInDirPipeline(repoPath, w, stderr)
|
||||||
|
w.Close() // Close writer to exit parsing goroutine
|
||||||
|
if err != nil {
|
||||||
|
return nil, concatenateError(err, stderr.String())
|
||||||
|
}
|
||||||
|
|
||||||
|
<-done
|
||||||
|
return fileStatus, nil
|
||||||
|
}
|
||||||
|
|
||||||
// GetFullCommitID returns full length (40) of commit ID by given short SHA in a repository.
|
// GetFullCommitID returns full length (40) of commit ID by given short SHA in a repository.
|
||||||
func GetFullCommitID(repoPath, shortID string) (string, error) {
|
func GetFullCommitID(repoPath, shortID string) (string, error) {
|
||||||
if len(shortID) >= 40 {
|
if len(shortID) >= 40 {
|
||||||
|
|||||||
20
vendor/code.gitea.io/git/commit_info.go
generated
vendored
20
vendor/code.gitea.io/git/commit_info.go
generated
vendored
@@ -72,13 +72,20 @@ func (state *getCommitsInfoState) getTargetedEntryPath() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// repeatedly perform targeted searches for unpopulated entries
|
// repeatedly perform targeted searches for unpopulated entries
|
||||||
func targetedSearch(state *getCommitsInfoState, done chan error) {
|
func targetedSearch(state *getCommitsInfoState, done chan error, cache LastCommitCache) {
|
||||||
for {
|
for {
|
||||||
entryPath := state.getTargetedEntryPath()
|
entryPath := state.getTargetedEntryPath()
|
||||||
if len(entryPath) == 0 {
|
if len(entryPath) == 0 {
|
||||||
done <- nil
|
done <- nil
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if cache != nil {
|
||||||
|
commit, err := cache.Get(state.headCommit.repo.Path, state.headCommit.ID.String(), entryPath)
|
||||||
|
if err == nil && commit != nil {
|
||||||
|
state.update(entryPath, commit)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
command := NewCommand("rev-list", "-1", state.headCommit.ID.String(), "--", entryPath)
|
command := NewCommand("rev-list", "-1", state.headCommit.ID.String(), "--", entryPath)
|
||||||
output, err := command.RunInDir(state.headCommit.repo.Path)
|
output, err := command.RunInDir(state.headCommit.repo.Path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -96,6 +103,9 @@ func targetedSearch(state *getCommitsInfoState, done chan error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
state.update(entryPath, commit)
|
state.update(entryPath, commit)
|
||||||
|
if cache != nil {
|
||||||
|
cache.Put(state.headCommit.repo.Path, state.headCommit.ID.String(), entryPath, commit)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -118,9 +128,9 @@ func initGetCommitInfoState(entries Entries, headCommit *Commit, treePath string
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GetCommitsInfo gets information of all commits that are corresponding to these entries
|
// GetCommitsInfo gets information of all commits that are corresponding to these entries
|
||||||
func (tes Entries) GetCommitsInfo(commit *Commit, treePath string) ([][]interface{}, error) {
|
func (tes Entries) GetCommitsInfo(commit *Commit, treePath string, cache LastCommitCache) ([][]interface{}, error) {
|
||||||
state := initGetCommitInfoState(tes, commit, treePath)
|
state := initGetCommitInfoState(tes, commit, treePath)
|
||||||
if err := getCommitsInfo(state); err != nil {
|
if err := getCommitsInfo(state, cache); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if len(state.commits) < len(state.entryPaths) {
|
if len(state.commits) < len(state.entryPaths) {
|
||||||
@@ -188,7 +198,7 @@ func (state *getCommitsInfoState) update(entryPath string, commit *Commit) bool
|
|||||||
|
|
||||||
const getCommitsInfoPretty = "--pretty=format:%H %ct %s"
|
const getCommitsInfoPretty = "--pretty=format:%H %ct %s"
|
||||||
|
|
||||||
func getCommitsInfo(state *getCommitsInfoState) error {
|
func getCommitsInfo(state *getCommitsInfoState, cache LastCommitCache) error {
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), 1*time.Minute)
|
ctx, cancel := context.WithTimeout(context.Background(), 1*time.Minute)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
@@ -215,7 +225,7 @@ func getCommitsInfo(state *getCommitsInfoState) error {
|
|||||||
numThreads := runtime.NumCPU()
|
numThreads := runtime.NumCPU()
|
||||||
done := make(chan error, numThreads)
|
done := make(chan error, numThreads)
|
||||||
for i := 0; i < numThreads; i++ {
|
for i := 0; i < numThreads; i++ {
|
||||||
go targetedSearch(state, done)
|
go targetedSearch(state, done, cache)
|
||||||
}
|
}
|
||||||
|
|
||||||
scanner := bufio.NewScanner(readCloser)
|
scanner := bufio.NewScanner(readCloser)
|
||||||
|
|||||||
29
vendor/code.gitea.io/git/repo_commit.go
generated
vendored
29
vendor/code.gitea.io/git/repo_commit.go
generated
vendored
@@ -10,7 +10,7 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/mcuadros/go-version"
|
version "github.com/mcuadros/go-version"
|
||||||
)
|
)
|
||||||
|
|
||||||
// GetRefCommitID returns the last commit ID string of given reference (branch or tag).
|
// GetRefCommitID returns the last commit ID string of given reference (branch or tag).
|
||||||
@@ -32,7 +32,14 @@ func (repo *Repository) GetBranchCommitID(name string) (string, error) {
|
|||||||
|
|
||||||
// GetTagCommitID returns last commit ID string of given tag.
|
// GetTagCommitID returns last commit ID string of given tag.
|
||||||
func (repo *Repository) GetTagCommitID(name string) (string, error) {
|
func (repo *Repository) GetTagCommitID(name string) (string, error) {
|
||||||
return repo.GetRefCommitID(TagPrefix + name)
|
stdout, err := NewCommand("rev-list", "-n", "1", name).RunInDir(repo.Path)
|
||||||
|
if err != nil {
|
||||||
|
if strings.Contains(err.Error(), "unknown revision or path") {
|
||||||
|
return "", ErrNotExist{name, ""}
|
||||||
|
}
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return strings.TrimSpace(stdout), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// parseCommitData parses commit information from the (uncompressed) raw
|
// parseCommitData parses commit information from the (uncompressed) raw
|
||||||
@@ -94,7 +101,11 @@ l:
|
|||||||
sig, err := newGPGSignatureFromCommitline(data, (nextline+1)+sigindex, true)
|
sig, err := newGPGSignatureFromCommitline(data, (nextline+1)+sigindex, true)
|
||||||
if err == nil && sig != nil {
|
if err == nil && sig != nil {
|
||||||
// remove signature from commit message
|
// remove signature from commit message
|
||||||
|
if sigindex == 0 {
|
||||||
|
cm = ""
|
||||||
|
} else {
|
||||||
cm = cm[:sigindex-1]
|
cm = cm[:sigindex-1]
|
||||||
|
}
|
||||||
commit.Signature = sig
|
commit.Signature = sig
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -130,6 +141,14 @@ func (repo *Repository) getCommit(id SHA1) (*Commit, error) {
|
|||||||
commit.repo = repo
|
commit.repo = repo
|
||||||
commit.ID = id
|
commit.ID = id
|
||||||
|
|
||||||
|
data, err = NewCommand("name-rev", id.String()).RunInDirBytes(repo.Path)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// name-rev commitID ouput will be "COMMIT_ID master" or "COMMIT_ID master~12"
|
||||||
|
commit.Branch = strings.Split(strings.Split(string(data), " ")[1], "~")[0]
|
||||||
|
|
||||||
repo.commitCache.Set(id.String(), commit)
|
repo.commitCache.Set(id.String(), commit)
|
||||||
return commit, nil
|
return commit, nil
|
||||||
}
|
}
|
||||||
@@ -138,10 +157,14 @@ func (repo *Repository) getCommit(id SHA1) (*Commit, error) {
|
|||||||
func (repo *Repository) GetCommit(commitID string) (*Commit, error) {
|
func (repo *Repository) GetCommit(commitID string) (*Commit, error) {
|
||||||
if len(commitID) != 40 {
|
if len(commitID) != 40 {
|
||||||
var err error
|
var err error
|
||||||
commitID, err = NewCommand("rev-parse", commitID).RunInDir(repo.Path)
|
actualCommitID, err := NewCommand("rev-parse", commitID).RunInDir(repo.Path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
if strings.Contains(err.Error(), "unknown revision or path") {
|
||||||
|
return nil, ErrNotExist{commitID, ""}
|
||||||
|
}
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
commitID = actualCommitID
|
||||||
}
|
}
|
||||||
id, err := NewIDFromString(commitID)
|
id, err := NewIDFromString(commitID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
20
vendor/code.gitea.io/git/repo_tag.go
generated
vendored
20
vendor/code.gitea.io/git/repo_tag.go
generated
vendored
@@ -76,12 +76,12 @@ func (repo *Repository) getTag(id SHA1) (*Tag, error) {
|
|||||||
|
|
||||||
// GetTag returns a Git tag by given name.
|
// GetTag returns a Git tag by given name.
|
||||||
func (repo *Repository) GetTag(name string) (*Tag, error) {
|
func (repo *Repository) GetTag(name string) (*Tag, error) {
|
||||||
stdout, err := NewCommand("show-ref", "--tags", name).RunInDir(repo.Path)
|
idStr, err := repo.GetTagCommitID(name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
id, err := NewIDFromString(strings.Split(stdout, " ")[0])
|
id, err := NewIDFromString(idStr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -103,26 +103,18 @@ func (repo *Repository) GetTagInfos() ([]*Tag, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
tagNames := strings.Split(stdout, "\n")
|
tagNames := strings.Split(stdout, "\n")
|
||||||
var tags []*Tag
|
var tags = make([]*Tag, 0, len(tagNames))
|
||||||
for _, tagName := range tagNames {
|
for _, tagName := range tagNames {
|
||||||
tagName = strings.TrimSpace(tagName)
|
tagName = strings.TrimSpace(tagName)
|
||||||
if len(tagName) == 0 {
|
if len(tagName) == 0 {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
commitID, err := NewCommand("rev-parse", tagName).RunInDir(repo.Path)
|
|
||||||
|
tag, err := repo.GetTag(tagName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
commit, err := repo.GetCommit(commitID)
|
tags = append(tags, tag)
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
tags = append(tags, &Tag{
|
|
||||||
Name: tagName,
|
|
||||||
Message: commit.Message(),
|
|
||||||
Object: commit.ID,
|
|
||||||
Tagger: commit.Author,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
sortTagsByTime(tags)
|
sortTagsByTime(tags)
|
||||||
return tags, nil
|
return tags, nil
|
||||||
|
|||||||
16
vendor/code.gitea.io/git/submodule.go
generated
vendored
16
vendor/code.gitea.io/git/submodule.go
generated
vendored
@@ -29,13 +29,12 @@ func NewSubModuleFile(c *Commit, refURL, refID string) *SubModuleFile {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// RefURL guesses and returns reference URL.
|
func getRefURL(refURL, urlPrefix, parentPath string) string {
|
||||||
func (sf *SubModuleFile) RefURL(urlPrefix string, parentPath string) string {
|
if refURL == "" {
|
||||||
if sf.refURL == "" {
|
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
url := strings.TrimSuffix(sf.refURL, ".git")
|
url := strings.TrimSuffix(refURL, ".git")
|
||||||
|
|
||||||
// git://xxx/user/repo
|
// git://xxx/user/repo
|
||||||
if strings.HasPrefix(url, "git://") {
|
if strings.HasPrefix(url, "git://") {
|
||||||
@@ -67,12 +66,21 @@ func (sf *SubModuleFile) RefURL(urlPrefix string, parentPath string) string {
|
|||||||
if strings.Contains(urlPrefix, url[i+1:j]) {
|
if strings.Contains(urlPrefix, url[i+1:j]) {
|
||||||
return urlPrefix + url[j+1:]
|
return urlPrefix + url[j+1:]
|
||||||
}
|
}
|
||||||
|
if strings.HasPrefix(url, "ssh://") || strings.HasPrefix(url, "git+ssh://") {
|
||||||
|
k := strings.Index(url[j+1:], "/")
|
||||||
|
return "http://" + url[i+1:j] + "/" + url[j+1:][k+1:]
|
||||||
|
}
|
||||||
return "http://" + url[i+1:j] + "/" + url[j+1:]
|
return "http://" + url[i+1:j] + "/" + url[j+1:]
|
||||||
}
|
}
|
||||||
|
|
||||||
return url
|
return url
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// RefURL guesses and returns reference URL.
|
||||||
|
func (sf *SubModuleFile) RefURL(urlPrefix string, parentPath string) string {
|
||||||
|
return getRefURL(sf.refURL, urlPrefix, parentPath)
|
||||||
|
}
|
||||||
|
|
||||||
// RefID returns reference ID.
|
// RefID returns reference ID.
|
||||||
func (sf *SubModuleFile) RefID() string {
|
func (sf *SubModuleFile) RefID() string {
|
||||||
return sf.refID
|
return sf.refID
|
||||||
|
|||||||
22
vendor/code.gitea.io/git/tree.go
generated
vendored
22
vendor/code.gitea.io/git/tree.go
generated
vendored
@@ -18,6 +18,9 @@ type Tree struct {
|
|||||||
|
|
||||||
entries Entries
|
entries Entries
|
||||||
entriesParsed bool
|
entriesParsed bool
|
||||||
|
|
||||||
|
entriesRecursive Entries
|
||||||
|
entriesRecursiveParsed bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewTree create a new tree according the repository and commit id
|
// NewTree create a new tree according the repository and commit id
|
||||||
@@ -67,20 +70,29 @@ func (t *Tree) ListEntries() (Entries, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
t.entries, err = parseTreeEntries(stdout, t)
|
t.entries, err = parseTreeEntries(stdout, t)
|
||||||
|
if err == nil {
|
||||||
|
t.entriesParsed = true
|
||||||
|
}
|
||||||
|
|
||||||
return t.entries, err
|
return t.entries, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// ListEntriesRecursive returns all entries of current tree recursively including all subtrees
|
// ListEntriesRecursive returns all entries of current tree recursively including all subtrees
|
||||||
func (t *Tree) ListEntriesRecursive() (Entries, error) {
|
func (t *Tree) ListEntriesRecursive() (Entries, error) {
|
||||||
if t.entriesParsed {
|
if t.entriesRecursiveParsed {
|
||||||
return t.entries, nil
|
return t.entriesRecursive, nil
|
||||||
}
|
}
|
||||||
stdout, err := NewCommand("ls-tree", "-t", "-r", t.ID.String()).RunInDirBytes(t.repo.Path)
|
stdout, err := NewCommand("ls-tree", "-t", "-r", t.ID.String()).RunInDirBytes(t.repo.Path)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
t.entries, err = parseTreeEntries(stdout, t)
|
|
||||||
return t.entries, err
|
t.entriesRecursive, err = parseTreeEntries(stdout, t)
|
||||||
|
if err == nil {
|
||||||
|
t.entriesRecursiveParsed = true
|
||||||
|
}
|
||||||
|
|
||||||
|
return t.entriesRecursive, err
|
||||||
}
|
}
|
||||||
|
|||||||
13
vendor/gopkg.in/ldap.v2/atomic_value.go
generated
vendored
13
vendor/gopkg.in/ldap.v2/atomic_value.go
generated
vendored
@@ -1,13 +0,0 @@
|
|||||||
// +build go1.4
|
|
||||||
|
|
||||||
package ldap
|
|
||||||
|
|
||||||
import (
|
|
||||||
"sync/atomic"
|
|
||||||
)
|
|
||||||
|
|
||||||
// For compilers that support it, we just use the underlying sync/atomic.Value
|
|
||||||
// type.
|
|
||||||
type atomicValue struct {
|
|
||||||
atomic.Value
|
|
||||||
}
|
|
||||||
28
vendor/gopkg.in/ldap.v2/atomic_value_go13.go
generated
vendored
28
vendor/gopkg.in/ldap.v2/atomic_value_go13.go
generated
vendored
@@ -1,28 +0,0 @@
|
|||||||
// +build !go1.4
|
|
||||||
|
|
||||||
package ldap
|
|
||||||
|
|
||||||
import (
|
|
||||||
"sync"
|
|
||||||
)
|
|
||||||
|
|
||||||
// This is a helper type that emulates the use of the "sync/atomic.Value"
|
|
||||||
// struct that's available in Go 1.4 and up.
|
|
||||||
type atomicValue struct {
|
|
||||||
value interface{}
|
|
||||||
lock sync.RWMutex
|
|
||||||
}
|
|
||||||
|
|
||||||
func (av *atomicValue) Store(val interface{}) {
|
|
||||||
av.lock.Lock()
|
|
||||||
av.value = val
|
|
||||||
av.lock.Unlock()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (av *atomicValue) Load() interface{} {
|
|
||||||
av.lock.RLock()
|
|
||||||
ret := av.value
|
|
||||||
av.lock.RUnlock()
|
|
||||||
|
|
||||||
return ret
|
|
||||||
}
|
|
||||||
155
vendor/gopkg.in/ldap.v2/error.go
generated
vendored
155
vendor/gopkg.in/ldap.v2/error.go
generated
vendored
@@ -1,155 +0,0 @@
|
|||||||
package ldap
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"gopkg.in/asn1-ber.v1"
|
|
||||||
)
|
|
||||||
|
|
||||||
// LDAP Result Codes
|
|
||||||
const (
|
|
||||||
LDAPResultSuccess = 0
|
|
||||||
LDAPResultOperationsError = 1
|
|
||||||
LDAPResultProtocolError = 2
|
|
||||||
LDAPResultTimeLimitExceeded = 3
|
|
||||||
LDAPResultSizeLimitExceeded = 4
|
|
||||||
LDAPResultCompareFalse = 5
|
|
||||||
LDAPResultCompareTrue = 6
|
|
||||||
LDAPResultAuthMethodNotSupported = 7
|
|
||||||
LDAPResultStrongAuthRequired = 8
|
|
||||||
LDAPResultReferral = 10
|
|
||||||
LDAPResultAdminLimitExceeded = 11
|
|
||||||
LDAPResultUnavailableCriticalExtension = 12
|
|
||||||
LDAPResultConfidentialityRequired = 13
|
|
||||||
LDAPResultSaslBindInProgress = 14
|
|
||||||
LDAPResultNoSuchAttribute = 16
|
|
||||||
LDAPResultUndefinedAttributeType = 17
|
|
||||||
LDAPResultInappropriateMatching = 18
|
|
||||||
LDAPResultConstraintViolation = 19
|
|
||||||
LDAPResultAttributeOrValueExists = 20
|
|
||||||
LDAPResultInvalidAttributeSyntax = 21
|
|
||||||
LDAPResultNoSuchObject = 32
|
|
||||||
LDAPResultAliasProblem = 33
|
|
||||||
LDAPResultInvalidDNSyntax = 34
|
|
||||||
LDAPResultAliasDereferencingProblem = 36
|
|
||||||
LDAPResultInappropriateAuthentication = 48
|
|
||||||
LDAPResultInvalidCredentials = 49
|
|
||||||
LDAPResultInsufficientAccessRights = 50
|
|
||||||
LDAPResultBusy = 51
|
|
||||||
LDAPResultUnavailable = 52
|
|
||||||
LDAPResultUnwillingToPerform = 53
|
|
||||||
LDAPResultLoopDetect = 54
|
|
||||||
LDAPResultNamingViolation = 64
|
|
||||||
LDAPResultObjectClassViolation = 65
|
|
||||||
LDAPResultNotAllowedOnNonLeaf = 66
|
|
||||||
LDAPResultNotAllowedOnRDN = 67
|
|
||||||
LDAPResultEntryAlreadyExists = 68
|
|
||||||
LDAPResultObjectClassModsProhibited = 69
|
|
||||||
LDAPResultAffectsMultipleDSAs = 71
|
|
||||||
LDAPResultOther = 80
|
|
||||||
|
|
||||||
ErrorNetwork = 200
|
|
||||||
ErrorFilterCompile = 201
|
|
||||||
ErrorFilterDecompile = 202
|
|
||||||
ErrorDebugging = 203
|
|
||||||
ErrorUnexpectedMessage = 204
|
|
||||||
ErrorUnexpectedResponse = 205
|
|
||||||
)
|
|
||||||
|
|
||||||
// LDAPResultCodeMap contains string descriptions for LDAP error codes
|
|
||||||
var LDAPResultCodeMap = map[uint8]string{
|
|
||||||
LDAPResultSuccess: "Success",
|
|
||||||
LDAPResultOperationsError: "Operations Error",
|
|
||||||
LDAPResultProtocolError: "Protocol Error",
|
|
||||||
LDAPResultTimeLimitExceeded: "Time Limit Exceeded",
|
|
||||||
LDAPResultSizeLimitExceeded: "Size Limit Exceeded",
|
|
||||||
LDAPResultCompareFalse: "Compare False",
|
|
||||||
LDAPResultCompareTrue: "Compare True",
|
|
||||||
LDAPResultAuthMethodNotSupported: "Auth Method Not Supported",
|
|
||||||
LDAPResultStrongAuthRequired: "Strong Auth Required",
|
|
||||||
LDAPResultReferral: "Referral",
|
|
||||||
LDAPResultAdminLimitExceeded: "Admin Limit Exceeded",
|
|
||||||
LDAPResultUnavailableCriticalExtension: "Unavailable Critical Extension",
|
|
||||||
LDAPResultConfidentialityRequired: "Confidentiality Required",
|
|
||||||
LDAPResultSaslBindInProgress: "Sasl Bind In Progress",
|
|
||||||
LDAPResultNoSuchAttribute: "No Such Attribute",
|
|
||||||
LDAPResultUndefinedAttributeType: "Undefined Attribute Type",
|
|
||||||
LDAPResultInappropriateMatching: "Inappropriate Matching",
|
|
||||||
LDAPResultConstraintViolation: "Constraint Violation",
|
|
||||||
LDAPResultAttributeOrValueExists: "Attribute Or Value Exists",
|
|
||||||
LDAPResultInvalidAttributeSyntax: "Invalid Attribute Syntax",
|
|
||||||
LDAPResultNoSuchObject: "No Such Object",
|
|
||||||
LDAPResultAliasProblem: "Alias Problem",
|
|
||||||
LDAPResultInvalidDNSyntax: "Invalid DN Syntax",
|
|
||||||
LDAPResultAliasDereferencingProblem: "Alias Dereferencing Problem",
|
|
||||||
LDAPResultInappropriateAuthentication: "Inappropriate Authentication",
|
|
||||||
LDAPResultInvalidCredentials: "Invalid Credentials",
|
|
||||||
LDAPResultInsufficientAccessRights: "Insufficient Access Rights",
|
|
||||||
LDAPResultBusy: "Busy",
|
|
||||||
LDAPResultUnavailable: "Unavailable",
|
|
||||||
LDAPResultUnwillingToPerform: "Unwilling To Perform",
|
|
||||||
LDAPResultLoopDetect: "Loop Detect",
|
|
||||||
LDAPResultNamingViolation: "Naming Violation",
|
|
||||||
LDAPResultObjectClassViolation: "Object Class Violation",
|
|
||||||
LDAPResultNotAllowedOnNonLeaf: "Not Allowed On Non Leaf",
|
|
||||||
LDAPResultNotAllowedOnRDN: "Not Allowed On RDN",
|
|
||||||
LDAPResultEntryAlreadyExists: "Entry Already Exists",
|
|
||||||
LDAPResultObjectClassModsProhibited: "Object Class Mods Prohibited",
|
|
||||||
LDAPResultAffectsMultipleDSAs: "Affects Multiple DSAs",
|
|
||||||
LDAPResultOther: "Other",
|
|
||||||
|
|
||||||
ErrorNetwork: "Network Error",
|
|
||||||
ErrorFilterCompile: "Filter Compile Error",
|
|
||||||
ErrorFilterDecompile: "Filter Decompile Error",
|
|
||||||
ErrorDebugging: "Debugging Error",
|
|
||||||
ErrorUnexpectedMessage: "Unexpected Message",
|
|
||||||
ErrorUnexpectedResponse: "Unexpected Response",
|
|
||||||
}
|
|
||||||
|
|
||||||
func getLDAPResultCode(packet *ber.Packet) (code uint8, description string) {
|
|
||||||
if packet == nil {
|
|
||||||
return ErrorUnexpectedResponse, "Empty packet"
|
|
||||||
} else if len(packet.Children) >= 2 {
|
|
||||||
response := packet.Children[1]
|
|
||||||
if response == nil {
|
|
||||||
return ErrorUnexpectedResponse, "Empty response in packet"
|
|
||||||
}
|
|
||||||
if response.ClassType == ber.ClassApplication && response.TagType == ber.TypeConstructed && len(response.Children) >= 3 {
|
|
||||||
// Children[1].Children[2] is the diagnosticMessage which is guaranteed to exist as seen here: https://tools.ietf.org/html/rfc4511#section-4.1.9
|
|
||||||
return uint8(response.Children[0].Value.(int64)), response.Children[2].Value.(string)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return ErrorNetwork, "Invalid packet format"
|
|
||||||
}
|
|
||||||
|
|
||||||
// Error holds LDAP error information
|
|
||||||
type Error struct {
|
|
||||||
// Err is the underlying error
|
|
||||||
Err error
|
|
||||||
// ResultCode is the LDAP error code
|
|
||||||
ResultCode uint8
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e *Error) Error() string {
|
|
||||||
return fmt.Sprintf("LDAP Result Code %d %q: %s", e.ResultCode, LDAPResultCodeMap[e.ResultCode], e.Err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewError creates an LDAP error with the given code and underlying error
|
|
||||||
func NewError(resultCode uint8, err error) error {
|
|
||||||
return &Error{ResultCode: resultCode, Err: err}
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsErrorWithCode returns true if the given error is an LDAP error with the given result code
|
|
||||||
func IsErrorWithCode(err error, desiredResultCode uint8) bool {
|
|
||||||
if err == nil {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
serverError, ok := err.(*Error)
|
|
||||||
if !ok {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
return serverError.ResultCode == desiredResultCode
|
|
||||||
}
|
|
||||||
0
vendor/gopkg.in/ldap.v2/LICENSE → vendor/gopkg.in/ldap.v3/LICENSE
generated
vendored
0
vendor/gopkg.in/ldap.v2/LICENSE → vendor/gopkg.in/ldap.v3/LICENSE
generated
vendored
14
vendor/gopkg.in/ldap.v2/add.go → vendor/gopkg.in/ldap.v3/add.go
generated
vendored
14
vendor/gopkg.in/ldap.v2/add.go → vendor/gopkg.in/ldap.v3/add.go
generated
vendored
@@ -41,6 +41,8 @@ type AddRequest struct {
|
|||||||
DN string
|
DN string
|
||||||
// Attributes list the attributes of the new entry
|
// Attributes list the attributes of the new entry
|
||||||
Attributes []Attribute
|
Attributes []Attribute
|
||||||
|
// Controls hold optional controls to send with the request
|
||||||
|
Controls []Control
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a AddRequest) encode() *ber.Packet {
|
func (a AddRequest) encode() *ber.Packet {
|
||||||
@@ -60,9 +62,10 @@ func (a *AddRequest) Attribute(attrType string, attrVals []string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// NewAddRequest returns an AddRequest for the given DN, with no attributes
|
// NewAddRequest returns an AddRequest for the given DN, with no attributes
|
||||||
func NewAddRequest(dn string) *AddRequest {
|
func NewAddRequest(dn string, controls []Control) *AddRequest {
|
||||||
return &AddRequest{
|
return &AddRequest{
|
||||||
DN: dn,
|
DN: dn,
|
||||||
|
Controls: controls,
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -72,6 +75,9 @@ func (l *Conn) Add(addRequest *AddRequest) error {
|
|||||||
packet := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "LDAP Request")
|
packet := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "LDAP Request")
|
||||||
packet.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagInteger, l.nextMessageID(), "MessageID"))
|
packet.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagInteger, l.nextMessageID(), "MessageID"))
|
||||||
packet.AppendChild(addRequest.encode())
|
packet.AppendChild(addRequest.encode())
|
||||||
|
if len(addRequest.Controls) > 0 {
|
||||||
|
packet.AppendChild(encodeControls(addRequest.Controls))
|
||||||
|
}
|
||||||
|
|
||||||
l.Debug.PrintPacket(packet)
|
l.Debug.PrintPacket(packet)
|
||||||
|
|
||||||
@@ -100,9 +106,9 @@ func (l *Conn) Add(addRequest *AddRequest) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if packet.Children[1].Tag == ApplicationAddResponse {
|
if packet.Children[1].Tag == ApplicationAddResponse {
|
||||||
resultCode, resultDescription := getLDAPResultCode(packet)
|
err := GetLDAPError(packet)
|
||||||
if resultCode != 0 {
|
if err != nil {
|
||||||
return NewError(resultCode, errors.New(resultDescription))
|
return err
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
log.Printf("Unexpected Response: %d", packet.Children[1].Tag)
|
log.Printf("Unexpected Response: %d", packet.Children[1].Tag)
|
||||||
94
vendor/gopkg.in/ldap.v2/bind.go → vendor/gopkg.in/ldap.v3/bind.go
generated
vendored
94
vendor/gopkg.in/ldap.v2/bind.go → vendor/gopkg.in/ldap.v3/bind.go
generated
vendored
@@ -1,11 +1,8 @@
|
|||||||
// Copyright 2011 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package ldap
|
package ldap
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
"gopkg.in/asn1-ber.v1"
|
"gopkg.in/asn1-ber.v1"
|
||||||
)
|
)
|
||||||
@@ -18,6 +15,9 @@ type SimpleBindRequest struct {
|
|||||||
Password string
|
Password string
|
||||||
// Controls are optional controls to send with the bind request
|
// Controls are optional controls to send with the bind request
|
||||||
Controls []Control
|
Controls []Control
|
||||||
|
// AllowEmptyPassword sets whether the client allows binding with an empty password
|
||||||
|
// (normally used for unauthenticated bind).
|
||||||
|
AllowEmptyPassword bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// SimpleBindResult contains the response from the server
|
// SimpleBindResult contains the response from the server
|
||||||
@@ -31,6 +31,7 @@ func NewSimpleBindRequest(username string, password string, controls []Control)
|
|||||||
Username: username,
|
Username: username,
|
||||||
Password: password,
|
Password: password,
|
||||||
Controls: controls,
|
Controls: controls,
|
||||||
|
AllowEmptyPassword: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -40,17 +41,22 @@ func (bindRequest *SimpleBindRequest) encode() *ber.Packet {
|
|||||||
request.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, bindRequest.Username, "User Name"))
|
request.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, bindRequest.Username, "User Name"))
|
||||||
request.AppendChild(ber.NewString(ber.ClassContext, ber.TypePrimitive, 0, bindRequest.Password, "Password"))
|
request.AppendChild(ber.NewString(ber.ClassContext, ber.TypePrimitive, 0, bindRequest.Password, "Password"))
|
||||||
|
|
||||||
request.AppendChild(encodeControls(bindRequest.Controls))
|
|
||||||
|
|
||||||
return request
|
return request
|
||||||
}
|
}
|
||||||
|
|
||||||
// SimpleBind performs the simple bind operation defined in the given request
|
// SimpleBind performs the simple bind operation defined in the given request
|
||||||
func (l *Conn) SimpleBind(simpleBindRequest *SimpleBindRequest) (*SimpleBindResult, error) {
|
func (l *Conn) SimpleBind(simpleBindRequest *SimpleBindRequest) (*SimpleBindResult, error) {
|
||||||
|
if simpleBindRequest.Password == "" && !simpleBindRequest.AllowEmptyPassword {
|
||||||
|
return nil, NewError(ErrorEmptyPassword, errors.New("ldap: empty password not allowed by the client"))
|
||||||
|
}
|
||||||
|
|
||||||
packet := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "LDAP Request")
|
packet := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "LDAP Request")
|
||||||
packet.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagInteger, l.nextMessageID(), "MessageID"))
|
packet.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagInteger, l.nextMessageID(), "MessageID"))
|
||||||
encodedBindRequest := simpleBindRequest.encode()
|
encodedBindRequest := simpleBindRequest.encode()
|
||||||
packet.AppendChild(encodedBindRequest)
|
packet.AppendChild(encodedBindRequest)
|
||||||
|
if len(simpleBindRequest.Controls) > 0 {
|
||||||
|
packet.AppendChild(encodeControls(simpleBindRequest.Controls))
|
||||||
|
}
|
||||||
|
|
||||||
if l.Debug {
|
if l.Debug {
|
||||||
ber.PrintPacket(packet)
|
ber.PrintPacket(packet)
|
||||||
@@ -73,7 +79,7 @@ func (l *Conn) SimpleBind(simpleBindRequest *SimpleBindRequest) (*SimpleBindResu
|
|||||||
}
|
}
|
||||||
|
|
||||||
if l.Debug {
|
if l.Debug {
|
||||||
if err := addLDAPDescriptions(packet); err != nil {
|
if err = addLDAPDescriptions(packet); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
ber.PrintPacket(packet)
|
ber.PrintPacket(packet)
|
||||||
@@ -85,59 +91,45 @@ func (l *Conn) SimpleBind(simpleBindRequest *SimpleBindRequest) (*SimpleBindResu
|
|||||||
|
|
||||||
if len(packet.Children) == 3 {
|
if len(packet.Children) == 3 {
|
||||||
for _, child := range packet.Children[2].Children {
|
for _, child := range packet.Children[2].Children {
|
||||||
result.Controls = append(result.Controls, DecodeControl(child))
|
decodedChild, decodeErr := DecodeControl(child)
|
||||||
|
if decodeErr != nil {
|
||||||
|
return nil, fmt.Errorf("failed to decode child control: %s", decodeErr)
|
||||||
|
}
|
||||||
|
result.Controls = append(result.Controls, decodedChild)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
resultCode, resultDescription := getLDAPResultCode(packet)
|
err = GetLDAPError(packet)
|
||||||
if resultCode != 0 {
|
return result, err
|
||||||
return result, NewError(resultCode, errors.New(resultDescription))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return result, nil
|
// Bind performs a bind with the given username and password.
|
||||||
}
|
//
|
||||||
|
// It does not allow unauthenticated bind (i.e. empty password). Use the UnauthenticatedBind method
|
||||||
// Bind performs a bind with the given username and password
|
// for that.
|
||||||
func (l *Conn) Bind(username, password string) error {
|
func (l *Conn) Bind(username, password string) error {
|
||||||
packet := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "LDAP Request")
|
req := &SimpleBindRequest{
|
||||||
packet.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagInteger, l.nextMessageID(), "MessageID"))
|
Username: username,
|
||||||
bindRequest := ber.Encode(ber.ClassApplication, ber.TypeConstructed, ApplicationBindRequest, nil, "Bind Request")
|
Password: password,
|
||||||
bindRequest.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagInteger, 3, "Version"))
|
AllowEmptyPassword: false,
|
||||||
bindRequest.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, username, "User Name"))
|
|
||||||
bindRequest.AppendChild(ber.NewString(ber.ClassContext, ber.TypePrimitive, 0, password, "Password"))
|
|
||||||
packet.AppendChild(bindRequest)
|
|
||||||
|
|
||||||
if l.Debug {
|
|
||||||
ber.PrintPacket(packet)
|
|
||||||
}
|
}
|
||||||
|
_, err := l.SimpleBind(req)
|
||||||
msgCtx, err := l.sendMessage(packet)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
defer l.finishMessage(msgCtx)
|
|
||||||
|
|
||||||
packetResponse, ok := <-msgCtx.responses
|
|
||||||
if !ok {
|
|
||||||
return NewError(ErrorNetwork, errors.New("ldap: response channel closed"))
|
|
||||||
}
|
|
||||||
packet, err = packetResponse.ReadPacket()
|
|
||||||
l.Debug.Printf("%d: got response %p", msgCtx.id, packet)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if l.Debug {
|
// UnauthenticatedBind performs an unauthenticated bind.
|
||||||
if err := addLDAPDescriptions(packet); err != nil {
|
//
|
||||||
|
// A username may be provided for trace (e.g. logging) purpose only, but it is normally not
|
||||||
|
// authenticated or otherwise validated by the LDAP server.
|
||||||
|
//
|
||||||
|
// See https://tools.ietf.org/html/rfc4513#section-5.1.2 .
|
||||||
|
// See https://tools.ietf.org/html/rfc4513#section-6.3.1 .
|
||||||
|
func (l *Conn) UnauthenticatedBind(username string) error {
|
||||||
|
req := &SimpleBindRequest{
|
||||||
|
Username: username,
|
||||||
|
Password: "",
|
||||||
|
AllowEmptyPassword: true,
|
||||||
|
}
|
||||||
|
_, err := l.SimpleBind(req)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
ber.PrintPacket(packet)
|
|
||||||
}
|
|
||||||
|
|
||||||
resultCode, resultDescription := getLDAPResultCode(packet)
|
|
||||||
if resultCode != 0 {
|
|
||||||
return NewError(resultCode, errors.New(resultDescription))
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
1
vendor/gopkg.in/ldap.v2/client.go → vendor/gopkg.in/ldap.v3/client.go
generated
vendored
1
vendor/gopkg.in/ldap.v2/client.go → vendor/gopkg.in/ldap.v3/client.go
generated
vendored
@@ -18,6 +18,7 @@ type Client interface {
|
|||||||
Add(addRequest *AddRequest) error
|
Add(addRequest *AddRequest) error
|
||||||
Del(delRequest *DelRequest) error
|
Del(delRequest *DelRequest) error
|
||||||
Modify(modifyRequest *ModifyRequest) error
|
Modify(modifyRequest *ModifyRequest) error
|
||||||
|
ModifyDN(modifyDNRequest *ModifyDNRequest) error
|
||||||
|
|
||||||
Compare(dn, attribute, value string) (bool, error)
|
Compare(dn, attribute, value string) (bool, error)
|
||||||
PasswordModify(passwordModifyRequest *PasswordModifyRequest) (*PasswordModifyResult, error)
|
PasswordModify(passwordModifyRequest *PasswordModifyRequest) (*PasswordModifyResult, error)
|
||||||
20
vendor/gopkg.in/ldap.v2/compare.go → vendor/gopkg.in/ldap.v3/compare.go
generated
vendored
20
vendor/gopkg.in/ldap.v2/compare.go → vendor/gopkg.in/ldap.v3/compare.go
generated
vendored
@@ -1,7 +1,3 @@
|
|||||||
// Copyright 2014 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
//
|
|
||||||
// File contains Compare functionality
|
// File contains Compare functionality
|
||||||
//
|
//
|
||||||
// https://tools.ietf.org/html/rfc4511
|
// https://tools.ietf.org/html/rfc4511
|
||||||
@@ -41,7 +37,7 @@ func (l *Conn) Compare(dn, attribute, value string) (bool, error) {
|
|||||||
|
|
||||||
ava := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "AttributeValueAssertion")
|
ava := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "AttributeValueAssertion")
|
||||||
ava.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, attribute, "AttributeDesc"))
|
ava.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, attribute, "AttributeDesc"))
|
||||||
ava.AppendChild(ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagOctetString, value, "AssertionValue"))
|
ava.AppendChild(ber.Encode(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, value, "AssertionValue"))
|
||||||
request.AppendChild(ava)
|
request.AppendChild(ava)
|
||||||
packet.AppendChild(request)
|
packet.AppendChild(request)
|
||||||
|
|
||||||
@@ -72,14 +68,16 @@ func (l *Conn) Compare(dn, attribute, value string) (bool, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if packet.Children[1].Tag == ApplicationCompareResponse {
|
if packet.Children[1].Tag == ApplicationCompareResponse {
|
||||||
resultCode, resultDescription := getLDAPResultCode(packet)
|
err := GetLDAPError(packet)
|
||||||
if resultCode == LDAPResultCompareTrue {
|
|
||||||
|
switch {
|
||||||
|
case IsErrorWithCode(err, LDAPResultCompareTrue):
|
||||||
return true, nil
|
return true, nil
|
||||||
} else if resultCode == LDAPResultCompareFalse {
|
case IsErrorWithCode(err, LDAPResultCompareFalse):
|
||||||
return false, nil
|
return false, nil
|
||||||
} else {
|
default:
|
||||||
return false, NewError(resultCode, errors.New(resultDescription))
|
return false, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false, fmt.Errorf("Unexpected Response: %d", packet.Children[1].Tag)
|
return false, fmt.Errorf("unexpected Response: %d", packet.Children[1].Tag)
|
||||||
}
|
}
|
||||||
98
vendor/gopkg.in/ldap.v2/conn.go → vendor/gopkg.in/ldap.v3/conn.go
generated
vendored
98
vendor/gopkg.in/ldap.v2/conn.go → vendor/gopkg.in/ldap.v3/conn.go
generated
vendored
@@ -1,7 +1,3 @@
|
|||||||
// Copyright 2011 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package ldap
|
package ldap
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@@ -10,6 +6,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"net"
|
"net"
|
||||||
|
"net/url"
|
||||||
"sync"
|
"sync"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
@@ -30,6 +27,13 @@ const (
|
|||||||
MessageTimeout = 4
|
MessageTimeout = 4
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
// DefaultLdapPort default ldap port for pure TCP connection
|
||||||
|
DefaultLdapPort = "389"
|
||||||
|
// DefaultLdapsPort default ldap port for SSL connection
|
||||||
|
DefaultLdapsPort = "636"
|
||||||
|
)
|
||||||
|
|
||||||
// PacketResponse contains the packet or error encountered reading a response
|
// PacketResponse contains the packet or error encountered reading a response
|
||||||
type PacketResponse struct {
|
type PacketResponse struct {
|
||||||
// Packet is the packet read from the server
|
// Packet is the packet read from the server
|
||||||
@@ -81,10 +85,13 @@ const (
|
|||||||
|
|
||||||
// Conn represents an LDAP Connection
|
// Conn represents an LDAP Connection
|
||||||
type Conn struct {
|
type Conn struct {
|
||||||
|
// requestTimeout is loaded atomically
|
||||||
|
// so we need to ensure 64-bit alignment on 32-bit platforms.
|
||||||
|
requestTimeout int64
|
||||||
conn net.Conn
|
conn net.Conn
|
||||||
isTLS bool
|
isTLS bool
|
||||||
closing uint32
|
closing uint32
|
||||||
closeErr atomicValue
|
closeErr atomic.Value
|
||||||
isStartingTLS bool
|
isStartingTLS bool
|
||||||
Debug debugging
|
Debug debugging
|
||||||
chanConfirm chan struct{}
|
chanConfirm chan struct{}
|
||||||
@@ -94,7 +101,6 @@ type Conn struct {
|
|||||||
wgClose sync.WaitGroup
|
wgClose sync.WaitGroup
|
||||||
outstandingRequests uint
|
outstandingRequests uint
|
||||||
messageMutex sync.Mutex
|
messageMutex sync.Mutex
|
||||||
requestTimeout int64
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ Client = &Conn{}
|
var _ Client = &Conn{}
|
||||||
@@ -121,22 +127,51 @@ func Dial(network, addr string) (*Conn, error) {
|
|||||||
// DialTLS connects to the given address on the given network using tls.Dial
|
// DialTLS connects to the given address on the given network using tls.Dial
|
||||||
// and then returns a new Conn for the connection.
|
// and then returns a new Conn for the connection.
|
||||||
func DialTLS(network, addr string, config *tls.Config) (*Conn, error) {
|
func DialTLS(network, addr string, config *tls.Config) (*Conn, error) {
|
||||||
dc, err := net.DialTimeout(network, addr, DefaultTimeout)
|
c, err := tls.DialWithDialer(&net.Dialer{Timeout: DefaultTimeout}, network, addr, config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, NewError(ErrorNetwork, err)
|
return nil, NewError(ErrorNetwork, err)
|
||||||
}
|
}
|
||||||
c := tls.Client(dc, config)
|
|
||||||
err = c.Handshake()
|
|
||||||
if err != nil {
|
|
||||||
// Handshake error, close the established connection before we return an error
|
|
||||||
dc.Close()
|
|
||||||
return nil, NewError(ErrorNetwork, err)
|
|
||||||
}
|
|
||||||
conn := NewConn(c, true)
|
conn := NewConn(c, true)
|
||||||
conn.Start()
|
conn.Start()
|
||||||
return conn, nil
|
return conn, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DialURL connects to the given ldap URL vie TCP using tls.Dial or net.Dial if ldaps://
|
||||||
|
// or ldap:// specified as protocol. On success a new Conn for the connection
|
||||||
|
// is returned.
|
||||||
|
func DialURL(addr string) (*Conn, error) {
|
||||||
|
|
||||||
|
lurl, err := url.Parse(addr)
|
||||||
|
if err != nil {
|
||||||
|
return nil, NewError(ErrorNetwork, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
host, port, err := net.SplitHostPort(lurl.Host)
|
||||||
|
if err != nil {
|
||||||
|
// we asume that error is due to missing port
|
||||||
|
host = lurl.Host
|
||||||
|
port = ""
|
||||||
|
}
|
||||||
|
|
||||||
|
switch lurl.Scheme {
|
||||||
|
case "ldap":
|
||||||
|
if port == "" {
|
||||||
|
port = DefaultLdapPort
|
||||||
|
}
|
||||||
|
return Dial("tcp", net.JoinHostPort(host, port))
|
||||||
|
case "ldaps":
|
||||||
|
if port == "" {
|
||||||
|
port = DefaultLdapsPort
|
||||||
|
}
|
||||||
|
tlsConf := &tls.Config{
|
||||||
|
ServerName: host,
|
||||||
|
}
|
||||||
|
return DialTLS("tcp", net.JoinHostPort(host, port), tlsConf)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, NewError(ErrorNetwork, fmt.Errorf("Unknown scheme '%s'", lurl.Scheme))
|
||||||
|
}
|
||||||
|
|
||||||
// NewConn returns a new Conn using conn for network I/O.
|
// NewConn returns a new Conn using conn for network I/O.
|
||||||
func NewConn(conn net.Conn, isTLS bool) *Conn {
|
func NewConn(conn net.Conn, isTLS bool) *Conn {
|
||||||
return &Conn{
|
return &Conn{
|
||||||
@@ -157,8 +192,8 @@ func (l *Conn) Start() {
|
|||||||
l.wgClose.Add(1)
|
l.wgClose.Add(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
// isClosing returns whether or not we're currently closing.
|
// IsClosing returns whether or not we're currently closing.
|
||||||
func (l *Conn) isClosing() bool {
|
func (l *Conn) IsClosing() bool {
|
||||||
return atomic.LoadUint32(&l.closing) == 1
|
return atomic.LoadUint32(&l.closing) == 1
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -242,30 +277,41 @@ func (l *Conn) StartTLS(config *tls.Config) error {
|
|||||||
ber.PrintPacket(packet)
|
ber.PrintPacket(packet)
|
||||||
}
|
}
|
||||||
|
|
||||||
if resultCode, message := getLDAPResultCode(packet); resultCode == LDAPResultSuccess {
|
if err := GetLDAPError(packet); err == nil {
|
||||||
conn := tls.Client(l.conn, config)
|
conn := tls.Client(l.conn, config)
|
||||||
|
|
||||||
if err := conn.Handshake(); err != nil {
|
if connErr := conn.Handshake(); connErr != nil {
|
||||||
l.Close()
|
l.Close()
|
||||||
return NewError(ErrorNetwork, fmt.Errorf("TLS handshake failed (%v)", err))
|
return NewError(ErrorNetwork, fmt.Errorf("TLS handshake failed (%v)", connErr))
|
||||||
}
|
}
|
||||||
|
|
||||||
l.isTLS = true
|
l.isTLS = true
|
||||||
l.conn = conn
|
l.conn = conn
|
||||||
} else {
|
} else {
|
||||||
return NewError(resultCode, fmt.Errorf("ldap: cannot StartTLS (%s)", message))
|
return err
|
||||||
}
|
}
|
||||||
go l.reader()
|
go l.reader()
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TLSConnectionState returns the client's TLS connection state.
|
||||||
|
// The return values are their zero values if StartTLS did
|
||||||
|
// not succeed.
|
||||||
|
func (l *Conn) TLSConnectionState() (state tls.ConnectionState, ok bool) {
|
||||||
|
tc, ok := l.conn.(*tls.Conn)
|
||||||
|
if !ok {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return tc.ConnectionState(), true
|
||||||
|
}
|
||||||
|
|
||||||
func (l *Conn) sendMessage(packet *ber.Packet) (*messageContext, error) {
|
func (l *Conn) sendMessage(packet *ber.Packet) (*messageContext, error) {
|
||||||
return l.sendMessageWithFlags(packet, 0)
|
return l.sendMessageWithFlags(packet, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *Conn) sendMessageWithFlags(packet *ber.Packet, flags sendMessageFlags) (*messageContext, error) {
|
func (l *Conn) sendMessageWithFlags(packet *ber.Packet, flags sendMessageFlags) (*messageContext, error) {
|
||||||
if l.isClosing() {
|
if l.IsClosing() {
|
||||||
return nil, NewError(ErrorNetwork, errors.New("ldap: connection closed"))
|
return nil, NewError(ErrorNetwork, errors.New("ldap: connection closed"))
|
||||||
}
|
}
|
||||||
l.messageMutex.Lock()
|
l.messageMutex.Lock()
|
||||||
@@ -304,7 +350,7 @@ func (l *Conn) sendMessageWithFlags(packet *ber.Packet, flags sendMessageFlags)
|
|||||||
func (l *Conn) finishMessage(msgCtx *messageContext) {
|
func (l *Conn) finishMessage(msgCtx *messageContext) {
|
||||||
close(msgCtx.done)
|
close(msgCtx.done)
|
||||||
|
|
||||||
if l.isClosing() {
|
if l.IsClosing() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -325,7 +371,7 @@ func (l *Conn) finishMessage(msgCtx *messageContext) {
|
|||||||
func (l *Conn) sendProcessMessage(message *messagePacket) bool {
|
func (l *Conn) sendProcessMessage(message *messagePacket) bool {
|
||||||
l.messageMutex.Lock()
|
l.messageMutex.Lock()
|
||||||
defer l.messageMutex.Unlock()
|
defer l.messageMutex.Unlock()
|
||||||
if l.isClosing() {
|
if l.IsClosing() {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
l.chanMessage <- message
|
l.chanMessage <- message
|
||||||
@@ -340,7 +386,7 @@ func (l *Conn) processMessages() {
|
|||||||
for messageID, msgCtx := range l.messageContexts {
|
for messageID, msgCtx := range l.messageContexts {
|
||||||
// If we are closing due to an error, inform anyone who
|
// If we are closing due to an error, inform anyone who
|
||||||
// is waiting about the error.
|
// is waiting about the error.
|
||||||
if l.isClosing() && l.closeErr.Load() != nil {
|
if l.IsClosing() && l.closeErr.Load() != nil {
|
||||||
msgCtx.sendResponse(&PacketResponse{Error: l.closeErr.Load().(error)})
|
msgCtx.sendResponse(&PacketResponse{Error: l.closeErr.Load().(error)})
|
||||||
}
|
}
|
||||||
l.Debug.Printf("Closing channel for MessageID %d", messageID)
|
l.Debug.Printf("Closing channel for MessageID %d", messageID)
|
||||||
@@ -400,7 +446,7 @@ func (l *Conn) processMessages() {
|
|||||||
if msgCtx, ok := l.messageContexts[message.MessageID]; ok {
|
if msgCtx, ok := l.messageContexts[message.MessageID]; ok {
|
||||||
msgCtx.sendResponse(&PacketResponse{message.Packet, nil})
|
msgCtx.sendResponse(&PacketResponse{message.Packet, nil})
|
||||||
} else {
|
} else {
|
||||||
log.Printf("Received unexpected message %d, %v", message.MessageID, l.isClosing())
|
log.Printf("Received unexpected message %d, %v", message.MessageID, l.IsClosing())
|
||||||
ber.PrintPacket(message.Packet)
|
ber.PrintPacket(message.Packet)
|
||||||
}
|
}
|
||||||
case MessageTimeout:
|
case MessageTimeout:
|
||||||
@@ -442,7 +488,7 @@ func (l *Conn) reader() {
|
|||||||
packet, err := ber.ReadPacket(l.conn)
|
packet, err := ber.ReadPacket(l.conn)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// A read error is expected here if we are closing the connection...
|
// A read error is expected here if we are closing the connection...
|
||||||
if !l.isClosing() {
|
if !l.IsClosing() {
|
||||||
l.closeErr.Store(fmt.Errorf("unable to read LDAP response packet: %s", err))
|
l.closeErr.Store(fmt.Errorf("unable to read LDAP response packet: %s", err))
|
||||||
l.Debug.Printf("reader error: %s", err.Error())
|
l.Debug.Printf("reader error: %s", err.Error())
|
||||||
}
|
}
|
||||||
113
vendor/gopkg.in/ldap.v2/control.go → vendor/gopkg.in/ldap.v3/control.go
generated
vendored
113
vendor/gopkg.in/ldap.v2/control.go → vendor/gopkg.in/ldap.v3/control.go
generated
vendored
@@ -1,7 +1,3 @@
|
|||||||
// Copyright 2011 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package ldap
|
package ldap
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@@ -22,6 +18,11 @@ const (
|
|||||||
ControlTypeVChuPasswordWarning = "2.16.840.1.113730.3.4.5"
|
ControlTypeVChuPasswordWarning = "2.16.840.1.113730.3.4.5"
|
||||||
// ControlTypeManageDsaIT - https://tools.ietf.org/html/rfc3296
|
// ControlTypeManageDsaIT - https://tools.ietf.org/html/rfc3296
|
||||||
ControlTypeManageDsaIT = "2.16.840.1.113730.3.4.2"
|
ControlTypeManageDsaIT = "2.16.840.1.113730.3.4.2"
|
||||||
|
|
||||||
|
// ControlTypeMicrosoftNotification - https://msdn.microsoft.com/en-us/library/aa366983(v=vs.85).aspx
|
||||||
|
ControlTypeMicrosoftNotification = "1.2.840.113556.1.4.528"
|
||||||
|
// ControlTypeMicrosoftShowDeleted - https://msdn.microsoft.com/en-us/library/aa366989(v=vs.85).aspx
|
||||||
|
ControlTypeMicrosoftShowDeleted = "1.2.840.113556.1.4.417"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ControlTypeMap maps controls to text descriptions
|
// ControlTypeMap maps controls to text descriptions
|
||||||
@@ -29,6 +30,8 @@ var ControlTypeMap = map[string]string{
|
|||||||
ControlTypePaging: "Paging",
|
ControlTypePaging: "Paging",
|
||||||
ControlTypeBeheraPasswordPolicy: "Password Policy - Behera Draft",
|
ControlTypeBeheraPasswordPolicy: "Password Policy - Behera Draft",
|
||||||
ControlTypeManageDsaIT: "Manage DSA IT",
|
ControlTypeManageDsaIT: "Manage DSA IT",
|
||||||
|
ControlTypeMicrosoftNotification: "Change Notification - Microsoft",
|
||||||
|
ControlTypeMicrosoftShowDeleted: "Show Deleted Objects - Microsoft",
|
||||||
}
|
}
|
||||||
|
|
||||||
// Control defines an interface controls provide to encode and describe themselves
|
// Control defines an interface controls provide to encode and describe themselves
|
||||||
@@ -242,6 +245,64 @@ func NewControlManageDsaIT(Criticality bool) *ControlManageDsaIT {
|
|||||||
return &ControlManageDsaIT{Criticality: Criticality}
|
return &ControlManageDsaIT{Criticality: Criticality}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ControlMicrosoftNotification implements the control described in https://msdn.microsoft.com/en-us/library/aa366983(v=vs.85).aspx
|
||||||
|
type ControlMicrosoftNotification struct{}
|
||||||
|
|
||||||
|
// GetControlType returns the OID
|
||||||
|
func (c *ControlMicrosoftNotification) GetControlType() string {
|
||||||
|
return ControlTypeMicrosoftNotification
|
||||||
|
}
|
||||||
|
|
||||||
|
// Encode returns the ber packet representation
|
||||||
|
func (c *ControlMicrosoftNotification) Encode() *ber.Packet {
|
||||||
|
packet := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "Control")
|
||||||
|
packet.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, ControlTypeMicrosoftNotification, "Control Type ("+ControlTypeMap[ControlTypeMicrosoftNotification]+")"))
|
||||||
|
|
||||||
|
return packet
|
||||||
|
}
|
||||||
|
|
||||||
|
// String returns a human-readable description
|
||||||
|
func (c *ControlMicrosoftNotification) String() string {
|
||||||
|
return fmt.Sprintf(
|
||||||
|
"Control Type: %s (%q)",
|
||||||
|
ControlTypeMap[ControlTypeMicrosoftNotification],
|
||||||
|
ControlTypeMicrosoftNotification)
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewControlMicrosoftNotification returns a ControlMicrosoftNotification control
|
||||||
|
func NewControlMicrosoftNotification() *ControlMicrosoftNotification {
|
||||||
|
return &ControlMicrosoftNotification{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ControlMicrosoftShowDeleted implements the control described in https://msdn.microsoft.com/en-us/library/aa366989(v=vs.85).aspx
|
||||||
|
type ControlMicrosoftShowDeleted struct{}
|
||||||
|
|
||||||
|
// GetControlType returns the OID
|
||||||
|
func (c *ControlMicrosoftShowDeleted) GetControlType() string {
|
||||||
|
return ControlTypeMicrosoftShowDeleted
|
||||||
|
}
|
||||||
|
|
||||||
|
// Encode returns the ber packet representation
|
||||||
|
func (c *ControlMicrosoftShowDeleted) Encode() *ber.Packet {
|
||||||
|
packet := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "Control")
|
||||||
|
packet.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, ControlTypeMicrosoftShowDeleted, "Control Type ("+ControlTypeMap[ControlTypeMicrosoftShowDeleted]+")"))
|
||||||
|
|
||||||
|
return packet
|
||||||
|
}
|
||||||
|
|
||||||
|
// String returns a human-readable description
|
||||||
|
func (c *ControlMicrosoftShowDeleted) String() string {
|
||||||
|
return fmt.Sprintf(
|
||||||
|
"Control Type: %s (%q)",
|
||||||
|
ControlTypeMap[ControlTypeMicrosoftShowDeleted],
|
||||||
|
ControlTypeMicrosoftShowDeleted)
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewControlMicrosoftShowDeleted returns a ControlMicrosoftShowDeleted control
|
||||||
|
func NewControlMicrosoftShowDeleted() *ControlMicrosoftShowDeleted {
|
||||||
|
return &ControlMicrosoftShowDeleted{}
|
||||||
|
}
|
||||||
|
|
||||||
// FindControl returns the first control of the given type in the list, or nil
|
// FindControl returns the first control of the given type in the list, or nil
|
||||||
func FindControl(controls []Control, controlType string) Control {
|
func FindControl(controls []Control, controlType string) Control {
|
||||||
for _, c := range controls {
|
for _, c := range controls {
|
||||||
@@ -253,7 +314,7 @@ func FindControl(controls []Control, controlType string) Control {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// DecodeControl returns a control read from the given packet, or nil if no recognized control can be made
|
// DecodeControl returns a control read from the given packet, or nil if no recognized control can be made
|
||||||
func DecodeControl(packet *ber.Packet) Control {
|
func DecodeControl(packet *ber.Packet) (Control, error) {
|
||||||
var (
|
var (
|
||||||
ControlType = ""
|
ControlType = ""
|
||||||
Criticality = false
|
Criticality = false
|
||||||
@@ -263,7 +324,7 @@ func DecodeControl(packet *ber.Packet) Control {
|
|||||||
switch len(packet.Children) {
|
switch len(packet.Children) {
|
||||||
case 0:
|
case 0:
|
||||||
// at least one child is required for control type
|
// at least one child is required for control type
|
||||||
return nil
|
return nil, fmt.Errorf("at least one child is required for control type")
|
||||||
|
|
||||||
case 1:
|
case 1:
|
||||||
// just type, no criticality or value
|
// just type, no criticality or value
|
||||||
@@ -296,17 +357,20 @@ func DecodeControl(packet *ber.Packet) Control {
|
|||||||
|
|
||||||
default:
|
default:
|
||||||
// more than 3 children is invalid
|
// more than 3 children is invalid
|
||||||
return nil
|
return nil, fmt.Errorf("more than 3 children is invalid for controls")
|
||||||
}
|
}
|
||||||
|
|
||||||
switch ControlType {
|
switch ControlType {
|
||||||
case ControlTypeManageDsaIT:
|
case ControlTypeManageDsaIT:
|
||||||
return NewControlManageDsaIT(Criticality)
|
return NewControlManageDsaIT(Criticality), nil
|
||||||
case ControlTypePaging:
|
case ControlTypePaging:
|
||||||
value.Description += " (Paging)"
|
value.Description += " (Paging)"
|
||||||
c := new(ControlPaging)
|
c := new(ControlPaging)
|
||||||
if value.Value != nil {
|
if value.Value != nil {
|
||||||
valueChildren := ber.DecodePacket(value.Data.Bytes())
|
valueChildren, err := ber.DecodePacketErr(value.Data.Bytes())
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to decode data bytes: %s", err)
|
||||||
|
}
|
||||||
value.Data.Truncate(0)
|
value.Data.Truncate(0)
|
||||||
value.Value = nil
|
value.Value = nil
|
||||||
value.AppendChild(valueChildren)
|
value.AppendChild(valueChildren)
|
||||||
@@ -318,12 +382,15 @@ func DecodeControl(packet *ber.Packet) Control {
|
|||||||
c.PagingSize = uint32(value.Children[0].Value.(int64))
|
c.PagingSize = uint32(value.Children[0].Value.(int64))
|
||||||
c.Cookie = value.Children[1].Data.Bytes()
|
c.Cookie = value.Children[1].Data.Bytes()
|
||||||
value.Children[1].Value = c.Cookie
|
value.Children[1].Value = c.Cookie
|
||||||
return c
|
return c, nil
|
||||||
case ControlTypeBeheraPasswordPolicy:
|
case ControlTypeBeheraPasswordPolicy:
|
||||||
value.Description += " (Password Policy - Behera)"
|
value.Description += " (Password Policy - Behera)"
|
||||||
c := NewControlBeheraPasswordPolicy()
|
c := NewControlBeheraPasswordPolicy()
|
||||||
if value.Value != nil {
|
if value.Value != nil {
|
||||||
valueChildren := ber.DecodePacket(value.Data.Bytes())
|
valueChildren, err := ber.DecodePacketErr(value.Data.Bytes())
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to decode data bytes: %s", err)
|
||||||
|
}
|
||||||
value.Data.Truncate(0)
|
value.Data.Truncate(0)
|
||||||
value.Value = nil
|
value.Value = nil
|
||||||
value.AppendChild(valueChildren)
|
value.AppendChild(valueChildren)
|
||||||
@@ -335,7 +402,10 @@ func DecodeControl(packet *ber.Packet) Control {
|
|||||||
if child.Tag == 0 {
|
if child.Tag == 0 {
|
||||||
//Warning
|
//Warning
|
||||||
warningPacket := child.Children[0]
|
warningPacket := child.Children[0]
|
||||||
packet := ber.DecodePacket(warningPacket.Data.Bytes())
|
packet, err := ber.DecodePacketErr(warningPacket.Data.Bytes())
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to decode data bytes: %s", err)
|
||||||
|
}
|
||||||
val, ok := packet.Value.(int64)
|
val, ok := packet.Value.(int64)
|
||||||
if ok {
|
if ok {
|
||||||
if warningPacket.Tag == 0 {
|
if warningPacket.Tag == 0 {
|
||||||
@@ -350,7 +420,10 @@ func DecodeControl(packet *ber.Packet) Control {
|
|||||||
}
|
}
|
||||||
} else if child.Tag == 1 {
|
} else if child.Tag == 1 {
|
||||||
// Error
|
// Error
|
||||||
packet := ber.DecodePacket(child.Data.Bytes())
|
packet, err := ber.DecodePacketErr(child.Data.Bytes())
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to decode data bytes: %s", err)
|
||||||
|
}
|
||||||
val, ok := packet.Value.(int8)
|
val, ok := packet.Value.(int8)
|
||||||
if !ok {
|
if !ok {
|
||||||
// what to do?
|
// what to do?
|
||||||
@@ -361,22 +434,26 @@ func DecodeControl(packet *ber.Packet) Control {
|
|||||||
c.ErrorString = BeheraPasswordPolicyErrorMap[c.Error]
|
c.ErrorString = BeheraPasswordPolicyErrorMap[c.Error]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return c
|
return c, nil
|
||||||
case ControlTypeVChuPasswordMustChange:
|
case ControlTypeVChuPasswordMustChange:
|
||||||
c := &ControlVChuPasswordMustChange{MustChange: true}
|
c := &ControlVChuPasswordMustChange{MustChange: true}
|
||||||
return c
|
return c, nil
|
||||||
case ControlTypeVChuPasswordWarning:
|
case ControlTypeVChuPasswordWarning:
|
||||||
c := &ControlVChuPasswordWarning{Expire: -1}
|
c := &ControlVChuPasswordWarning{Expire: -1}
|
||||||
expireStr := ber.DecodeString(value.Data.Bytes())
|
expireStr := ber.DecodeString(value.Data.Bytes())
|
||||||
|
|
||||||
expire, err := strconv.ParseInt(expireStr, 10, 64)
|
expire, err := strconv.ParseInt(expireStr, 10, 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil
|
return nil, fmt.Errorf("failed to parse value as int: %s", err)
|
||||||
}
|
}
|
||||||
c.Expire = expire
|
c.Expire = expire
|
||||||
value.Value = c.Expire
|
value.Value = c.Expire
|
||||||
|
|
||||||
return c
|
return c, nil
|
||||||
|
case ControlTypeMicrosoftNotification:
|
||||||
|
return NewControlMicrosoftNotification(), nil
|
||||||
|
case ControlTypeMicrosoftShowDeleted:
|
||||||
|
return NewControlMicrosoftShowDeleted(), nil
|
||||||
default:
|
default:
|
||||||
c := new(ControlString)
|
c := new(ControlString)
|
||||||
c.ControlType = ControlType
|
c.ControlType = ControlType
|
||||||
@@ -384,7 +461,7 @@ func DecodeControl(packet *ber.Packet) Control {
|
|||||||
if value != nil {
|
if value != nil {
|
||||||
c.ControlValue = value.Value.(string)
|
c.ControlValue = value.Value.(string)
|
||||||
}
|
}
|
||||||
return c
|
return c, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
0
vendor/gopkg.in/ldap.v2/debug.go → vendor/gopkg.in/ldap.v3/debug.go
generated
vendored
0
vendor/gopkg.in/ldap.v2/debug.go → vendor/gopkg.in/ldap.v3/debug.go
generated
vendored
8
vendor/gopkg.in/ldap.v2/del.go → vendor/gopkg.in/ldap.v3/del.go
generated
vendored
8
vendor/gopkg.in/ldap.v2/del.go → vendor/gopkg.in/ldap.v3/del.go
generated
vendored
@@ -40,7 +40,7 @@ func (l *Conn) Del(delRequest *DelRequest) error {
|
|||||||
packet := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "LDAP Request")
|
packet := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "LDAP Request")
|
||||||
packet.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagInteger, l.nextMessageID(), "MessageID"))
|
packet.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagInteger, l.nextMessageID(), "MessageID"))
|
||||||
packet.AppendChild(delRequest.encode())
|
packet.AppendChild(delRequest.encode())
|
||||||
if delRequest.Controls != nil {
|
if len(delRequest.Controls) > 0 {
|
||||||
packet.AppendChild(encodeControls(delRequest.Controls))
|
packet.AppendChild(encodeControls(delRequest.Controls))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -71,9 +71,9 @@ func (l *Conn) Del(delRequest *DelRequest) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if packet.Children[1].Tag == ApplicationDelResponse {
|
if packet.Children[1].Tag == ApplicationDelResponse {
|
||||||
resultCode, resultDescription := getLDAPResultCode(packet)
|
err := GetLDAPError(packet)
|
||||||
if resultCode != 0 {
|
if err != nil {
|
||||||
return NewError(resultCode, errors.New(resultDescription))
|
return err
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
log.Printf("Unexpected Response: %d", packet.Children[1].Tag)
|
log.Printf("Unexpected Response: %d", packet.Children[1].Tag)
|
||||||
30
vendor/gopkg.in/ldap.v2/dn.go → vendor/gopkg.in/ldap.v3/dn.go
generated
vendored
30
vendor/gopkg.in/ldap.v2/dn.go → vendor/gopkg.in/ldap.v3/dn.go
generated
vendored
@@ -1,7 +1,3 @@
|
|||||||
// Copyright 2015 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
//
|
|
||||||
// File contains DN parsing functionality
|
// File contains DN parsing functionality
|
||||||
//
|
//
|
||||||
// https://tools.ietf.org/html/rfc4514
|
// https://tools.ietf.org/html/rfc4514
|
||||||
@@ -94,7 +90,8 @@ func ParseDN(str string) (*DN, error) {
|
|||||||
|
|
||||||
for i := 0; i < len(str); i++ {
|
for i := 0; i < len(str); i++ {
|
||||||
char := str[i]
|
char := str[i]
|
||||||
if escaping {
|
switch {
|
||||||
|
case escaping:
|
||||||
unescapedTrailingSpaces = 0
|
unescapedTrailingSpaces = 0
|
||||||
escaping = false
|
escaping = false
|
||||||
switch char {
|
switch char {
|
||||||
@@ -104,22 +101,22 @@ func ParseDN(str string) (*DN, error) {
|
|||||||
}
|
}
|
||||||
// Not a special character, assume hex encoded octet
|
// Not a special character, assume hex encoded octet
|
||||||
if len(str) == i+1 {
|
if len(str) == i+1 {
|
||||||
return nil, errors.New("Got corrupted escaped character")
|
return nil, errors.New("got corrupted escaped character")
|
||||||
}
|
}
|
||||||
|
|
||||||
dst := []byte{0}
|
dst := []byte{0}
|
||||||
n, err := enchex.Decode([]byte(dst), []byte(str[i:i+2]))
|
n, err := enchex.Decode([]byte(dst), []byte(str[i:i+2]))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("Failed to decode escaped character: %s", err)
|
return nil, fmt.Errorf("failed to decode escaped character: %s", err)
|
||||||
} else if n != 1 {
|
} else if n != 1 {
|
||||||
return nil, fmt.Errorf("Expected 1 byte when un-escaping, got %d", n)
|
return nil, fmt.Errorf("expected 1 byte when un-escaping, got %d", n)
|
||||||
}
|
}
|
||||||
buffer.WriteByte(dst[0])
|
buffer.WriteByte(dst[0])
|
||||||
i++
|
i++
|
||||||
} else if char == '\\' {
|
case char == '\\':
|
||||||
unescapedTrailingSpaces = 0
|
unescapedTrailingSpaces = 0
|
||||||
escaping = true
|
escaping = true
|
||||||
} else if char == '=' {
|
case char == '=':
|
||||||
attribute.Type = stringFromBuffer()
|
attribute.Type = stringFromBuffer()
|
||||||
// Special case: If the first character in the value is # the
|
// Special case: If the first character in the value is # the
|
||||||
// following data is BER encoded so we can just fast forward
|
// following data is BER encoded so we can just fast forward
|
||||||
@@ -135,13 +132,16 @@ func ParseDN(str string) (*DN, error) {
|
|||||||
}
|
}
|
||||||
rawBER, err := enchex.DecodeString(data)
|
rawBER, err := enchex.DecodeString(data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("Failed to decode BER encoding: %s", err)
|
return nil, fmt.Errorf("failed to decode BER encoding: %s", err)
|
||||||
|
}
|
||||||
|
packet, err := ber.DecodePacketErr(rawBER)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to decode BER packet: %s", err)
|
||||||
}
|
}
|
||||||
packet := ber.DecodePacket(rawBER)
|
|
||||||
buffer.WriteString(packet.Data.String())
|
buffer.WriteString(packet.Data.String())
|
||||||
i += len(data) - 1
|
i += len(data) - 1
|
||||||
}
|
}
|
||||||
} else if char == ',' || char == '+' {
|
case char == ',' || char == '+':
|
||||||
// We're done with this RDN or value, push it
|
// We're done with this RDN or value, push it
|
||||||
if len(attribute.Type) == 0 {
|
if len(attribute.Type) == 0 {
|
||||||
return nil, errors.New("incomplete type, value pair")
|
return nil, errors.New("incomplete type, value pair")
|
||||||
@@ -154,10 +154,10 @@ func ParseDN(str string) (*DN, error) {
|
|||||||
rdn = new(RelativeDN)
|
rdn = new(RelativeDN)
|
||||||
rdn.Attributes = make([]*AttributeTypeAndValue, 0)
|
rdn.Attributes = make([]*AttributeTypeAndValue, 0)
|
||||||
}
|
}
|
||||||
} else if char == ' ' && buffer.Len() == 0 {
|
case char == ' ' && buffer.Len() == 0:
|
||||||
// ignore unescaped leading spaces
|
// ignore unescaped leading spaces
|
||||||
continue
|
continue
|
||||||
} else {
|
default:
|
||||||
if char == ' ' {
|
if char == ' ' {
|
||||||
// Track unescaped spaces in case they are trailing and we need to remove them
|
// Track unescaped spaces in case they are trailing and we need to remove them
|
||||||
unescapedTrailingSpaces++
|
unescapedTrailingSpaces++
|
||||||
0
vendor/gopkg.in/ldap.v2/doc.go → vendor/gopkg.in/ldap.v3/doc.go
generated
vendored
0
vendor/gopkg.in/ldap.v2/doc.go → vendor/gopkg.in/ldap.v3/doc.go
generated
vendored
234
vendor/gopkg.in/ldap.v3/error.go
generated
vendored
Normal file
234
vendor/gopkg.in/ldap.v3/error.go
generated
vendored
Normal file
@@ -0,0 +1,234 @@
|
|||||||
|
package ldap
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"gopkg.in/asn1-ber.v1"
|
||||||
|
)
|
||||||
|
|
||||||
|
// LDAP Result Codes
|
||||||
|
const (
|
||||||
|
LDAPResultSuccess = 0
|
||||||
|
LDAPResultOperationsError = 1
|
||||||
|
LDAPResultProtocolError = 2
|
||||||
|
LDAPResultTimeLimitExceeded = 3
|
||||||
|
LDAPResultSizeLimitExceeded = 4
|
||||||
|
LDAPResultCompareFalse = 5
|
||||||
|
LDAPResultCompareTrue = 6
|
||||||
|
LDAPResultAuthMethodNotSupported = 7
|
||||||
|
LDAPResultStrongAuthRequired = 8
|
||||||
|
LDAPResultReferral = 10
|
||||||
|
LDAPResultAdminLimitExceeded = 11
|
||||||
|
LDAPResultUnavailableCriticalExtension = 12
|
||||||
|
LDAPResultConfidentialityRequired = 13
|
||||||
|
LDAPResultSaslBindInProgress = 14
|
||||||
|
LDAPResultNoSuchAttribute = 16
|
||||||
|
LDAPResultUndefinedAttributeType = 17
|
||||||
|
LDAPResultInappropriateMatching = 18
|
||||||
|
LDAPResultConstraintViolation = 19
|
||||||
|
LDAPResultAttributeOrValueExists = 20
|
||||||
|
LDAPResultInvalidAttributeSyntax = 21
|
||||||
|
LDAPResultNoSuchObject = 32
|
||||||
|
LDAPResultAliasProblem = 33
|
||||||
|
LDAPResultInvalidDNSyntax = 34
|
||||||
|
LDAPResultIsLeaf = 35
|
||||||
|
LDAPResultAliasDereferencingProblem = 36
|
||||||
|
LDAPResultInappropriateAuthentication = 48
|
||||||
|
LDAPResultInvalidCredentials = 49
|
||||||
|
LDAPResultInsufficientAccessRights = 50
|
||||||
|
LDAPResultBusy = 51
|
||||||
|
LDAPResultUnavailable = 52
|
||||||
|
LDAPResultUnwillingToPerform = 53
|
||||||
|
LDAPResultLoopDetect = 54
|
||||||
|
LDAPResultSortControlMissing = 60
|
||||||
|
LDAPResultOffsetRangeError = 61
|
||||||
|
LDAPResultNamingViolation = 64
|
||||||
|
LDAPResultObjectClassViolation = 65
|
||||||
|
LDAPResultNotAllowedOnNonLeaf = 66
|
||||||
|
LDAPResultNotAllowedOnRDN = 67
|
||||||
|
LDAPResultEntryAlreadyExists = 68
|
||||||
|
LDAPResultObjectClassModsProhibited = 69
|
||||||
|
LDAPResultResultsTooLarge = 70
|
||||||
|
LDAPResultAffectsMultipleDSAs = 71
|
||||||
|
LDAPResultVirtualListViewErrorOrControlError = 76
|
||||||
|
LDAPResultOther = 80
|
||||||
|
LDAPResultServerDown = 81
|
||||||
|
LDAPResultLocalError = 82
|
||||||
|
LDAPResultEncodingError = 83
|
||||||
|
LDAPResultDecodingError = 84
|
||||||
|
LDAPResultTimeout = 85
|
||||||
|
LDAPResultAuthUnknown = 86
|
||||||
|
LDAPResultFilterError = 87
|
||||||
|
LDAPResultUserCanceled = 88
|
||||||
|
LDAPResultParamError = 89
|
||||||
|
LDAPResultNoMemory = 90
|
||||||
|
LDAPResultConnectError = 91
|
||||||
|
LDAPResultNotSupported = 92
|
||||||
|
LDAPResultControlNotFound = 93
|
||||||
|
LDAPResultNoResultsReturned = 94
|
||||||
|
LDAPResultMoreResultsToReturn = 95
|
||||||
|
LDAPResultClientLoop = 96
|
||||||
|
LDAPResultReferralLimitExceeded = 97
|
||||||
|
LDAPResultInvalidResponse = 100
|
||||||
|
LDAPResultAmbiguousResponse = 101
|
||||||
|
LDAPResultTLSNotSupported = 112
|
||||||
|
LDAPResultIntermediateResponse = 113
|
||||||
|
LDAPResultUnknownType = 114
|
||||||
|
LDAPResultCanceled = 118
|
||||||
|
LDAPResultNoSuchOperation = 119
|
||||||
|
LDAPResultTooLate = 120
|
||||||
|
LDAPResultCannotCancel = 121
|
||||||
|
LDAPResultAssertionFailed = 122
|
||||||
|
LDAPResultAuthorizationDenied = 123
|
||||||
|
LDAPResultSyncRefreshRequired = 4096
|
||||||
|
|
||||||
|
ErrorNetwork = 200
|
||||||
|
ErrorFilterCompile = 201
|
||||||
|
ErrorFilterDecompile = 202
|
||||||
|
ErrorDebugging = 203
|
||||||
|
ErrorUnexpectedMessage = 204
|
||||||
|
ErrorUnexpectedResponse = 205
|
||||||
|
ErrorEmptyPassword = 206
|
||||||
|
)
|
||||||
|
|
||||||
|
// LDAPResultCodeMap contains string descriptions for LDAP error codes
|
||||||
|
var LDAPResultCodeMap = map[uint16]string{
|
||||||
|
LDAPResultSuccess: "Success",
|
||||||
|
LDAPResultOperationsError: "Operations Error",
|
||||||
|
LDAPResultProtocolError: "Protocol Error",
|
||||||
|
LDAPResultTimeLimitExceeded: "Time Limit Exceeded",
|
||||||
|
LDAPResultSizeLimitExceeded: "Size Limit Exceeded",
|
||||||
|
LDAPResultCompareFalse: "Compare False",
|
||||||
|
LDAPResultCompareTrue: "Compare True",
|
||||||
|
LDAPResultAuthMethodNotSupported: "Auth Method Not Supported",
|
||||||
|
LDAPResultStrongAuthRequired: "Strong Auth Required",
|
||||||
|
LDAPResultReferral: "Referral",
|
||||||
|
LDAPResultAdminLimitExceeded: "Admin Limit Exceeded",
|
||||||
|
LDAPResultUnavailableCriticalExtension: "Unavailable Critical Extension",
|
||||||
|
LDAPResultConfidentialityRequired: "Confidentiality Required",
|
||||||
|
LDAPResultSaslBindInProgress: "Sasl Bind In Progress",
|
||||||
|
LDAPResultNoSuchAttribute: "No Such Attribute",
|
||||||
|
LDAPResultUndefinedAttributeType: "Undefined Attribute Type",
|
||||||
|
LDAPResultInappropriateMatching: "Inappropriate Matching",
|
||||||
|
LDAPResultConstraintViolation: "Constraint Violation",
|
||||||
|
LDAPResultAttributeOrValueExists: "Attribute Or Value Exists",
|
||||||
|
LDAPResultInvalidAttributeSyntax: "Invalid Attribute Syntax",
|
||||||
|
LDAPResultNoSuchObject: "No Such Object",
|
||||||
|
LDAPResultAliasProblem: "Alias Problem",
|
||||||
|
LDAPResultInvalidDNSyntax: "Invalid DN Syntax",
|
||||||
|
LDAPResultIsLeaf: "Is Leaf",
|
||||||
|
LDAPResultAliasDereferencingProblem: "Alias Dereferencing Problem",
|
||||||
|
LDAPResultInappropriateAuthentication: "Inappropriate Authentication",
|
||||||
|
LDAPResultInvalidCredentials: "Invalid Credentials",
|
||||||
|
LDAPResultInsufficientAccessRights: "Insufficient Access Rights",
|
||||||
|
LDAPResultBusy: "Busy",
|
||||||
|
LDAPResultUnavailable: "Unavailable",
|
||||||
|
LDAPResultUnwillingToPerform: "Unwilling To Perform",
|
||||||
|
LDAPResultLoopDetect: "Loop Detect",
|
||||||
|
LDAPResultSortControlMissing: "Sort Control Missing",
|
||||||
|
LDAPResultOffsetRangeError: "Result Offset Range Error",
|
||||||
|
LDAPResultNamingViolation: "Naming Violation",
|
||||||
|
LDAPResultObjectClassViolation: "Object Class Violation",
|
||||||
|
LDAPResultResultsTooLarge: "Results Too Large",
|
||||||
|
LDAPResultNotAllowedOnNonLeaf: "Not Allowed On Non Leaf",
|
||||||
|
LDAPResultNotAllowedOnRDN: "Not Allowed On RDN",
|
||||||
|
LDAPResultEntryAlreadyExists: "Entry Already Exists",
|
||||||
|
LDAPResultObjectClassModsProhibited: "Object Class Mods Prohibited",
|
||||||
|
LDAPResultAffectsMultipleDSAs: "Affects Multiple DSAs",
|
||||||
|
LDAPResultVirtualListViewErrorOrControlError: "Failed because of a problem related to the virtual list view",
|
||||||
|
LDAPResultOther: "Other",
|
||||||
|
LDAPResultServerDown: "Cannot establish a connection",
|
||||||
|
LDAPResultLocalError: "An error occurred",
|
||||||
|
LDAPResultEncodingError: "LDAP encountered an error while encoding",
|
||||||
|
LDAPResultDecodingError: "LDAP encountered an error while decoding",
|
||||||
|
LDAPResultTimeout: "LDAP timeout while waiting for a response from the server",
|
||||||
|
LDAPResultAuthUnknown: "The auth method requested in a bind request is unknown",
|
||||||
|
LDAPResultFilterError: "An error occurred while encoding the given search filter",
|
||||||
|
LDAPResultUserCanceled: "The user canceled the operation",
|
||||||
|
LDAPResultParamError: "An invalid parameter was specified",
|
||||||
|
LDAPResultNoMemory: "Out of memory error",
|
||||||
|
LDAPResultConnectError: "A connection to the server could not be established",
|
||||||
|
LDAPResultNotSupported: "An attempt has been made to use a feature not supported LDAP",
|
||||||
|
LDAPResultControlNotFound: "The controls required to perform the requested operation were not found",
|
||||||
|
LDAPResultNoResultsReturned: "No results were returned from the server",
|
||||||
|
LDAPResultMoreResultsToReturn: "There are more results in the chain of results",
|
||||||
|
LDAPResultClientLoop: "A loop has been detected. For example when following referrals",
|
||||||
|
LDAPResultReferralLimitExceeded: "The referral hop limit has been exceeded",
|
||||||
|
LDAPResultCanceled: "Operation was canceled",
|
||||||
|
LDAPResultNoSuchOperation: "Server has no knowledge of the operation requested for cancellation",
|
||||||
|
LDAPResultTooLate: "Too late to cancel the outstanding operation",
|
||||||
|
LDAPResultCannotCancel: "The identified operation does not support cancellation or the cancel operation cannot be performed",
|
||||||
|
LDAPResultAssertionFailed: "An assertion control given in the LDAP operation evaluated to false causing the operation to not be performed",
|
||||||
|
LDAPResultSyncRefreshRequired: "Refresh Required",
|
||||||
|
LDAPResultInvalidResponse: "Invalid Response",
|
||||||
|
LDAPResultAmbiguousResponse: "Ambiguous Response",
|
||||||
|
LDAPResultTLSNotSupported: "Tls Not Supported",
|
||||||
|
LDAPResultIntermediateResponse: "Intermediate Response",
|
||||||
|
LDAPResultUnknownType: "Unknown Type",
|
||||||
|
LDAPResultAuthorizationDenied: "Authorization Denied",
|
||||||
|
|
||||||
|
ErrorNetwork: "Network Error",
|
||||||
|
ErrorFilterCompile: "Filter Compile Error",
|
||||||
|
ErrorFilterDecompile: "Filter Decompile Error",
|
||||||
|
ErrorDebugging: "Debugging Error",
|
||||||
|
ErrorUnexpectedMessage: "Unexpected Message",
|
||||||
|
ErrorUnexpectedResponse: "Unexpected Response",
|
||||||
|
ErrorEmptyPassword: "Empty password not allowed by the client",
|
||||||
|
}
|
||||||
|
|
||||||
|
// Error holds LDAP error information
|
||||||
|
type Error struct {
|
||||||
|
// Err is the underlying error
|
||||||
|
Err error
|
||||||
|
// ResultCode is the LDAP error code
|
||||||
|
ResultCode uint16
|
||||||
|
// MatchedDN is the matchedDN returned if any
|
||||||
|
MatchedDN string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *Error) Error() string {
|
||||||
|
return fmt.Sprintf("LDAP Result Code %d %q: %s", e.ResultCode, LDAPResultCodeMap[e.ResultCode], e.Err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetLDAPError creates an Error out of a BER packet representing a LDAPResult
|
||||||
|
// The return is an error object. It can be casted to a Error structure.
|
||||||
|
// This function returns nil if resultCode in the LDAPResult sequence is success(0).
|
||||||
|
func GetLDAPError(packet *ber.Packet) error {
|
||||||
|
if packet == nil {
|
||||||
|
return &Error{ResultCode: ErrorUnexpectedResponse, Err: fmt.Errorf("Empty packet")}
|
||||||
|
} else if len(packet.Children) >= 2 {
|
||||||
|
response := packet.Children[1]
|
||||||
|
if response == nil {
|
||||||
|
return &Error{ResultCode: ErrorUnexpectedResponse, Err: fmt.Errorf("Empty response in packet")}
|
||||||
|
}
|
||||||
|
if response.ClassType == ber.ClassApplication && response.TagType == ber.TypeConstructed && len(response.Children) >= 3 {
|
||||||
|
resultCode := uint16(response.Children[0].Value.(int64))
|
||||||
|
if resultCode == 0 { // No error
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return &Error{ResultCode: resultCode, MatchedDN: response.Children[1].Value.(string),
|
||||||
|
Err: fmt.Errorf(response.Children[2].Value.(string))}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return &Error{ResultCode: ErrorNetwork, Err: fmt.Errorf("Invalid packet format")}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewError creates an LDAP error with the given code and underlying error
|
||||||
|
func NewError(resultCode uint16, err error) error {
|
||||||
|
return &Error{ResultCode: resultCode, Err: err}
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsErrorWithCode returns true if the given error is an LDAP error with the given result code
|
||||||
|
func IsErrorWithCode(err error, desiredResultCode uint16) bool {
|
||||||
|
if err == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
serverError, ok := err.(*Error)
|
||||||
|
if !ok {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return serverError.ResultCode == desiredResultCode
|
||||||
|
}
|
||||||
4
vendor/gopkg.in/ldap.v2/filter.go → vendor/gopkg.in/ldap.v3/filter.go
generated
vendored
4
vendor/gopkg.in/ldap.v2/filter.go → vendor/gopkg.in/ldap.v3/filter.go
generated
vendored
@@ -1,7 +1,3 @@
|
|||||||
// Copyright 2011 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package ldap
|
package ldap
|
||||||
|
|
||||||
import (
|
import (
|
||||||
86
vendor/gopkg.in/ldap.v2/ldap.go → vendor/gopkg.in/ldap.v3/ldap.go
generated
vendored
86
vendor/gopkg.in/ldap.v2/ldap.go → vendor/gopkg.in/ldap.v3/ldap.go
generated
vendored
@@ -1,11 +1,8 @@
|
|||||||
// Copyright 2011 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package ldap
|
package ldap
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
@@ -101,13 +98,13 @@ func addLDAPDescriptions(packet *ber.Packet) (err error) {
|
|||||||
|
|
||||||
switch application {
|
switch application {
|
||||||
case ApplicationBindRequest:
|
case ApplicationBindRequest:
|
||||||
addRequestDescriptions(packet)
|
err = addRequestDescriptions(packet)
|
||||||
case ApplicationBindResponse:
|
case ApplicationBindResponse:
|
||||||
addDefaultLDAPResponseDescriptions(packet)
|
err = addDefaultLDAPResponseDescriptions(packet)
|
||||||
case ApplicationUnbindRequest:
|
case ApplicationUnbindRequest:
|
||||||
addRequestDescriptions(packet)
|
err = addRequestDescriptions(packet)
|
||||||
case ApplicationSearchRequest:
|
case ApplicationSearchRequest:
|
||||||
addRequestDescriptions(packet)
|
err = addRequestDescriptions(packet)
|
||||||
case ApplicationSearchResultEntry:
|
case ApplicationSearchResultEntry:
|
||||||
packet.Children[1].Children[0].Description = "Object Name"
|
packet.Children[1].Children[0].Description = "Object Name"
|
||||||
packet.Children[1].Children[1].Description = "Attributes"
|
packet.Children[1].Children[1].Description = "Attributes"
|
||||||
@@ -120,37 +117,37 @@ func addLDAPDescriptions(packet *ber.Packet) (err error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if len(packet.Children) == 3 {
|
if len(packet.Children) == 3 {
|
||||||
addControlDescriptions(packet.Children[2])
|
err = addControlDescriptions(packet.Children[2])
|
||||||
}
|
}
|
||||||
case ApplicationSearchResultDone:
|
case ApplicationSearchResultDone:
|
||||||
addDefaultLDAPResponseDescriptions(packet)
|
err = addDefaultLDAPResponseDescriptions(packet)
|
||||||
case ApplicationModifyRequest:
|
case ApplicationModifyRequest:
|
||||||
addRequestDescriptions(packet)
|
err = addRequestDescriptions(packet)
|
||||||
case ApplicationModifyResponse:
|
case ApplicationModifyResponse:
|
||||||
case ApplicationAddRequest:
|
case ApplicationAddRequest:
|
||||||
addRequestDescriptions(packet)
|
err = addRequestDescriptions(packet)
|
||||||
case ApplicationAddResponse:
|
case ApplicationAddResponse:
|
||||||
case ApplicationDelRequest:
|
case ApplicationDelRequest:
|
||||||
addRequestDescriptions(packet)
|
err = addRequestDescriptions(packet)
|
||||||
case ApplicationDelResponse:
|
case ApplicationDelResponse:
|
||||||
case ApplicationModifyDNRequest:
|
case ApplicationModifyDNRequest:
|
||||||
addRequestDescriptions(packet)
|
err = addRequestDescriptions(packet)
|
||||||
case ApplicationModifyDNResponse:
|
case ApplicationModifyDNResponse:
|
||||||
case ApplicationCompareRequest:
|
case ApplicationCompareRequest:
|
||||||
addRequestDescriptions(packet)
|
err = addRequestDescriptions(packet)
|
||||||
case ApplicationCompareResponse:
|
case ApplicationCompareResponse:
|
||||||
case ApplicationAbandonRequest:
|
case ApplicationAbandonRequest:
|
||||||
addRequestDescriptions(packet)
|
err = addRequestDescriptions(packet)
|
||||||
case ApplicationSearchResultReference:
|
case ApplicationSearchResultReference:
|
||||||
case ApplicationExtendedRequest:
|
case ApplicationExtendedRequest:
|
||||||
addRequestDescriptions(packet)
|
err = addRequestDescriptions(packet)
|
||||||
case ApplicationExtendedResponse:
|
case ApplicationExtendedResponse:
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func addControlDescriptions(packet *ber.Packet) {
|
func addControlDescriptions(packet *ber.Packet) error {
|
||||||
packet.Description = "Controls"
|
packet.Description = "Controls"
|
||||||
for _, child := range packet.Children {
|
for _, child := range packet.Children {
|
||||||
var value *ber.Packet
|
var value *ber.Packet
|
||||||
@@ -159,7 +156,7 @@ func addControlDescriptions(packet *ber.Packet) {
|
|||||||
switch len(child.Children) {
|
switch len(child.Children) {
|
||||||
case 0:
|
case 0:
|
||||||
// at least one child is required for control type
|
// at least one child is required for control type
|
||||||
continue
|
return fmt.Errorf("at least one child is required for control type")
|
||||||
|
|
||||||
case 1:
|
case 1:
|
||||||
// just type, no criticality or value
|
// just type, no criticality or value
|
||||||
@@ -188,8 +185,9 @@ func addControlDescriptions(packet *ber.Packet) {
|
|||||||
|
|
||||||
default:
|
default:
|
||||||
// more than 3 children is invalid
|
// more than 3 children is invalid
|
||||||
continue
|
return fmt.Errorf("more than 3 children for control packet found")
|
||||||
}
|
}
|
||||||
|
|
||||||
if value == nil {
|
if value == nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@@ -197,7 +195,10 @@ func addControlDescriptions(packet *ber.Packet) {
|
|||||||
case ControlTypePaging:
|
case ControlTypePaging:
|
||||||
value.Description += " (Paging)"
|
value.Description += " (Paging)"
|
||||||
if value.Value != nil {
|
if value.Value != nil {
|
||||||
valueChildren := ber.DecodePacket(value.Data.Bytes())
|
valueChildren, err := ber.DecodePacketErr(value.Data.Bytes())
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to decode data bytes: %s", err)
|
||||||
|
}
|
||||||
value.Data.Truncate(0)
|
value.Data.Truncate(0)
|
||||||
value.Value = nil
|
value.Value = nil
|
||||||
valueChildren.Children[1].Value = valueChildren.Children[1].Data.Bytes()
|
valueChildren.Children[1].Value = valueChildren.Children[1].Data.Bytes()
|
||||||
@@ -210,7 +211,10 @@ func addControlDescriptions(packet *ber.Packet) {
|
|||||||
case ControlTypeBeheraPasswordPolicy:
|
case ControlTypeBeheraPasswordPolicy:
|
||||||
value.Description += " (Password Policy - Behera Draft)"
|
value.Description += " (Password Policy - Behera Draft)"
|
||||||
if value.Value != nil {
|
if value.Value != nil {
|
||||||
valueChildren := ber.DecodePacket(value.Data.Bytes())
|
valueChildren, err := ber.DecodePacketErr(value.Data.Bytes())
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to decode data bytes: %s", err)
|
||||||
|
}
|
||||||
value.Data.Truncate(0)
|
value.Data.Truncate(0)
|
||||||
value.Value = nil
|
value.Value = nil
|
||||||
value.AppendChild(valueChildren)
|
value.AppendChild(valueChildren)
|
||||||
@@ -220,7 +224,10 @@ func addControlDescriptions(packet *ber.Packet) {
|
|||||||
if child.Tag == 0 {
|
if child.Tag == 0 {
|
||||||
//Warning
|
//Warning
|
||||||
warningPacket := child.Children[0]
|
warningPacket := child.Children[0]
|
||||||
packet := ber.DecodePacket(warningPacket.Data.Bytes())
|
packet, err := ber.DecodePacketErr(warningPacket.Data.Bytes())
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to decode data bytes: %s", err)
|
||||||
|
}
|
||||||
val, ok := packet.Value.(int64)
|
val, ok := packet.Value.(int64)
|
||||||
if ok {
|
if ok {
|
||||||
if warningPacket.Tag == 0 {
|
if warningPacket.Tag == 0 {
|
||||||
@@ -235,7 +242,10 @@ func addControlDescriptions(packet *ber.Packet) {
|
|||||||
}
|
}
|
||||||
} else if child.Tag == 1 {
|
} else if child.Tag == 1 {
|
||||||
// Error
|
// Error
|
||||||
packet := ber.DecodePacket(child.Data.Bytes())
|
packet, err := ber.DecodePacketErr(child.Data.Bytes())
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to decode data bytes: %s", err)
|
||||||
|
}
|
||||||
val, ok := packet.Value.(int8)
|
val, ok := packet.Value.(int8)
|
||||||
if !ok {
|
if !ok {
|
||||||
val = -1
|
val = -1
|
||||||
@@ -246,28 +256,31 @@ func addControlDescriptions(packet *ber.Packet) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func addRequestDescriptions(packet *ber.Packet) {
|
func addRequestDescriptions(packet *ber.Packet) error {
|
||||||
packet.Description = "LDAP Request"
|
packet.Description = "LDAP Request"
|
||||||
packet.Children[0].Description = "Message ID"
|
packet.Children[0].Description = "Message ID"
|
||||||
packet.Children[1].Description = ApplicationMap[uint8(packet.Children[1].Tag)]
|
packet.Children[1].Description = ApplicationMap[uint8(packet.Children[1].Tag)]
|
||||||
if len(packet.Children) == 3 {
|
if len(packet.Children) == 3 {
|
||||||
addControlDescriptions(packet.Children[2])
|
return addControlDescriptions(packet.Children[2])
|
||||||
}
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func addDefaultLDAPResponseDescriptions(packet *ber.Packet) {
|
func addDefaultLDAPResponseDescriptions(packet *ber.Packet) error {
|
||||||
resultCode, _ := getLDAPResultCode(packet)
|
err := GetLDAPError(packet)
|
||||||
packet.Children[1].Children[0].Description = "Result Code (" + LDAPResultCodeMap[resultCode] + ")"
|
packet.Children[1].Children[0].Description = "Result Code (" + LDAPResultCodeMap[err.(*Error).ResultCode] + ")"
|
||||||
packet.Children[1].Children[1].Description = "Matched DN"
|
packet.Children[1].Children[1].Description = "Matched DN (" + err.(*Error).MatchedDN + ")"
|
||||||
packet.Children[1].Children[2].Description = "Error Message"
|
packet.Children[1].Children[2].Description = "Error Message"
|
||||||
if len(packet.Children[1].Children) > 3 {
|
if len(packet.Children[1].Children) > 3 {
|
||||||
packet.Children[1].Children[3].Description = "Referral"
|
packet.Children[1].Children[3].Description = "Referral"
|
||||||
}
|
}
|
||||||
if len(packet.Children) == 3 {
|
if len(packet.Children) == 3 {
|
||||||
addControlDescriptions(packet.Children[2])
|
return addControlDescriptions(packet.Children[2])
|
||||||
}
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// DebugBinaryFile reads and prints packets from the given filename
|
// DebugBinaryFile reads and prints packets from the given filename
|
||||||
@@ -277,8 +290,13 @@ func DebugBinaryFile(fileName string) error {
|
|||||||
return NewError(ErrorDebugging, err)
|
return NewError(ErrorDebugging, err)
|
||||||
}
|
}
|
||||||
ber.PrintBytes(os.Stdout, file, "")
|
ber.PrintBytes(os.Stdout, file, "")
|
||||||
packet := ber.DecodePacket(file)
|
packet, err := ber.DecodePacketErr(file)
|
||||||
addLDAPDescriptions(packet)
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to decode packet: %s", err)
|
||||||
|
}
|
||||||
|
if err := addLDAPDescriptions(packet); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
ber.PrintPacket(packet)
|
ber.PrintPacket(packet)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
104
vendor/gopkg.in/ldap.v3/moddn.go
generated
vendored
Normal file
104
vendor/gopkg.in/ldap.v3/moddn.go
generated
vendored
Normal file
@@ -0,0 +1,104 @@
|
|||||||
|
// Package ldap - moddn.go contains ModifyDN functionality
|
||||||
|
//
|
||||||
|
// https://tools.ietf.org/html/rfc4511
|
||||||
|
// ModifyDNRequest ::= [APPLICATION 12] SEQUENCE {
|
||||||
|
// entry LDAPDN,
|
||||||
|
// newrdn RelativeLDAPDN,
|
||||||
|
// deleteoldrdn BOOLEAN,
|
||||||
|
// newSuperior [0] LDAPDN OPTIONAL }
|
||||||
|
//
|
||||||
|
//
|
||||||
|
package ldap
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"log"
|
||||||
|
|
||||||
|
"gopkg.in/asn1-ber.v1"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ModifyDNRequest holds the request to modify a DN
|
||||||
|
type ModifyDNRequest struct {
|
||||||
|
DN string
|
||||||
|
NewRDN string
|
||||||
|
DeleteOldRDN bool
|
||||||
|
NewSuperior string
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewModifyDNRequest creates a new request which can be passed to ModifyDN().
|
||||||
|
//
|
||||||
|
// To move an object in the tree, set the "newSup" to the new parent entry DN. Use an
|
||||||
|
// empty string for just changing the object's RDN.
|
||||||
|
//
|
||||||
|
// For moving the object without renaming, the "rdn" must be the first
|
||||||
|
// RDN of the given DN.
|
||||||
|
//
|
||||||
|
// A call like
|
||||||
|
// mdnReq := NewModifyDNRequest("uid=someone,dc=example,dc=org", "uid=newname", true, "")
|
||||||
|
// will setup the request to just rename uid=someone,dc=example,dc=org to
|
||||||
|
// uid=newname,dc=example,dc=org.
|
||||||
|
func NewModifyDNRequest(dn string, rdn string, delOld bool, newSup string) *ModifyDNRequest {
|
||||||
|
return &ModifyDNRequest{
|
||||||
|
DN: dn,
|
||||||
|
NewRDN: rdn,
|
||||||
|
DeleteOldRDN: delOld,
|
||||||
|
NewSuperior: newSup,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m ModifyDNRequest) encode() *ber.Packet {
|
||||||
|
request := ber.Encode(ber.ClassApplication, ber.TypeConstructed, ApplicationModifyDNRequest, nil, "Modify DN Request")
|
||||||
|
request.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, m.DN, "DN"))
|
||||||
|
request.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, m.NewRDN, "New RDN"))
|
||||||
|
request.AppendChild(ber.NewBoolean(ber.ClassUniversal, ber.TypePrimitive, ber.TagBoolean, m.DeleteOldRDN, "Delete old RDN"))
|
||||||
|
if m.NewSuperior != "" {
|
||||||
|
request.AppendChild(ber.NewString(ber.ClassContext, ber.TypePrimitive, 0, m.NewSuperior, "New Superior"))
|
||||||
|
}
|
||||||
|
return request
|
||||||
|
}
|
||||||
|
|
||||||
|
// ModifyDN renames the given DN and optionally move to another base (when the "newSup" argument
|
||||||
|
// to NewModifyDNRequest() is not "").
|
||||||
|
func (l *Conn) ModifyDN(m *ModifyDNRequest) error {
|
||||||
|
packet := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "LDAP Request")
|
||||||
|
packet.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagInteger, l.nextMessageID(), "MessageID"))
|
||||||
|
packet.AppendChild(m.encode())
|
||||||
|
|
||||||
|
l.Debug.PrintPacket(packet)
|
||||||
|
|
||||||
|
msgCtx, err := l.sendMessage(packet)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer l.finishMessage(msgCtx)
|
||||||
|
|
||||||
|
l.Debug.Printf("%d: waiting for response", msgCtx.id)
|
||||||
|
packetResponse, ok := <-msgCtx.responses
|
||||||
|
if !ok {
|
||||||
|
return NewError(ErrorNetwork, errors.New("ldap: channel closed"))
|
||||||
|
}
|
||||||
|
packet, err = packetResponse.ReadPacket()
|
||||||
|
l.Debug.Printf("%d: got response %p", msgCtx.id, packet)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if l.Debug {
|
||||||
|
if err := addLDAPDescriptions(packet); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
ber.PrintPacket(packet)
|
||||||
|
}
|
||||||
|
|
||||||
|
if packet.Children[1].Tag == ApplicationModifyDNResponse {
|
||||||
|
err := GetLDAPError(packet)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
log.Printf("Unexpected Response: %d", packet.Children[1].Tag)
|
||||||
|
}
|
||||||
|
|
||||||
|
l.Debug.Printf("%d: returning", msgCtx.id)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
75
vendor/gopkg.in/ldap.v2/modify.go → vendor/gopkg.in/ldap.v3/modify.go
generated
vendored
75
vendor/gopkg.in/ldap.v2/modify.go → vendor/gopkg.in/ldap.v3/modify.go
generated
vendored
@@ -1,7 +1,3 @@
|
|||||||
// Copyright 2014 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
//
|
|
||||||
// File contains Modify functionality
|
// File contains Modify functionality
|
||||||
//
|
//
|
||||||
// https://tools.ietf.org/html/rfc4511
|
// https://tools.ietf.org/html/rfc4511
|
||||||
@@ -62,54 +58,56 @@ func (p *PartialAttribute) encode() *ber.Packet {
|
|||||||
return seq
|
return seq
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Change for a ModifyRequest as defined in https://tools.ietf.org/html/rfc4511
|
||||||
|
type Change struct {
|
||||||
|
// Operation is the type of change to be made
|
||||||
|
Operation uint
|
||||||
|
// Modification is the attribute to be modified
|
||||||
|
Modification PartialAttribute
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Change) encode() *ber.Packet {
|
||||||
|
change := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "Change")
|
||||||
|
change.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagEnumerated, uint64(c.Operation), "Operation"))
|
||||||
|
change.AppendChild(c.Modification.encode())
|
||||||
|
return change
|
||||||
|
}
|
||||||
|
|
||||||
// ModifyRequest as defined in https://tools.ietf.org/html/rfc4511
|
// ModifyRequest as defined in https://tools.ietf.org/html/rfc4511
|
||||||
type ModifyRequest struct {
|
type ModifyRequest struct {
|
||||||
// DN is the distinguishedName of the directory entry to modify
|
// DN is the distinguishedName of the directory entry to modify
|
||||||
DN string
|
DN string
|
||||||
// AddAttributes contain the attributes to add
|
// Changes contain the attributes to modify
|
||||||
AddAttributes []PartialAttribute
|
Changes []Change
|
||||||
// DeleteAttributes contain the attributes to delete
|
// Controls hold optional controls to send with the request
|
||||||
DeleteAttributes []PartialAttribute
|
Controls []Control
|
||||||
// ReplaceAttributes contain the attributes to replace
|
|
||||||
ReplaceAttributes []PartialAttribute
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add inserts the given attribute to the list of attributes to add
|
// Add appends the given attribute to the list of changes to be made
|
||||||
func (m *ModifyRequest) Add(attrType string, attrVals []string) {
|
func (m *ModifyRequest) Add(attrType string, attrVals []string) {
|
||||||
m.AddAttributes = append(m.AddAttributes, PartialAttribute{Type: attrType, Vals: attrVals})
|
m.appendChange(AddAttribute, attrType, attrVals)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete inserts the given attribute to the list of attributes to delete
|
// Delete appends the given attribute to the list of changes to be made
|
||||||
func (m *ModifyRequest) Delete(attrType string, attrVals []string) {
|
func (m *ModifyRequest) Delete(attrType string, attrVals []string) {
|
||||||
m.DeleteAttributes = append(m.DeleteAttributes, PartialAttribute{Type: attrType, Vals: attrVals})
|
m.appendChange(DeleteAttribute, attrType, attrVals)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Replace inserts the given attribute to the list of attributes to replace
|
// Replace appends the given attribute to the list of changes to be made
|
||||||
func (m *ModifyRequest) Replace(attrType string, attrVals []string) {
|
func (m *ModifyRequest) Replace(attrType string, attrVals []string) {
|
||||||
m.ReplaceAttributes = append(m.ReplaceAttributes, PartialAttribute{Type: attrType, Vals: attrVals})
|
m.appendChange(ReplaceAttribute, attrType, attrVals)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *ModifyRequest) appendChange(operation uint, attrType string, attrVals []string) {
|
||||||
|
m.Changes = append(m.Changes, Change{operation, PartialAttribute{Type: attrType, Vals: attrVals}})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m ModifyRequest) encode() *ber.Packet {
|
func (m ModifyRequest) encode() *ber.Packet {
|
||||||
request := ber.Encode(ber.ClassApplication, ber.TypeConstructed, ApplicationModifyRequest, nil, "Modify Request")
|
request := ber.Encode(ber.ClassApplication, ber.TypeConstructed, ApplicationModifyRequest, nil, "Modify Request")
|
||||||
request.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, m.DN, "DN"))
|
request.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, m.DN, "DN"))
|
||||||
changes := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "Changes")
|
changes := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "Changes")
|
||||||
for _, attribute := range m.AddAttributes {
|
for _, change := range m.Changes {
|
||||||
change := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "Change")
|
changes.AppendChild(change.encode())
|
||||||
change.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagEnumerated, uint64(AddAttribute), "Operation"))
|
|
||||||
change.AppendChild(attribute.encode())
|
|
||||||
changes.AppendChild(change)
|
|
||||||
}
|
|
||||||
for _, attribute := range m.DeleteAttributes {
|
|
||||||
change := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "Change")
|
|
||||||
change.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagEnumerated, uint64(DeleteAttribute), "Operation"))
|
|
||||||
change.AppendChild(attribute.encode())
|
|
||||||
changes.AppendChild(change)
|
|
||||||
}
|
|
||||||
for _, attribute := range m.ReplaceAttributes {
|
|
||||||
change := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "Change")
|
|
||||||
change.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagEnumerated, uint64(ReplaceAttribute), "Operation"))
|
|
||||||
change.AppendChild(attribute.encode())
|
|
||||||
changes.AppendChild(change)
|
|
||||||
}
|
}
|
||||||
request.AppendChild(changes)
|
request.AppendChild(changes)
|
||||||
return request
|
return request
|
||||||
@@ -118,9 +116,11 @@ func (m ModifyRequest) encode() *ber.Packet {
|
|||||||
// NewModifyRequest creates a modify request for the given DN
|
// NewModifyRequest creates a modify request for the given DN
|
||||||
func NewModifyRequest(
|
func NewModifyRequest(
|
||||||
dn string,
|
dn string,
|
||||||
|
controls []Control,
|
||||||
) *ModifyRequest {
|
) *ModifyRequest {
|
||||||
return &ModifyRequest{
|
return &ModifyRequest{
|
||||||
DN: dn,
|
DN: dn,
|
||||||
|
Controls: controls,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -129,6 +129,9 @@ func (l *Conn) Modify(modifyRequest *ModifyRequest) error {
|
|||||||
packet := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "LDAP Request")
|
packet := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "LDAP Request")
|
||||||
packet.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagInteger, l.nextMessageID(), "MessageID"))
|
packet.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagInteger, l.nextMessageID(), "MessageID"))
|
||||||
packet.AppendChild(modifyRequest.encode())
|
packet.AppendChild(modifyRequest.encode())
|
||||||
|
if len(modifyRequest.Controls) > 0 {
|
||||||
|
packet.AppendChild(encodeControls(modifyRequest.Controls))
|
||||||
|
}
|
||||||
|
|
||||||
l.Debug.PrintPacket(packet)
|
l.Debug.PrintPacket(packet)
|
||||||
|
|
||||||
@@ -157,9 +160,9 @@ func (l *Conn) Modify(modifyRequest *ModifyRequest) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if packet.Children[1].Tag == ApplicationModifyResponse {
|
if packet.Children[1].Tag == ApplicationModifyResponse {
|
||||||
resultCode, resultDescription := getLDAPResultCode(packet)
|
err := GetLDAPError(packet)
|
||||||
if resultCode != 0 {
|
if err != nil {
|
||||||
return NewError(resultCode, errors.New(resultDescription))
|
return err
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
log.Printf("Unexpected Response: %d", packet.Children[1].Tag)
|
log.Printf("Unexpected Response: %d", packet.Children[1].Tag)
|
||||||
17
vendor/gopkg.in/ldap.v2/passwdmodify.go → vendor/gopkg.in/ldap.v3/passwdmodify.go
generated
vendored
17
vendor/gopkg.in/ldap.v2/passwdmodify.go → vendor/gopkg.in/ldap.v3/passwdmodify.go
generated
vendored
@@ -32,6 +32,8 @@ type PasswordModifyRequest struct {
|
|||||||
type PasswordModifyResult struct {
|
type PasswordModifyResult struct {
|
||||||
// GeneratedPassword holds a password generated by the server, if present
|
// GeneratedPassword holds a password generated by the server, if present
|
||||||
GeneratedPassword string
|
GeneratedPassword string
|
||||||
|
// Referral are the returned referral
|
||||||
|
Referral string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *PasswordModifyRequest) encode() (*ber.Packet, error) {
|
func (r *PasswordModifyRequest) encode() (*ber.Packet, error) {
|
||||||
@@ -124,12 +126,19 @@ func (l *Conn) PasswordModify(passwordModifyRequest *PasswordModifyRequest) (*Pa
|
|||||||
}
|
}
|
||||||
|
|
||||||
if packet.Children[1].Tag == ApplicationExtendedResponse {
|
if packet.Children[1].Tag == ApplicationExtendedResponse {
|
||||||
resultCode, resultDescription := getLDAPResultCode(packet)
|
err := GetLDAPError(packet)
|
||||||
if resultCode != 0 {
|
if err != nil {
|
||||||
return nil, NewError(resultCode, errors.New(resultDescription))
|
if IsErrorWithCode(err, LDAPResultReferral) {
|
||||||
|
for _, child := range packet.Children[1].Children {
|
||||||
|
if child.Tag == 3 {
|
||||||
|
result.Referral = child.Children[0].Value.(string)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result, err
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return nil, NewError(ErrorUnexpectedResponse, fmt.Errorf("Unexpected Response: %d", packet.Children[1].Tag))
|
return nil, NewError(ErrorUnexpectedResponse, fmt.Errorf("unexpected Response: %d", packet.Children[1].Tag))
|
||||||
}
|
}
|
||||||
|
|
||||||
extendedResponse := packet.Children[1]
|
extendedResponse := packet.Children[1]
|
||||||
22
vendor/gopkg.in/ldap.v2/search.go → vendor/gopkg.in/ldap.v3/search.go
generated
vendored
22
vendor/gopkg.in/ldap.v2/search.go → vendor/gopkg.in/ldap.v3/search.go
generated
vendored
@@ -1,7 +1,3 @@
|
|||||||
// Copyright 2011 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
//
|
|
||||||
// File contains Search functionality
|
// File contains Search functionality
|
||||||
//
|
//
|
||||||
// https://tools.ietf.org/html/rfc4511
|
// https://tools.ietf.org/html/rfc4511
|
||||||
@@ -313,10 +309,10 @@ func (l *Conn) SearchWithPaging(searchRequest *SearchRequest, pagingSize uint32)
|
|||||||
} else {
|
} else {
|
||||||
castControl, ok := control.(*ControlPaging)
|
castControl, ok := control.(*ControlPaging)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, fmt.Errorf("Expected paging control to be of type *ControlPaging, got %v", control)
|
return nil, fmt.Errorf("expected paging control to be of type *ControlPaging, got %v", control)
|
||||||
}
|
}
|
||||||
if castControl.PagingSize != pagingSize {
|
if castControl.PagingSize != pagingSize {
|
||||||
return nil, fmt.Errorf("Paging size given in search request (%d) conflicts with size given in search call (%d)", castControl.PagingSize, pagingSize)
|
return nil, fmt.Errorf("paging size given in search request (%d) conflicts with size given in search call (%d)", castControl.PagingSize, pagingSize)
|
||||||
}
|
}
|
||||||
pagingControl = castControl
|
pagingControl = castControl
|
||||||
}
|
}
|
||||||
@@ -379,7 +375,7 @@ func (l *Conn) Search(searchRequest *SearchRequest) (*SearchResult, error) {
|
|||||||
}
|
}
|
||||||
packet.AppendChild(encodedSearchRequest)
|
packet.AppendChild(encodedSearchRequest)
|
||||||
// encode search controls
|
// encode search controls
|
||||||
if searchRequest.Controls != nil {
|
if len(searchRequest.Controls) > 0 {
|
||||||
packet.AppendChild(encodeControls(searchRequest.Controls))
|
packet.AppendChild(encodeControls(searchRequest.Controls))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -431,13 +427,17 @@ func (l *Conn) Search(searchRequest *SearchRequest) (*SearchResult, error) {
|
|||||||
}
|
}
|
||||||
result.Entries = append(result.Entries, entry)
|
result.Entries = append(result.Entries, entry)
|
||||||
case 5:
|
case 5:
|
||||||
resultCode, resultDescription := getLDAPResultCode(packet)
|
err := GetLDAPError(packet)
|
||||||
if resultCode != 0 {
|
if err != nil {
|
||||||
return result, NewError(resultCode, errors.New(resultDescription))
|
return nil, err
|
||||||
}
|
}
|
||||||
if len(packet.Children) == 3 {
|
if len(packet.Children) == 3 {
|
||||||
for _, child := range packet.Children[2].Children {
|
for _, child := range packet.Children[2].Children {
|
||||||
result.Controls = append(result.Controls, DecodeControl(child))
|
decodedChild, err := DecodeControl(child)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to decode child control: %s", err)
|
||||||
|
}
|
||||||
|
result.Controls = append(result.Controls, decodedChild)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
foundSearchResultDone = true
|
foundSearchResultDone = true
|
||||||
Reference in New Issue
Block a user