diff --git a/models/cloudbrain.go b/models/cloudbrain.go
index f9c0fb4e0..7a2966f74 100755
--- a/models/cloudbrain.go
+++ b/models/cloudbrain.go
@@ -72,11 +72,11 @@ type CloudBrainLoginResult struct {
type TaskRole struct {
Name string `json:"name"`
- TaskNumber int8 `json:"taskNumber"`
- MinSucceededTaskCount int8 `json:"minSucceededTaskCount"`
- MinFailedTaskCount int8 `json:"minFailedTaskCount"`
- CPUNumber int8 `json:"cpuNumber"`
- GPUNumber int8 `json:"gpuNumber"`
+ TaskNumber int `json:"taskNumber"`
+ MinSucceededTaskCount int `json:"minSucceededTaskCount"`
+ MinFailedTaskCount int `json:"minFailedTaskCount"`
+ CPUNumber int `json:"cpuNumber"`
+ GPUNumber int `json:"gpuNumber"`
MemoryMB int `json:"memoryMB"`
ShmMB int `json:"shmMB"`
Command string `json:"command"`
@@ -286,6 +286,18 @@ type GpuInfo struct {
Queue string `json:"queue"`
}
+type ResourceSpecs struct {
+ ResourceSpec []*ResourceSpec `json:"resorce_specs"`
+}
+
+type ResourceSpec struct {
+ Id int `json:"id"`
+ CpuNum int `json:"cpu"`
+ GpuNum int `json:"gpu"`
+ MemMiB int `json:"memMiB"`
+ ShareMemMiB int `json:"shareMemMiB"`
+}
+
type CommitImageParams struct {
Ip string `json:"ip"`
TaskContainerId string `json:"taskContainerId"`
diff --git a/models/user.go b/models/user.go
index 3dcd2eee9..42e688358 100755
--- a/models/user.go
+++ b/models/user.go
@@ -976,12 +976,12 @@ func CreateUser(u *User) (err error) {
result, err := blockchain.CreateBlockchainAccount()
if err != nil {
log.Error("createBlockchainAccount failed:", err.Error())
- return err
+ //return err
+ } else {
+ u.PublicKey = result.Payload["publickey"].(string)
+ u.PrivateKey = result.Payload["privatekey"].(string)
}
- u.PublicKey = result.Payload["publickey"].(string)
- u.PrivateKey = result.Payload["privatekey"].(string)
-
sess := x.NewSession()
defer sess.Close()
if err = sess.Begin(); err != nil {
diff --git a/models/user_mail.go b/models/user_mail.go
old mode 100644
new mode 100755
index af9602e71..7244ec378
--- a/models/user_mail.go
+++ b/models/user_mail.go
@@ -80,6 +80,18 @@ func GetEmailAddressByID(uid, id int64) (*EmailAddress, error) {
return email, nil
}
+// GetEmailAddressByIDAndEmail gets a user's email address by ID and email
+func GetEmailAddressByIDAndEmail(uid int64, emailAddr string) (*EmailAddress, error) {
+ // User ID is required for security reasons
+ email := &EmailAddress{UID: uid, Email: emailAddr}
+ if has, err := x.Get(email); err != nil {
+ return nil, err
+ } else if !has {
+ return nil, nil
+ }
+ return email, nil
+}
+
func isEmailActive(e Engine, email string, userID, emailID int64) (bool, error) {
if len(email) == 0 {
return true, nil
diff --git a/modules/auth/cloudbrain.go b/modules/auth/cloudbrain.go
index 8325dc063..d598b495c 100755
--- a/modules/auth/cloudbrain.go
+++ b/modules/auth/cloudbrain.go
@@ -13,6 +13,7 @@ type CreateCloudBrainForm struct {
JobType string `form:"job_type" binding:"Required"`
BenchmarkCategory string `form:"get_benchmark_category"`
GpuType string `form:"gpu_type"`
+ ResourceSpecId int `form:"resource_spec_id" binding:"Required"`
}
type CommitImageCloudBrainForm struct {
diff --git a/modules/cloudbrain/cloudbrain.go b/modules/cloudbrain/cloudbrain.go
index 9fda84ee8..0de1db9a6 100755
--- a/modules/cloudbrain/cloudbrain.go
+++ b/modules/cloudbrain/cloudbrain.go
@@ -23,12 +23,29 @@ const (
Success = "S000"
)
-func GenerateTask(ctx *context.Context, jobName, image, command, uuid, codePath, modelPath, benchmarkPath, snn4imagenetPath, jobType, gpuQueue string) error {
+var (
+ ResourceSpecs *models.ResourceSpecs
+)
+
+func GenerateTask(ctx *context.Context, jobName, image, command, uuid, codePath, modelPath, benchmarkPath, snn4imagenetPath, jobType, gpuQueue string, resourceSpecId int) error {
dataActualPath := setting.Attachment.Minio.RealPath +
setting.Attachment.Minio.Bucket + "/" +
setting.Attachment.Minio.BasePath +
models.AttachmentRelativePath(uuid) +
uuid
+
+ var resourceSpec *models.ResourceSpec
+ for _, spec := range ResourceSpecs.ResourceSpec {
+ if resourceSpecId == spec.Id {
+ resourceSpec = spec
+ }
+ }
+
+ if resourceSpec == nil {
+ log.Error("no such resourceSpecId(%d)", resourceSpecId, ctx.Data["MsgID"])
+ return errors.New("no such resourceSpec")
+ }
+
jobResult, err := CreateJob(jobName, models.CreateJobParams{
JobName: jobName,
RetryCount: 1,
@@ -40,10 +57,10 @@ func GenerateTask(ctx *context.Context, jobName, image, command, uuid, codePath,
TaskNumber: 1,
MinSucceededTaskCount: 1,
MinFailedTaskCount: 1,
- CPUNumber: 2,
- GPUNumber: 1,
- MemoryMB: 16384,
- ShmMB: 8192,
+ CPUNumber: resourceSpec.CpuNum,
+ GPUNumber: resourceSpec.GpuNum,
+ MemoryMB: resourceSpec.MemMiB,
+ ShmMB: resourceSpec.ShareMemMiB,
Command: command,
NeedIBDevice: false,
IsMainRole: false,
diff --git a/modules/convert/convert.go b/modules/convert/convert.go
old mode 100644
new mode 100755
index ec18b1305..fa2e8f2e7
--- a/modules/convert/convert.go
+++ b/modules/convert/convert.go
@@ -335,6 +335,7 @@ func ToUser(user *models.User, signed, authed bool) *api.User {
AvatarURL: user.AvatarLink(),
FullName: markup.Sanitize(user.FullName),
Created: user.CreatedUnix.AsTime(),
+ IsActive: user.IsActive,
}
// hide primary email if API caller is anonymous or user keep email private
if signed && (!user.KeepEmailPrivate || authed) {
diff --git a/modules/setting/setting.go b/modules/setting/setting.go
index 7785028f8..986a18313 100755
--- a/modules/setting/setting.go
+++ b/modules/setting/setting.go
@@ -439,6 +439,7 @@ var (
JobType string
GpuTypes string
DebugServerHost string
+ ResourceSpecs string
//benchmark config
IsBenchmarkEnabled bool
@@ -1147,7 +1148,8 @@ func NewContext() {
JobPath = sec.Key("JOB_PATH").MustString("/datasets/minio/data/opendata/jobs/")
DebugServerHost = sec.Key("DEBUG_SERVER_HOST").MustString("http://192.168.202.73")
JobType = sec.Key("GPU_TYPE_DEFAULT").MustString("openidebug")
- GpuTypes = sec.Key("GPU_TYPES").MustString("openidebug,openidgx")
+ GpuTypes = sec.Key("GPU_TYPES").MustString("")
+ ResourceSpecs = sec.Key("RESOURCE_SPECS").MustString("")
sec = Cfg.Section("benchmark")
IsBenchmarkEnabled = sec.Key("ENABLED").MustBool(false)
diff --git a/modules/structs/user.go b/modules/structs/user.go
old mode 100644
new mode 100755
index bf52cc9ed..d6e7298cc
--- a/modules/structs/user.go
+++ b/modules/structs/user.go
@@ -26,6 +26,8 @@ type User struct {
Language string `json:"language"`
// Is the user an administrator
IsAdmin bool `json:"is_admin"`
+ // Is the user active
+ IsActive bool `json:"is_active"`
// swagger:strfmt date-time
LastLogin time.Time `json:"last_login,omitempty"`
// swagger:strfmt date-time
diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini
index e809a33e8..b81dc9694 100644
--- a/options/locale/locale_en-US.ini
+++ b/options/locale/locale_en-US.ini
@@ -90,7 +90,7 @@ loading = Loading…
error404_index = Request forbidden by administrative rules
error500_index = Internal Server Error
error404 = The page you are trying to reach either does not exist or you are not authorized to view it.
-
+error500= Sorry, the site has encountered some problems, we are trying to fix the page, please try again later.
[error]
occurred = An error has occurred
report_message = An error has occurred
diff --git a/options/locale/locale_zh-CN.ini b/options/locale/locale_zh-CN.ini
index 9747bc7dc..5ac54f6c8 100755
--- a/options/locale/locale_zh-CN.ini
+++ b/options/locale/locale_zh-CN.ini
@@ -90,6 +90,7 @@ loading=正在加载...
error404_index = 您的访问受限!
error500_index = 抱歉!您指定的网页无法访问。
error404=您正尝试访问的页面 不存在 或 您尚未被授权 查看该页面。
+error500=抱歉,站点遇到一些问题,我们正尝试修复网页,请您稍后再试。
[error]
occurred=发生错误
diff --git a/package-lock.json b/package-lock.json
index 2c3c983e6..b0b0acad0 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1841,6 +1841,14 @@
"async-done": "^1.2.2"
}
},
+ "async-validator": {
+ "version": "1.8.5",
+ "resolved": "https://registry.npmjs.org/async-validator/-/async-validator-1.8.5.tgz",
+ "integrity": "sha512-tXBM+1m056MAX0E8TL2iCjg8WvSyXu0Zc8LNtYqrVeyoL3+esHRZ4SieE9fKQyyU09uONjnMEjrNBMqT0mbvmA==",
+ "requires": {
+ "babel-runtime": "6.x"
+ }
+ },
"asynckit": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
@@ -1934,6 +1942,11 @@
}
}
},
+ "babel-helper-vue-jsx-merge-props": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/babel-helper-vue-jsx-merge-props/-/babel-helper-vue-jsx-merge-props-2.0.3.tgz",
+ "integrity": "sha512-gsLiKK7Qrb7zYJNgiXKpXblxbV5ffSwR0f5whkPAaBAR4fhi6bwRZxX9wBlIc5M/v8CCkXUbXZL4N/nSE97cqg=="
+ },
"babel-loader": {
"version": "8.1.0",
"resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-8.1.0.tgz",
@@ -3882,6 +3895,26 @@
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.437.tgz",
"integrity": "sha512-PBQn2q68ErqMyBUABh9Gh8R6DunGky8aB5y3N5lPM7OVpldwyUbAK5AX9WcwE/5F6ceqvQ+iQLYkJYRysAs6Bg=="
},
+ "element-ui": {
+ "version": "2.15.5",
+ "resolved": "https://registry.npmjs.org/element-ui/-/element-ui-2.15.5.tgz",
+ "integrity": "sha512-B/YCdz2aRY2WnFXzbTRTHPKZHBD/2KV6u88EBnkaARC/Lyxnap+7vpvrcW5UNTyVwjItS5Fj1eQyRy6236lbXg==",
+ "requires": {
+ "async-validator": "~1.8.1",
+ "babel-helper-vue-jsx-merge-props": "^2.0.0",
+ "deepmerge": "^1.2.0",
+ "normalize-wheel": "^1.0.1",
+ "resize-observer-polyfill": "^1.5.0",
+ "throttle-debounce": "^1.0.1"
+ },
+ "dependencies": {
+ "deepmerge": {
+ "version": "1.5.2",
+ "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-1.5.2.tgz",
+ "integrity": "sha512-95k0GDqvBjZavkuvzx/YqVLv/6YYa17fz6ILMSf7neqQITCPbnfEnQvEgMPNjH4kgobe7+WIL0yJEHku+H3qtQ=="
+ }
+ }
+ },
"elliptic": {
"version": "6.5.4",
"resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz",
@@ -9186,6 +9219,11 @@
"resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-3.3.0.tgz",
"integrity": "sha512-U+JJi7duF1o+u2pynbp2zXDW2/PADgC30f0GsHZtRh+HOcXHnw137TrNlyxxRvWW5fjKd3bcLHPxofWuCjaeZg=="
},
+ "normalize-wheel": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/normalize-wheel/-/normalize-wheel-1.0.1.tgz",
+ "integrity": "sha1-rsiGr/2wRQcNhWRH32Ls+GFG7EU="
+ },
"now-and-later": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/now-and-later/-/now-and-later-2.0.1.tgz",
@@ -11687,6 +11725,11 @@
"resolved": "https://registry.npmjs.org/reselect/-/reselect-4.0.0.tgz",
"integrity": "sha512-qUgANli03jjAyGlnbYVAV5vvnOmJnODyABz51RdBN7M4WaVu8mecZWgyQNkG8Yqe3KRGRt0l4K4B3XVEULC4CA=="
},
+ "resize-observer-polyfill": {
+ "version": "1.5.1",
+ "resolved": "https://registry.npmjs.org/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz",
+ "integrity": "sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg=="
+ },
"resolve": {
"version": "1.17.0",
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz",
@@ -13526,6 +13569,11 @@
"resolved": "https://registry.npmjs.org/textextensions/-/textextensions-2.6.0.tgz",
"integrity": "sha512-49WtAWS+tcsy93dRt6P0P3AMD2m5PvXRhuEA0kaXos5ZLlujtYmpmFsB+QvWUSxE1ZsstmYXfQ7L40+EcQgpAQ=="
},
+ "throttle-debounce": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/throttle-debounce/-/throttle-debounce-1.1.0.tgz",
+ "integrity": "sha512-XH8UiPCQcWNuk2LYePibW/4qL97+ZQ1AN3FNXwZRBNPPowo/NRU5fAlDCSNBJIYCKbioZfuYtMhG4quqoJhVzg=="
+ },
"through": {
"version": "2.3.8",
"resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
diff --git a/package.json b/package.json
index 4afc213e7..bda9843e8 100644
--- a/package.json
+++ b/package.json
@@ -19,6 +19,7 @@
"cssnano": "4.1.10",
"domino": "2.1.5",
"dropzone": "5.7.2",
+ "element-ui": "2.15.5",
"esdk-obs-browserjs": "3.20.7",
"esdk-obs-nodejs": "3.20.11",
"fast-glob": "3.2.2",
diff --git a/routers/repo/attachment.go b/routers/repo/attachment.go
index 830f193ee..fea7a3384 100755
--- a/routers/repo/attachment.go
+++ b/routers/repo/attachment.go
@@ -151,18 +151,20 @@ func DownloadUserIsOrgOrCollaboration(ctx *context.Context, attach *models.Attac
log.Info("query repo error.")
} else {
repo.GetOwner()
- if repo.Owner.IsOrganization() {
- //log.Info("ower is org.")
- if repo.Owner.IsUserPartOfOrg(ctx.User.ID) {
- log.Info("org user may visit the attach.")
+ if ctx.User != nil {
+
+ if repo.Owner.IsOrganization() {
+ if repo.Owner.IsUserPartOfOrg(ctx.User.ID) {
+ log.Info("org user may visit the attach.")
+ return true
+ }
+ }
+ isCollaborator, _ := repo.IsCollaborator(ctx.User.ID)
+ if isCollaborator {
+ log.Info("Collaborator user may visit the attach.")
return true
}
}
- isCollaborator, _ := repo.IsCollaborator(ctx.User.ID)
- if isCollaborator {
- log.Info("Collaborator user may visit the attach.")
- return true
- }
}
}
return false
@@ -192,19 +194,29 @@ func GetAttachment(ctx *context.Context) {
ctx.ServerError("LinkedRepository", err)
return
}
+ dataSet, err := attach.LinkedDataSet()
+ if err != nil {
+ ctx.ServerError("LinkedDataSet", err)
+ return
+ }
+
+ if repository == nil && dataSet != nil {
+ repository, _ = models.GetRepositoryByID(dataSet.RepoID)
+ unitType = models.UnitTypeDatasets
+ }
if repository == nil { //If not linked
//if !(ctx.IsSigned && attach.UploaderID == ctx.User.ID) && attach.IsPrivate { //We block if not the uploader
- if !(ctx.IsSigned && attach.UploaderID == ctx.User.ID) && !DownloadUserIsOrgOrCollaboration(ctx, attach) { //We block if not the uploader
+ //log.Info("ctx.IsSigned =" + fmt.Sprintf("%v", ctx.IsSigned))
+ if !(ctx.IsSigned && attach.UploaderID == ctx.User.ID) && attach.IsPrivate && !DownloadUserIsOrgOrCollaboration(ctx, attach) { //We block if not the uploader
ctx.Error(http.StatusNotFound)
return
}
} else { //If we have the repository we check access
-
- perm, err := models.GetUserRepoPermission(repository, ctx.User)
- if err != nil {
- ctx.Error(http.StatusInternalServerError, "GetUserRepoPermission", err.Error())
+ perm, errPermission := models.GetUserRepoPermission(repository, ctx.User)
+ if errPermission != nil {
+ ctx.Error(http.StatusInternalServerError, "GetUserRepoPermission", errPermission.Error())
return
}
if !perm.CanRead(unitType) {
@@ -213,12 +225,6 @@ func GetAttachment(ctx *context.Context) {
}
}
- dataSet, err := attach.LinkedDataSet()
- if err != nil {
- ctx.ServerError("LinkedDataSet", err)
- return
- }
-
if dataSet != nil {
isPermit, err := models.GetUserDataSetPermission(dataSet, ctx.User)
if err != nil {
diff --git a/routers/repo/cloudbrain.go b/routers/repo/cloudbrain.go
index 1088f47d3..f6f796e14 100755
--- a/routers/repo/cloudbrain.go
+++ b/routers/repo/cloudbrain.go
@@ -148,6 +148,11 @@ func CloudBrainNew(ctx *context.Context) {
json.Unmarshal([]byte(setting.GpuTypes), &gpuInfos)
}
ctx.Data["gpu_types"] = gpuInfos.GpuInfo
+
+ if cloudbrain.ResourceSpecs == nil {
+ json.Unmarshal([]byte(setting.ResourceSpecs), &cloudbrain.ResourceSpecs)
+ }
+ ctx.Data["resource_specs"] = cloudbrain.ResourceSpecs.ResourceSpec
ctx.Data["snn4imagenet_path"] = cloudbrain.Snn4imagenetMountPath
ctx.Data["is_snn4imagenet_enabled"] = setting.IsSnn4imagenetEnabled
ctx.HTML(200, tplCloudBrainNew)
@@ -162,6 +167,7 @@ func CloudBrainCreate(ctx *context.Context, form auth.CreateCloudBrainForm) {
jobType := form.JobType
gpuQueue := setting.JobType
codePath := setting.JobPath + jobName + cloudbrain.CodeMountPath
+ resourceSpecId := form.ResourceSpecId
if jobType != string(models.JobTypeBenchmark) && jobType != string(models.JobTypeDebug) && jobType != string(models.JobTypeSnn4imagenet) {
log.Error("jobtype error:", jobType, ctx.Data["msgID"])
@@ -208,7 +214,7 @@ func CloudBrainCreate(ctx *context.Context, form auth.CreateCloudBrainForm) {
downloadRateCode(repo, jobName, setting.Snn4imagenetCode, snn4imagenetPath, "", "")
}
- err = cloudbrain.GenerateTask(ctx, jobName, image, command, uuid, codePath, modelPath, benchmarkPath, snn4imagenetPath, jobType, gpuQueue)
+ err = cloudbrain.GenerateTask(ctx, jobName, image, command, uuid, codePath, modelPath, benchmarkPath, snn4imagenetPath, jobType, gpuQueue, resourceSpecId)
if err != nil {
ctx.RenderWithErr(err.Error(), tplCloudBrainNew, &form)
return
diff --git a/routers/repo/dataset.go b/routers/repo/dataset.go
index bdadd2066..b2da4b8d8 100755
--- a/routers/repo/dataset.go
+++ b/routers/repo/dataset.go
@@ -32,13 +32,13 @@ func newFilterPrivateAttachments(ctx *context.Context, list []*models.Attachment
repo.GetOwner()
}
permission := false
- if repo.Owner.IsOrganization() {
+ if repo.Owner.IsOrganization() && ctx.User != nil {
if repo.Owner.IsUserPartOfOrg(ctx.User.ID) {
log.Info("user is member of org.")
permission = true
}
}
- if !permission {
+ if !permission && ctx.User != nil {
isCollaborator, _ := repo.IsCollaborator(ctx.User.ID)
if isCollaborator {
log.Info("Collaborator user may visit the attach.")
diff --git a/routers/routes/routes.go b/routers/routes/routes.go
index 100ff009f..b3565878e 100755
--- a/routers/routes/routes.go
+++ b/routers/routes/routes.go
@@ -1129,7 +1129,7 @@ func RegisterRoutes(m *macaron.Macaron) {
//secure api,
m.Group("/secure", func() {
- m.Post("/user", binding.Bind(structs.CreateUserOption{}), secure.CreateUser)
+ m.Post("/user", binding.BindIgnErr(structs.CreateUserOption{}), secure.CreateUser)
}, reqBasicAuth)
m.Group("/api/internal", func() {
diff --git a/routers/secure/user.go b/routers/secure/user.go
index 1e88a7381..8567dc9e6 100755
--- a/routers/secure/user.go
+++ b/routers/secure/user.go
@@ -7,6 +7,7 @@ package secure
import (
"net/http"
+ "strings"
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/context"
@@ -75,11 +76,19 @@ func CreateUser(ctx *context.Context, form api.CreateUserOption) {
u.MustChangePassword = *form.MustChangePassword
}
+ if strings.Contains(form.Email, " ") {
+ log.Error("CreateUser failed: email(%s) contains blank space", form.Email, ctx.Data["MsgID"])
+ ctx.JSON(http.StatusBadRequest, map[string]string{
+ "error_msg": "Email contains blank space",
+ })
+ return
+ }
+
parseLoginSource(ctx, u, form.SourceID, form.LoginName)
if ctx.Written() {
return
}
- if !password.IsComplexEnough(form.Password) {
+ if !password.IsComplexEnough(form.Password) || len(form.Password) < setting.MinPasswordLength {
log.Error("CreateUser failed: PasswordComplexity", ctx.Data["MsgID"])
ctx.JSON(http.StatusBadRequest, map[string]string{
"error_msg": "PasswordComplexity",
@@ -119,6 +128,14 @@ func CreateUser(ctx *context.Context, form api.CreateUserOption) {
return
}
+ // Send confirmation email
+ if setting.Service.RegisterEmailConfirm{
+ mailer.SendActivateAccountMail(ctx.Locale, u)
+ if err := ctx.Cache.Put("MailResendLimit_"+u.LowerName, u.LowerName, 180); err != nil {
+ log.Error("Set cache(MailResendLimit) fail: %v", err)
+ }
+ }
+
log.Trace("Account created (%s): %s", ctx.User.Name, u.Name, ctx.Data["MsgID"])
// Send email notification.
diff --git a/routers/user/auth.go b/routers/user/auth.go
index dd66fcb8b..13e338565 100755
--- a/routers/user/auth.go
+++ b/routers/user/auth.go
@@ -1266,6 +1266,15 @@ func Activate(ctx *context.Context) {
log.Error("Error storing session: %v", err)
}
+ email, err := models.GetEmailAddressByIDAndEmail(user.ID, user.Email)
+ if err != nil || email == nil{
+ log.Error("GetEmailAddressByIDAndEmail failed", ctx.Data["MsgID"])
+ } else {
+ if err := email.Activate(); err != nil {
+ log.Error("Activate failed: %v", err, ctx.Data["MsgID"])
+ }
+ }
+
ctx.Flash.Success(ctx.Tr("auth.account_activated"))
ctx.Redirect(setting.AppSubURL + "/")
return
diff --git a/routers/user/setting/profile.go b/routers/user/setting/profile.go
old mode 100644
new mode 100755
index d6f25f913..a385f2cac
--- a/routers/user/setting/profile.go
+++ b/routers/user/setting/profile.go
@@ -96,6 +96,18 @@ func ProfilePost(ctx *context.Context, form auth.UpdateProfileForm) {
ctx.User.Location = form.Location
ctx.User.Language = form.Language
ctx.User.Description = form.Description
+ isUsed, err := models.IsEmailUsed(form.Email)
+ if err != nil {
+ ctx.ServerError("IsEmailUsed", err)
+ return
+ }
+
+ if isUsed {
+ ctx.Flash.Error(ctx.Tr("form.email_been_used"))
+ ctx.Redirect(setting.AppSubURL + "/user/settings")
+ return
+ }
+
if err := models.UpdateUserSetting(ctx.User); err != nil {
if _, ok := err.(models.ErrEmailAlreadyUsed); ok {
ctx.Flash.Error(ctx.Tr("form.email_been_used"))
diff --git a/templates/home.tmpl b/templates/home.tmpl
index 35790cbba..97a2a7fc9 100755
--- a/templates/home.tmpl
+++ b/templates/home.tmpl
@@ -127,7 +127,7 @@
- {{if .Repository.DescriptionHTML}} - {{.Repository.DescriptionHTML}} - {{else}} - {{.i18n.Tr "repo.no_desc"}} - {{end}} - {{.Repository.Website}} + {{if .Repository.DescriptionHTML}} + {{.Repository.DescriptionHTML}} + {{else}} + {{.i18n.Tr "repo.no_desc"}} + {{end}} +
++ + {{.Repository.Website}} +
+ + {{end}} +{{range .Topics}}{{.Name}}{{end}} {{if and .Permission.IsAdmin (not .Repository.IsArchived)}}{{.i18n.Tr "repo.topic.manage_topics"}}{{end}}
- +{{range .LanguageStats}} {{.Language}} {{end}}
+ + + {{if .LICENSE}}- {{if .LICENSE}} - {{.LICENSE}} - {{end}} + {{.LICENSE}}
+ + {{end}} diff --git a/templates/status/500.tmpl b/templates/status/500.tmpl index e4ea06d3d..ca7336f82 100644 --- a/templates/status/500.tmpl +++ b/templates/status/500.tmpl @@ -6,7 +6,7 @@{{.i18n.Tr "error404" | Safe}}
+{{.i18n.Tr "error500" | Safe}}