Compare commits

..

6 Commits

Author SHA1 Message Date
Lauris BH
3022681432 Changelog for 1.4.0-rc3 (#3679) 2018-03-16 22:11:34 +02:00
Lauris BH
c0e0fb7d39 Refactor and simplify redirect to url (#3674) (#3676) 2018-03-16 19:59:47 +08:00
Lauris BH
0c612124f9 Update markbates/goth libary to fix OAuth2 support (#3661) (#3663) 2018-03-13 09:08:26 +02:00
Lauris BH
5d0c9872a9 Fix MySQL and PostgreSQL column drop SQL (#3649) (#3651) 2018-03-10 10:27:19 +08:00
Lauris BH
92a3061753 Fix column removal in MSSQL (#3638) (#3640)
* Fix column removal in MSSQL

* Use xorm session in MSSQL drop column operations

* Add transaction as MSSQL alter table is transactional
2018-03-07 11:59:20 +02:00
Lauris BH
efc5a7171b Fix wiki inter-links with spaces (#3560) (#3632) 2018-03-06 16:43:50 +08:00
12 changed files with 177 additions and 86 deletions

View File

@@ -4,6 +4,14 @@ 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
been added to each release, please refer to the [blog](https://blog.gitea.io).
## [1.4.0-rc3](https://github.com/go-gitea/gitea/releases/tag/v1.4.0-rc3) - 2018-03-16
* SECURITY
* Refactor and simplify to correctly validate redirect to URL (#3674) (#3676)
* BUGFIXES
* Update markbates/goth library to fix OAuth2 support (#3661) (#3663)
* Fix column removal in MSSQL (#3638) (#3640)
* Fix wiki inter-links with spaces (#3560) (#3632)
## [1.4.0-rc2](https://github.com/go-gitea/gitea/releases/tag/v1.4.0-rc2) - 2018-03-02
* SECURITY
* Fix escaping changed title in comments (#3530) (#3534)

View File

@@ -217,6 +217,66 @@ Please try to upgrade to a lower version (>= v0.6.0) first, then upgrade to curr
return nil
}
func dropTableColumns(x *xorm.Engine, tableName string, columnNames ...string) (err error) {
if tableName == "" || len(columnNames) == 0 {
return nil
}
switch {
case setting.UseSQLite3:
log.Warn("Unable to drop columns in SQLite")
case setting.UseMySQL, setting.UseTiDB, setting.UsePostgreSQL:
cols := ""
for _, col := range columnNames {
if cols != "" {
cols += ", "
}
cols += "DROP COLUMN `" + col + "`"
}
if _, err := x.Exec(fmt.Sprintf("ALTER TABLE `%s` %s", tableName, cols)); err != nil {
return fmt.Errorf("Drop table `%s` columns %v: %v", tableName, columnNames, err)
}
case setting.UseMSSQL:
sess := x.NewSession()
defer sess.Close()
if err = sess.Begin(); err != nil {
return err
}
cols := ""
for _, col := range columnNames {
if cols != "" {
cols += ", "
}
cols += "`" + strings.ToLower(col) + "`"
}
sql := fmt.Sprintf("SELECT Name FROM SYS.DEFAULT_CONSTRAINTS WHERE PARENT_OBJECT_ID = OBJECT_ID('%[1]s') AND PARENT_COLUMN_ID IN (SELECT column_id FROM sys.columns WHERE lower(NAME) IN (%[2]s) AND object_id = OBJECT_ID('%[1]s'))",
tableName, strings.Replace(cols, "`", "'", -1))
constraints := make([]string, 0)
if err := sess.SQL(sql).Find(&constraints); err != nil {
sess.Rollback()
return fmt.Errorf("Find constraints: %v", err)
}
for _, constraint := range constraints {
if _, err := sess.Exec(fmt.Sprintf("ALTER TABLE `%s` DROP CONSTRAINT `%s`", tableName, constraint)); err != nil {
sess.Rollback()
return fmt.Errorf("Drop table `%s` constraint `%s`: %v", tableName, constraint, err)
}
}
if _, err := sess.Exec(fmt.Sprintf("ALTER TABLE `%s` DROP COLUMN %s", tableName, cols)); err != nil {
sess.Rollback()
return fmt.Errorf("Drop table `%s` columns %v: %v", tableName, columnNames, err)
}
return sess.Commit()
default:
log.Fatal(4, "Unrecognized DB")
}
return nil
}
func fixLocaleFileLoadPanic(_ *xorm.Engine) error {
cfg, err := ini.Load(setting.CustomConf)
if err != nil {

View File

@@ -5,29 +5,9 @@
package migrations
import (
"fmt"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting"
"github.com/go-xorm/xorm"
)
func removeIsOwnerColumnFromOrgUser(x *xorm.Engine) (err error) {
switch {
case setting.UseSQLite3:
log.Warn("Unable to drop columns in SQLite")
case setting.UseMySQL, setting.UseTiDB, setting.UsePostgreSQL:
if _, err := x.Exec("ALTER TABLE org_user DROP COLUMN is_owner, DROP COLUMN num_teams"); err != nil {
return fmt.Errorf("DROP COLUMN org_user.is_owner, org_user.num_teams: %v", err)
}
case setting.UseMSSQL:
if _, err := x.Exec("ALTER TABLE org_user DROP COLUMN is_owner, num_teams"); err != nil {
return fmt.Errorf("DROP COLUMN org_user.is_owner, org_user.num_teams: %v", err)
}
default:
log.Fatal(4, "Unrecognized DB")
}
return nil
return dropTableColumns(x, "org_user", "is_owner", "num_teams")
}

View File

@@ -9,6 +9,7 @@ import (
"html/template"
"io"
"net/http"
"net/url"
"path"
"strings"
"time"
@@ -75,6 +76,26 @@ func (ctx *Context) HasValue(name string) bool {
return ok
}
// RedirectToFirst redirects to first not empty URL
func (ctx *Context) RedirectToFirst(location ...string) {
for _, loc := range location {
if len(loc) == 0 {
continue
}
u, err := url.Parse(loc)
if err != nil || (u.Scheme != "" && !strings.HasPrefix(strings.ToLower(loc), strings.ToLower(setting.AppURL))) {
continue
}
ctx.Redirect(loc)
return
}
ctx.Redirect(setting.AppSubURL + "/")
return
}
// HTML calls Context.HTML and converts template name to string.
func (ctx *Context) HTML(status int, name base.TplName) {
log.Debug("Template: %s", name)

View File

@@ -391,7 +391,11 @@ func RenderShortLinks(rawBytes []byte, urlPrefix string, noLink bool, isWikiMark
}
absoluteLink := isLink([]byte(link))
if !absoluteLink {
link = strings.Replace(link, " ", "+", -1)
if image {
link = strings.Replace(link, " ", "+", -1)
} else {
link = strings.Replace(link, " ", "-", -1)
}
}
if image {
if !absoluteLink {

View File

@@ -307,11 +307,7 @@ func Action(ctx *context.Context) {
return
}
redirectTo := ctx.Query("redirect_to")
if len(redirectTo) == 0 {
redirectTo = ctx.Repo.RepoLink
}
ctx.Redirect(redirectTo)
ctx.RedirectToFirst(ctx.Query("redirect_to"), ctx.Repo.RepoLink)
}
// Download download an archive of a repository

View File

@@ -93,12 +93,8 @@ func checkAutoLogin(ctx *context.Context) bool {
}
if isSucceed {
if len(redirectTo) > 0 {
ctx.SetCookie("redirect_to", "", -1, setting.AppSubURL)
ctx.Redirect(redirectTo)
} else {
ctx.Redirect(setting.AppSubURL + string(setting.LandingPageURL))
}
ctx.SetCookie("redirect_to", "", -1, setting.AppSubURL)
ctx.RedirectToFirst(redirectTo, setting.AppSubURL+string(setting.LandingPageURL))
return true
}
@@ -350,7 +346,7 @@ func handleSignInFull(ctx *context.Context, u *models.User, remember bool, obeyR
if redirectTo, _ := url.QueryUnescape(ctx.GetCookie("redirect_to")); len(redirectTo) > 0 {
ctx.SetCookie("redirect_to", "", -1, setting.AppSubURL)
if obeyRedirect {
ctx.Redirect(redirectTo)
ctx.RedirectToFirst(redirectTo)
}
return
}
@@ -439,7 +435,7 @@ func handleOAuth2SignIn(u *models.User, gothUser goth.User, ctx *context.Context
if redirectTo, _ := url.QueryUnescape(ctx.GetCookie("redirect_to")); len(redirectTo) > 0 {
ctx.SetCookie("redirect_to", "", -1, setting.AppSubURL)
ctx.Redirect(redirectTo)
ctx.RedirectToFirst(redirectTo)
return
}

View File

@@ -49,12 +49,8 @@ func SignInOpenID(ctx *context.Context) {
}
if isSucceed {
if len(redirectTo) > 0 {
ctx.SetCookie("redirect_to", "", -1, setting.AppSubURL)
ctx.Redirect(redirectTo)
} else {
ctx.Redirect(setting.AppSubURL + "/")
}
ctx.SetCookie("redirect_to", "", -1, setting.AppSubURL)
ctx.RedirectToFirst(redirectTo)
return
}

View File

@@ -271,9 +271,5 @@ func Action(ctx *context.Context) {
return
}
redirectTo := ctx.Query("redirect_to")
if len(redirectTo) == 0 {
redirectTo = u.HomeLink()
}
ctx.Redirect(redirectTo)
ctx.RedirectToFirst(ctx.Query("redirect_to"), u.HomeLink())
}

View File

@@ -132,7 +132,7 @@ func GetAuthURL(res http.ResponseWriter, req *http.Request) (string, error) {
return "", err
}
err = storeInSession(providerName, sess.Marshal(), req, res)
err = StoreInSession(providerName, sess.Marshal(), req, res)
if err != nil {
return "", err
@@ -166,7 +166,7 @@ var CompleteUserAuth = func(res http.ResponseWriter, req *http.Request) (goth.Us
return goth.User{}, err
}
value, err := getFromSession(providerName, req)
value, err := GetFromSession(providerName, req)
if err != nil {
return goth.User{}, err
}
@@ -193,7 +193,7 @@ var CompleteUserAuth = func(res http.ResponseWriter, req *http.Request) (goth.Us
return goth.User{}, err
}
err = storeInSession(providerName, sess.Marshal(), req, res)
err = StoreInSession(providerName, sess.Marshal(), req, res)
if err != nil {
return goth.User{}, err
@@ -284,8 +284,9 @@ func getProviderName(req *http.Request) (string, error) {
return "", errors.New("you must select a provider")
}
func storeInSession(key string, value string, req *http.Request, res http.ResponseWriter) error {
session, _ := Store.Get(req, SessionName)
// StoreInSession stores a specified key/value pair in the session.
func StoreInSession(key string, value string, req *http.Request, res http.ResponseWriter) error {
session, _ := Store.New(req, SessionName)
if err := updateSessionValue(session, key, value); err != nil {
return err
@@ -294,7 +295,9 @@ func storeInSession(key string, value string, req *http.Request, res http.Respon
return session.Save(req, res)
}
func getFromSession(key string, req *http.Request) (string, error) {
// GetFromSession retrieves a previously-stored value from the session.
// If no value has previously been stored at the specified key, it will return an error.
func GetFromSession(key string, req *http.Request) (string, error) {
session, _ := Store.Get(req, SessionName)
value, err := getSessionValue(session, key)
if err != nil {

View File

@@ -2,9 +2,11 @@
package dropbox
import (
"bytes"
"encoding/json"
"errors"
"io"
"io/ioutil"
"net/http"
"strings"
@@ -25,6 +27,7 @@ type Provider struct {
ClientKey string
Secret string
CallbackURL string
AccountURL string
HTTPClient *http.Client
config *oauth2.Config
providerName string
@@ -44,6 +47,7 @@ func New(clientKey, secret, callbackURL string, scopes ...string) *Provider {
ClientKey: clientKey,
Secret: secret,
CallbackURL: callbackURL,
AccountURL: accountURL,
providerName: "dropbox",
}
p.config = newConfig(p, scopes)
@@ -87,7 +91,7 @@ func (p *Provider) FetchUser(session goth.Session) (goth.User, error) {
return user, fmt.Errorf("%s cannot get user information without accessToken", p.providerName)
}
req, err := http.NewRequest("POST", accountURL, nil)
req, err := http.NewRequest("POST", p.AccountURL, nil)
if err != nil {
return user, err
}
@@ -102,7 +106,17 @@ func (p *Provider) FetchUser(session goth.Session) (goth.User, error) {
return user, fmt.Errorf("%s responded with a %d trying to fetch user information", p.providerName, resp.StatusCode)
}
err = userFromReader(resp.Body, &user)
bits, err := ioutil.ReadAll(resp.Body)
if err != nil {
return user, err
}
err = json.NewDecoder(bytes.NewReader(bits)).Decode(&user.RawData)
if err != nil {
return user, err
}
err = userFromReader(bytes.NewReader(bits), &user)
return user, err
}
@@ -162,22 +176,29 @@ func newConfig(p *Provider, scopes []string) *oauth2.Config {
func userFromReader(r io.Reader, user *goth.User) error {
u := struct {
Name string `json:"display_name"`
NameDetails struct {
NickName string `json:"familiar_name"`
} `json:"name_details"`
Location string `json:"country"`
Email string `json:"email"`
AccountID string `json:"account_id"`
Name struct {
GivenName string `json:"given_name"`
Surname string `json:"surname"`
DisplayName string `json:"display_name"`
} `json:"name"`
Country string `json:"country"`
Email string `json:"email"`
ProfilePhotoURL string `json:"profile_photo_url"`
}{}
err := json.NewDecoder(r).Decode(&u)
if err != nil {
return err
}
user.UserID = u.AccountID // The user's unique Dropbox ID.
user.FirstName = u.Name.GivenName
user.LastName = u.Name.Surname
user.Name = strings.TrimSpace(fmt.Sprintf("%s %s", u.Name.GivenName, u.Name.Surname))
user.Description = u.Name.DisplayName // Full name plus parenthetical team naem
user.Email = u.Email
user.Name = u.Name
user.NickName = u.NameDetails.NickName
user.UserID = u.Email // Dropbox doesn't provide a separate user ID
user.Location = u.Location
user.NickName = u.Email // Email is the dropbox username
user.Location = u.Country
user.AvatarURL = u.ProfilePhotoURL // May be blank
return nil
}

54
vendor/vendor.json vendored
View File

@@ -655,63 +655,73 @@
},
{
"checksumSHA1": "q9MD1ienC+kmKq5i51oAktQEV1E=",
"origin": "github.com/go-gitea/goth",
"path": "github.com/markbates/goth",
"revision": "bc7deaf077a50416cf3a23aa5903d2a7b5a30ada",
"revisionTime": "2018-02-15T02:27:40Z"
"revision": "3b54d96084a5e11030f19556cf68a6ab5d93ba20",
"revisionTime": "2018-03-12T06:32:04Z"
},
{
"checksumSHA1": "+nosptSgGb2qCAR6CSHV2avwmNg=",
"checksumSHA1": "FISfgOkoMtn98wglLUvfBTZ6baE=",
"origin": "github.com/go-gitea/goth/gothic",
"path": "github.com/markbates/goth/gothic",
"revision": "bc7deaf077a50416cf3a23aa5903d2a7b5a30ada",
"revisionTime": "2018-02-15T02:27:40Z"
"revision": "3b54d96084a5e11030f19556cf68a6ab5d93ba20",
"revisionTime": "2018-03-12T06:32:04Z"
},
{
"checksumSHA1": "pJ+Cws/TU22K6tZ/ALFOvvH1K5U=",
"origin": "github.com/go-gitea/goth/providers/bitbucket",
"path": "github.com/markbates/goth/providers/bitbucket",
"revision": "bc7deaf077a50416cf3a23aa5903d2a7b5a30ada",
"revisionTime": "2018-02-15T02:27:40Z"
"revision": "3b54d96084a5e11030f19556cf68a6ab5d93ba20",
"revisionTime": "2018-03-12T06:32:04Z"
},
{
"checksumSHA1": "bKokLof0Pkk5nEhW8NdbfcVzuqk=",
"checksumSHA1": "XsF5HI4240QHbFXbtWWnGgTsoq8=",
"origin": "github.com/go-gitea/goth/providers/dropbox",
"path": "github.com/markbates/goth/providers/dropbox",
"revision": "bc7deaf077a50416cf3a23aa5903d2a7b5a30ada",
"revisionTime": "2018-02-15T02:27:40Z"
"revision": "3b54d96084a5e11030f19556cf68a6ab5d93ba20",
"revisionTime": "2018-03-12T06:32:04Z"
},
{
"checksumSHA1": "VzbroIA9R00Ig3iGnOlZLU7d4ls=",
"origin": "github.com/go-gitea/goth/providers/facebook",
"path": "github.com/markbates/goth/providers/facebook",
"revision": "bc7deaf077a50416cf3a23aa5903d2a7b5a30ada",
"revisionTime": "2018-02-15T02:27:40Z"
"revision": "3b54d96084a5e11030f19556cf68a6ab5d93ba20",
"revisionTime": "2018-03-12T06:32:04Z"
},
{
"checksumSHA1": "P6nBZ850aaekpOcoXNdRhK86bH8=",
"origin": "github.com/go-gitea/goth/providers/github",
"path": "github.com/markbates/goth/providers/github",
"revision": "bc7deaf077a50416cf3a23aa5903d2a7b5a30ada",
"revisionTime": "2018-02-15T02:27:40Z"
"revision": "3b54d96084a5e11030f19556cf68a6ab5d93ba20",
"revisionTime": "2018-03-12T06:32:04Z"
},
{
"checksumSHA1": "ld488t+yGoTwtmiCSSggEX4fxVk=",
"origin": "github.com/go-gitea/goth/providers/gitlab",
"path": "github.com/markbates/goth/providers/gitlab",
"revision": "bc7deaf077a50416cf3a23aa5903d2a7b5a30ada",
"revisionTime": "2018-02-15T02:27:40Z"
"revision": "3b54d96084a5e11030f19556cf68a6ab5d93ba20",
"revisionTime": "2018-03-12T06:32:04Z"
},
{
"checksumSHA1": "qXEulD7vnwY9hFrxh91Pm5YrvTM=",
"origin": "github.com/go-gitea/goth/providers/gplus",
"path": "github.com/markbates/goth/providers/gplus",
"revision": "bc7deaf077a50416cf3a23aa5903d2a7b5a30ada",
"revisionTime": "2018-02-15T02:27:40Z"
"revision": "3b54d96084a5e11030f19556cf68a6ab5d93ba20",
"revisionTime": "2018-03-12T06:32:04Z"
},
{
"checksumSHA1": "wsOBzyp4LKDhfCPmX1LLP7T0S3U=",
"origin": "github.com/go-gitea/goth/providers/openidConnect",
"path": "github.com/markbates/goth/providers/openidConnect",
"revision": "bc7deaf077a50416cf3a23aa5903d2a7b5a30ada",
"revisionTime": "2018-02-15T02:27:40Z"
"revision": "3b54d96084a5e11030f19556cf68a6ab5d93ba20",
"revisionTime": "2018-03-12T06:32:04Z"
},
{
"checksumSHA1": "o6RqMbbE8QNZhNT9TsAIRMPI8tg=",
"origin": "github.com/go-gitea/goth/providers/twitter",
"path": "github.com/markbates/goth/providers/twitter",
"revision": "bc7deaf077a50416cf3a23aa5903d2a7b5a30ada",
"revisionTime": "2018-02-15T02:27:40Z"
"revision": "3b54d96084a5e11030f19556cf68a6ab5d93ba20",
"revisionTime": "2018-03-12T06:32:04Z"
},
{
"checksumSHA1": "61HNjGetaBoMp8HBOpuEZRSim8g=",