| @@ -5,7 +5,7 @@ Gogs(Go Git Service) is a painless self-hosted Git Service written in Go. | |||
|  | |||
| ##### Current version: 0.4.7 Beta | |||
| ##### Current version: 0.4.8 Beta | |||
| ### NOTICES | |||
| @@ -5,7 +5,7 @@ Gogs(Go Git Service) 是一个基于 Go 语言的自助 Git 服务。 | |||
|  | |||
| ##### 当前版本:0.4.7 Beta | |||
| ##### 当前版本:0.4.8 Beta | |||
| ## 开发目的 | |||
| @@ -192,28 +192,36 @@ func runWeb(*cli.Context) { | |||
| adminReq := middleware.Toggle(&middleware.ToggleOptions{SignInRequire: true, AdminRequire: true}) | |||
| m.Get("/admin", adminReq, admin.Dashboard) | |||
| m.Group("/admin", func(r *macaron.Router) { | |||
| r.Get("/users", admin.Users) | |||
| r.Get("/repos", admin.Repositories) | |||
| r.Get("/auths", admin.Auths) | |||
| m.Get("", adminReq, admin.Dashboard) | |||
| r.Get("/config", admin.Config) | |||
| r.Get("/monitor", admin.Monitor) | |||
| }, adminReq) | |||
| m.Group("/admin/users", func(r *macaron.Router) { | |||
| r.Get("/new", admin.NewUser) | |||
| r.Post("/new", bindIgnErr(auth.RegisterForm{}), admin.NewUserPost) | |||
| r.Get("/:userid", admin.EditUser) | |||
| r.Post("/:userid", bindIgnErr(auth.AdminEditUserForm{}), admin.EditUserPost) | |||
| r.Post("/:userid/delete", admin.DeleteUser) | |||
| }, adminReq) | |||
| m.Group("/admin/auths", func(r *macaron.Router) { | |||
| r.Get("/new", admin.NewAuthSource) | |||
| r.Post("/new", bindIgnErr(auth.AuthenticationForm{}), admin.NewAuthSourcePost) | |||
| r.Get("/:authid", admin.EditAuthSource) | |||
| r.Post("/:authid", bindIgnErr(auth.AuthenticationForm{}), admin.EditAuthSourcePost) | |||
| r.Get("/:authid/delete", admin.DeleteAuthSource) | |||
| m.Group("/users", func(r *macaron.Router) { | |||
| r.Get("", admin.Users) | |||
| r.Get("/new", admin.NewUser) | |||
| r.Post("/new", bindIgnErr(auth.RegisterForm{}), admin.NewUserPost) | |||
| r.Get("/:userid", admin.EditUser) | |||
| r.Post("/:userid", bindIgnErr(auth.AdminEditUserForm{}), admin.EditUserPost) | |||
| r.Post("/:userid/delete", admin.DeleteUser) | |||
| }) | |||
| m.Group("/orgs", func(r *macaron.Router) { | |||
| r.Get("", admin.Organizations) | |||
| }) | |||
| m.Group("/repos", func(r *macaron.Router) { | |||
| r.Get("", admin.Repositories) | |||
| }) | |||
| m.Group("/auths", func(r *macaron.Router) { | |||
| r.Get("", admin.Authentications) | |||
| r.Get("/new", admin.NewAuthSource) | |||
| r.Post("/new", bindIgnErr(auth.AuthenticationForm{}), admin.NewAuthSourcePost) | |||
| r.Get("/:authid", admin.EditAuthSource) | |||
| r.Post("/:authid", bindIgnErr(auth.AuthenticationForm{}), admin.EditAuthSourcePost) | |||
| r.Post("/:authid/delete", admin.DeleteAuthSource) | |||
| }) | |||
| }, adminReq) | |||
| m.Get("/:username", ignSignIn, user.Profile) | |||
| @@ -80,6 +80,7 @@ SSHTitle = SSH key name | |||
| HttpsUrl = HTTPS URL | |||
| PayloadUrl = Payload URL | |||
| TeamName = Team name | |||
| AuthName = Authorization name | |||
| require_error = ` cannot be empty.` | |||
| alpha_dash_error = ` must be valid alpha or numeric or dash(-_) characters.` | |||
| @@ -115,6 +116,8 @@ auth_failed = Authentication failed: %v | |||
| still_own_repo = Your account still have ownership of repository, you have to delete or transfer them first. | |||
| org_still_own_repo = This organization still have ownership of repository, you have to delete or transfer them first. | |||
| still_own_user = This authentication still has used by some users, you should move them and then delete again. | |||
| [settings] | |||
| profile = Profile | |||
| password = Password | |||
| @@ -300,6 +303,8 @@ repositories = Repositories | |||
| authentication = Authentications | |||
| config = Configuration | |||
| monitor = Monitoring | |||
| prev = Prev. | |||
| next = Next | |||
| dashboard.statistic = Statistic | |||
| dashboard.operations = Operations | |||
| @@ -343,15 +348,14 @@ dashboard.gc_times = GC Times | |||
| users.user_manage_panel = User Manage Panel | |||
| users.new_account = Create New Account | |||
| users.name = Name | |||
| users.email = E-mail | |||
| users.activated = Activated | |||
| users.admin = Admin | |||
| users.repos = Repos | |||
| users.created = Created | |||
| users.edit = Edit | |||
| users.auth_source = Auth Source | |||
| users.auth_source = Authorization Source | |||
| users.local = Local | |||
| users.auth_login_name = Auth Login Name | |||
| users.auth_login_name = Authorization Login Name | |||
| users.update_profile_success = Account profile has been successfully updated. | |||
| users.edit_account = Edit Account | |||
| users.is_activated = This account is activated | |||
| @@ -360,6 +364,46 @@ users.update_profile = Update Account Profile | |||
| users.delete_account = Delete This Account | |||
| users.still_own_repo = This account still have ownership of repository, you have to delete or transfer them first. | |||
| orgs.org_manage_panel = Organization Manage Panel | |||
| orgs.name = Name | |||
| orgs.teams = Teams | |||
| orgs.members = Members | |||
| repos.repo_manage_panel = Repository Manage Panel | |||
| repos.owner = Owner | |||
| repos.name = Name | |||
| repos.private = Private | |||
| repos.watches = Watches | |||
| repos.stars = Stars | |||
| repos.issues = Issues | |||
| auths.auth_manage_panel = Authorization Manage Panel | |||
| auths.new = Add New Authorization Source | |||
| auths.name = Name | |||
| auths.type = Type | |||
| auths.enabled = Enabled | |||
| auths.updated = Updated | |||
| auths.auth_type = Authorization Type | |||
| auths.auth_name = Authorization Name | |||
| auths.domain = Domain | |||
| auths.host = Host | |||
| auths.port = Port | |||
| auths.base_dn = Base DN | |||
| auths.attributes = Search Attributes | |||
| auths.filter = Search Filter | |||
| auths.ms_ad_sa = Ms Ad SA | |||
| auths.smtp_auth = SMTP Authorization Type | |||
| auths.smtphost = SMTP Host | |||
| auths.smtpport = SMTP Port | |||
| auths.enable_tls = Enable TLS Encryption | |||
| auths.enable_auto_register = Enable Auto Registration | |||
| auths.tips = Tips | |||
| auths.edit = Edit Authorization Setting | |||
| auths.activated = This authentication has activated | |||
| auths.update_success = Authorization setting has been successfully updated. | |||
| auths.update = Update Authorization Setting | |||
| auths.delete = Delete This Authorization | |||
| [action] | |||
| create_repo = created repository <a href="/%s">%s</a> | |||
| commit_repo = pushed to <a href="/%s/src/%s">%s</a> at <a href="/%s">%s</a> | |||
| @@ -80,6 +80,7 @@ SSHTitle = SSH 密钥名称 | |||
| HttpsUrl = HTTPS URL 地址 | |||
| PayloadUrl = 推送地址 | |||
| TeamName = 团队名称 | |||
| AuthName = 认证名称 | |||
| require_error = 不能为空。 | |||
| alpha_dash_error = 必须为英文字母、阿拉伯数字或横线(-_)。 | |||
| @@ -115,6 +116,8 @@ auth_failed = 授权验证失败:%v | |||
| still_own_repo = 您的帐户仍然是某些仓库的拥有者,您必须先转移或删除它们才能执行删除帐户操作! | |||
| org_still_own_repo = 该组织仍然是某些仓库的拥有者,您必须先转移或删除它们才能执行删除组织操作! | |||
| still_own_user = 该授权认证依旧被部分用户使用,请先删除该部分用户后再试! | |||
| [settings] | |||
| profile = 个人信息 | |||
| password = 修改密码 | |||
| @@ -129,7 +132,7 @@ full_name = 自定义名称 | |||
| website = 个人网站 | |||
| location = 所在地区 | |||
| update_profile = 更新信息 | |||
| update_profile_success = 您的个人信息已经更新成功! | |||
| update_profile_success = 您的个人信息更新成功! | |||
| change_password = 修改密码 | |||
| old_password = 当前密码 | |||
| @@ -284,7 +287,7 @@ teams.members = 团队成员 | |||
| teams.update_settings = 更新团队设置 | |||
| teams.delete_team = 删除当前团队 | |||
| teams.add_team_member = 添加团队成员 | |||
| teams.delete_team_success = 指定团队已经被成功删除! | |||
| teams.delete_team_success = 指定团队删除成功! | |||
| teams.read_permission_desc = 该团队拥有对所属仓库的 <strong>读取</strong> 权限,团队成员可以进行查看和克隆等只读操作。 | |||
| teams.write_permission_desc = 该团队拥有对所属仓库的 <strong>读取</strong> 和 <strong>写入</strong> 的权限。 | |||
| teams.admin_permission_desc = 该团队拥有一定的 <strong>管理</strong> 权限,团队成员可以读取、克隆、推送以及添加其它仓库协作者。 | |||
| @@ -297,9 +300,11 @@ dashboard = 控制面板 | |||
| users = 用户管理 | |||
| organizations = 组织管理 | |||
| repositories = 仓库管理 | |||
| authentication = 权限认证管理 | |||
| authentication = 授权认证管理 | |||
| config = 应用配置管理 | |||
| monitor = 应用监控面板 | |||
| prev = 上一页 | |||
| next = 下一页 | |||
| dashboard.statistic = 应用统计数据 | |||
| dashboard.operations = 管理员操作 | |||
| @@ -343,7 +348,6 @@ dashboard.gc_times = GC 执行次数 | |||
| users.user_manage_panel = 用户管理面板 | |||
| users.new_account = 创建新的帐户 | |||
| users.name = 用户名 | |||
| users.email = 邮箱 | |||
| users.activated = 已激活 | |||
| users.admin = 管理员 | |||
| users.repos = 仓库数 | |||
| @@ -352,13 +356,53 @@ users.edit = 编辑 | |||
| users.auth_source = 认证源 | |||
| users.local = 本地 | |||
| users.auth_login_name = 认证登录名 | |||
| users.update_profile_success = 该用户信息已经更新成功! | |||
| users.update_profile_success = 该用户信息更新成功! | |||
| users.edit_account = 编辑用户信息 | |||
| users.is_activated = 该用户已被激活 | |||
| users.is_admin = 该用户具有管理员权限 | |||
| users.update_profile = 更新用户信息 | |||
| users.delete_account = 删除该用户 | |||
| orgs.org_manage_panel = 组织管理面板 | |||
| orgs.name = 组织名称 | |||
| orgs.teams = 团队数 | |||
| orgs.members = 成员数 | |||
| repos.repo_manage_panel = 仓库管理界面 | |||
| repos.owner = 所有者 | |||
| repos.name = 仓库名称 | |||
| repos.private = 私有库 | |||
| repos.watches = 关注数 | |||
| repos.stars = 点赞数 | |||
| repos.issues = 工单数 | |||
| auths.auth_manage_panel = 授权认证管理面板 | |||
| auths.new = 添加新的认证源 | |||
| auths.name = 认证名称 | |||
| auths.type = 认证类型 | |||
| auths.enabled = 已启用 | |||
| auths.updated = 最后更新时间 | |||
| auths.auth_type = 授权类型 | |||
| auths.auth_name = 授权名称 | |||
| auths.domain = 域名 | |||
| auths.host = 主机地址 | |||
| auths.port = 主机端口 | |||
| auths.base_dn = Base DN | |||
| auths.attributes = Search Attributes | |||
| auths.filter = Search Filter | |||
| auths.ms_ad_sa = Ms Ad SA | |||
| auths.smtp_auth = SMTP 授权类型 | |||
| auths.smtphost = SMTP 主机地址 | |||
| auths.smtpport = SMTP 主机端口 | |||
| auths.enable_tls = 启用 TLS 加密 | |||
| auths.enable_auto_register = 允许授权用户自动注册 | |||
| auths.tips = 帮助提示 | |||
| auths.edit = 修改授权认证设置 | |||
| auths.activated = 该授权认证已经启用 | |||
| auths.update_success = 授权认证设置更新成功! | |||
| auths.update = 更新授权认证信息 | |||
| auths.delete = 删除该授权认证 | |||
| [action] | |||
| create_repo = 创建了仓库 <a href="/%s">%s</a> | |||
| commit_repo = 推送了 <a href="/%s/src/%s">%s</a> 分支的代码到 <a href="/%s">%s</a> | |||
| @@ -17,7 +17,7 @@ import ( | |||
| "github.com/gogits/gogs/modules/setting" | |||
| ) | |||
| const APP_VER = "0.4.7.0829 Alpha" | |||
| const APP_VER = "0.4.8.0829 Alpha" | |||
| func init() { | |||
| runtime.GOMAXPROCS(runtime.NumCPU()) | |||
| @@ -165,6 +165,13 @@ func CountOrganizations() int64 { | |||
| return count | |||
| } | |||
| // GetOrganizations returns given number of organizations with offset. | |||
| func GetOrganizations(num, offset int) ([]*User, error) { | |||
| orgs := make([]*User, 0, num) | |||
| err := x.Limit(num, offset).Where("type=1").Asc("id").Find(&orgs) | |||
| return orgs, err | |||
| } | |||
| // TODO: need some kind of mechanism to record failure. | |||
| // DeleteOrganization completely and permanently deletes everything of organization. | |||
| func DeleteOrganization(org *User) (err error) { | |||
| @@ -248,8 +248,8 @@ func CountUsers() int64 { | |||
| } | |||
| // GetUsers returns given number of user objects with offset. | |||
| func GetUsers(num, offset int) ([]User, error) { | |||
| users := make([]User, 0, num) | |||
| func GetUsers(num, offset int) ([]*User, error) { | |||
| users := make([]*User, 0, num) | |||
| err := x.Limit(num, offset).Where("type=0").Asc("id").Find(&users) | |||
| return users, err | |||
| } | |||
| @@ -1400,31 +1400,37 @@ The register and sign-in page style | |||
| .setting-content { | |||
| margin-left: 32px; | |||
| } | |||
| #auth-setting-form, | |||
| #org-setting-form, | |||
| #repo-setting-form, | |||
| #user-profile-form { | |||
| background-color: #FFF; | |||
| padding: 30px 0; | |||
| } | |||
| #auth-setting-form textarea, | |||
| #org-setting-form textarea, | |||
| #repo-setting-form textarea, | |||
| #user-profile-form textarea { | |||
| margin-left: 4px; | |||
| height: 100px; | |||
| } | |||
| #auth-setting-form label, | |||
| #org-setting-form label, | |||
| #repo-setting-form label, | |||
| #user-profile-form label, | |||
| #auth-setting-form .form-label, | |||
| #org-setting-form .form-label, | |||
| #repo-setting-form .form-label, | |||
| #user-profile-form .form-label { | |||
| width: 240px; | |||
| } | |||
| #auth-setting-form .ipt, | |||
| #org-setting-form .ipt, | |||
| #repo-setting-form .ipt, | |||
| #user-profile-form .ipt { | |||
| width: 360px; | |||
| } | |||
| #auth-setting-form .field, | |||
| #org-setting-form .field, | |||
| #repo-setting-form .field, | |||
| #user-profile-form .field { | |||
| @@ -429,13 +429,13 @@ function initTeamRepositoriesList() { | |||
| function initAdmin() { | |||
| // Create account. | |||
| $('#login-type').on("change",function(){ | |||
| $('#login-type').on("change", function () { | |||
| var v = $(this).val(); | |||
| if(v.indexOf("0-")+1){ | |||
| if (v.indexOf("0-") + 1) { | |||
| $('.auth-name').toggleHide(); | |||
| $(".pwd").find("input").attr("required","required") | |||
| $(".pwd").find("input").attr("required", "required") | |||
| .end().toggleShow(); | |||
| }else{ | |||
| } else { | |||
| $(".pwd").find("input").removeAttr("required") | |||
| .end().toggleHide(); | |||
| $('.auth-name').toggleShow(); | |||
| @@ -450,6 +450,27 @@ function initAdmin() { | |||
| var $form = $('user-profile-form'); | |||
| $form.attr('action', $form.data('delete-url')); | |||
| }); | |||
| // Create authorization. | |||
| $('#auth-type').on("change", function () { | |||
| var v = $(this).val(); | |||
| if (v == 2) { | |||
| $('.ldap').toggleShow(); | |||
| $('.smtp').toggleHide(); | |||
| } | |||
| if (v == 3) { | |||
| $('.smtp').toggleShow(); | |||
| $('.ldap').toggleHide(); | |||
| } | |||
| }); | |||
| // Delete authorization. | |||
| $('#auth-delete').click(function (e) { | |||
| if (!confirm('This authorization is going to be deleted, do you want to continue?')) { | |||
| e.preventDefault(); | |||
| return true; | |||
| } | |||
| var $form = $('auth-setting-form'); | |||
| $form.attr('action', $form.data('delete-url')); | |||
| }); | |||
| } | |||
| $(document).ready(function () { | |||
| @@ -31,6 +31,7 @@ | |||
| margin-left: 32px; | |||
| } | |||
| #auth-setting-form, | |||
| #org-setting-form, | |||
| #repo-setting-form, | |||
| #user-profile-form { | |||
| @@ -23,8 +23,6 @@ import ( | |||
| const ( | |||
| DASHBOARD base.TplName = "admin/dashboard" | |||
| REPOS base.TplName = "admin/repos" | |||
| AUTHS base.TplName = "admin/auths" | |||
| CONFIG base.TplName = "admin/config" | |||
| MONITOR_PROCESS base.TplName = "admin/monitor/process" | |||
| MONITOR_CRON base.TplName = "admin/monitor/cron" | |||
| @@ -156,48 +154,6 @@ func Dashboard(ctx *middleware.Context) { | |||
| ctx.HTML(200, DASHBOARD) | |||
| } | |||
| func Repositories(ctx *middleware.Context) { | |||
| ctx.Data["Title"] = "Repository Management" | |||
| ctx.Data["PageIsRepos"] = true | |||
| p := com.StrTo(ctx.Query("p")).MustInt() | |||
| if p < 1 { | |||
| p = 1 | |||
| } | |||
| pageNum := 50 | |||
| count := models.CountRepositories() | |||
| curCount := int64((p-1)*pageNum + pageNum) | |||
| if curCount > count { | |||
| p = int(count) / pageNum | |||
| } else if count > curCount { | |||
| ctx.Data["NextPageNum"] = p + 1 | |||
| } | |||
| if p > 1 { | |||
| ctx.Data["LastPageNum"] = p - 1 | |||
| } | |||
| var err error | |||
| ctx.Data["Repos"], err = models.GetRepositoriesWithUsers(pageNum, (p-1)*pageNum) | |||
| if err != nil { | |||
| ctx.Handle(500, "admin.Repositories", err) | |||
| return | |||
| } | |||
| ctx.HTML(200, REPOS) | |||
| } | |||
| func Auths(ctx *middleware.Context) { | |||
| ctx.Data["Title"] = "Auth Sources" | |||
| ctx.Data["PageIsAuths"] = true | |||
| var err error | |||
| ctx.Data["Sources"], err = models.GetAuths() | |||
| if err != nil { | |||
| ctx.Handle(500, "admin.Auths", err) | |||
| return | |||
| } | |||
| ctx.HTML(200, AUTHS) | |||
| } | |||
| func Config(ctx *middleware.Context) { | |||
| ctx.Data["Title"] = "Server Configuration" | |||
| ctx.Data["PageIsConfig"] = true | |||
| @@ -5,8 +5,6 @@ | |||
| package admin | |||
| import ( | |||
| "strings" | |||
| "github.com/Unknwon/com" | |||
| "github.com/go-xorm/core" | |||
| @@ -19,21 +17,38 @@ import ( | |||
| ) | |||
| const ( | |||
| AUTHS base.TplName = "admin/auth/list" | |||
| AUTH_NEW base.TplName = "admin/auth/new" | |||
| AUTH_EDIT base.TplName = "admin/auth/edit" | |||
| ) | |||
| func Authentications(ctx *middleware.Context) { | |||
| ctx.Data["Title"] = ctx.Tr("admin.authentication") | |||
| ctx.Data["PageIsAdmin"] = true | |||
| ctx.Data["PageIsAdminAuthentications"] = true | |||
| var err error | |||
| ctx.Data["Sources"], err = models.GetAuths() | |||
| if err != nil { | |||
| ctx.Handle(500, "GetAuths", err) | |||
| return | |||
| } | |||
| ctx.HTML(200, AUTHS) | |||
| } | |||
| func NewAuthSource(ctx *middleware.Context) { | |||
| ctx.Data["Title"] = "New Authentication" | |||
| ctx.Data["PageIsAuths"] = true | |||
| ctx.Data["Title"] = ctx.Tr("admin.auths.new") | |||
| ctx.Data["PageIsAdmin"] = true | |||
| ctx.Data["PageIsAdminAuthentications"] = true | |||
| ctx.Data["LoginTypes"] = models.LoginTypes | |||
| ctx.Data["SMTPAuths"] = models.SMTPAuths | |||
| ctx.HTML(200, AUTH_NEW) | |||
| } | |||
| func NewAuthSourcePost(ctx *middleware.Context, form auth.AuthenticationForm) { | |||
| ctx.Data["Title"] = "New Authentication" | |||
| ctx.Data["PageIsAuths"] = true | |||
| ctx.Data["Title"] = ctx.Tr("admin.auths.new") | |||
| ctx.Data["PageIsAdmin"] = true | |||
| ctx.Data["PageIsAdminAuthentications"] = true | |||
| ctx.Data["LoginTypes"] = models.LoginTypes | |||
| ctx.Data["SMTPAuths"] = models.SMTPAuths | |||
| @@ -79,30 +94,29 @@ func NewAuthSourcePost(ctx *middleware.Context, form auth.AuthenticationForm) { | |||
| } | |||
| if err := models.CreateSource(source); err != nil { | |||
| ctx.Handle(500, "admin.auths.NewAuth(CreateSource)", err) | |||
| ctx.Handle(500, "CreateSource", err) | |||
| return | |||
| } | |||
| log.Trace("%s Authentication created by admin(%s): %s", ctx.Req.RequestURI, | |||
| ctx.User.LowerName, strings.ToLower(form.AuthName)) | |||
| log.Trace("Authentication created by admin(%s): %s", ctx.User.Name, form.AuthName) | |||
| ctx.Redirect("/admin/auths") | |||
| } | |||
| func EditAuthSource(ctx *middleware.Context) { | |||
| ctx.Data["Title"] = "Edit Authentication" | |||
| ctx.Data["PageIsAuths"] = true | |||
| ctx.Data["Title"] = ctx.Tr("admin.auths.edit") | |||
| ctx.Data["PageIsAdmin"] = true | |||
| ctx.Data["PageIsAdminAuthentications"] = true | |||
| ctx.Data["LoginTypes"] = models.LoginTypes | |||
| ctx.Data["SMTPAuths"] = models.SMTPAuths | |||
| id, err := com.StrTo(ctx.Params(":authid")).Int64() | |||
| if err != nil { | |||
| ctx.Handle(404, "admin.auths.EditAuthSource", err) | |||
| id := com.StrTo(ctx.Params(":authid")).MustInt64() | |||
| if id == 0 { | |||
| ctx.Handle(404, "EditAuthSource", nil) | |||
| return | |||
| } | |||
| u, err := models.GetLoginSourceById(id) | |||
| if err != nil { | |||
| ctx.Handle(500, "admin.user.EditUser(GetLoginSourceById)", err) | |||
| ctx.Handle(500, "GetLoginSourceById", err) | |||
| return | |||
| } | |||
| ctx.Data["Source"] = u | |||
| @@ -110,7 +124,9 @@ func EditAuthSource(ctx *middleware.Context) { | |||
| } | |||
| func EditAuthSourcePost(ctx *middleware.Context, form auth.AuthenticationForm) { | |||
| ctx.Data["Title"] = "Edit Authentication" | |||
| ctx.Data["Title"] = ctx.Tr("admin.auths.edit") | |||
| ctx.Data["PageIsAdmin"] = true | |||
| ctx.Data["PageIsAdminAuthentications"] = true | |||
| ctx.Data["PageIsAuths"] = true | |||
| ctx.Data["LoginTypes"] = models.LoginTypes | |||
| ctx.Data["SMTPAuths"] = models.SMTPAuths | |||
| @@ -158,44 +174,38 @@ func EditAuthSourcePost(ctx *middleware.Context, form auth.AuthenticationForm) { | |||
| } | |||
| if err := models.UpdateSource(&u); err != nil { | |||
| ctx.Handle(500, "admin.auths.EditAuth(UpdateSource)", err) | |||
| ctx.Handle(500, "UpdateSource", err) | |||
| return | |||
| } | |||
| log.Trace("%s Authentication changed by admin(%s): %s", ctx.Req.RequestURI, | |||
| ctx.User.LowerName, form.AuthName) | |||
| ctx.Redirect("/admin/auths") | |||
| log.Trace("Authentication changed by admin(%s): %s", ctx.User.Name, form.AuthName) | |||
| ctx.Flash.Success(ctx.Tr("admin.auths.update_success")) | |||
| ctx.Redirect("/admin/auths/" + ctx.Params(":authid")) | |||
| } | |||
| func DeleteAuthSource(ctx *middleware.Context) { | |||
| ctx.Data["Title"] = "Delete Authentication" | |||
| ctx.Data["PageIsAuths"] = true | |||
| id, err := com.StrTo(ctx.Params(":authid")).Int64() | |||
| if err != nil { | |||
| ctx.Handle(404, "admin.auths.DeleteAuth", err) | |||
| id := com.StrTo(ctx.Params(":authid")).MustInt64() | |||
| if id == 0 { | |||
| ctx.Handle(404, "DeleteAuthSource", nil) | |||
| return | |||
| } | |||
| a, err := models.GetLoginSourceById(id) | |||
| if err != nil { | |||
| ctx.Handle(500, "admin.auths.DeleteAuth(GetLoginSourceById)", err) | |||
| ctx.Handle(500, "GetLoginSourceById", err) | |||
| return | |||
| } | |||
| if err = models.DelLoginSource(a); err != nil { | |||
| switch err { | |||
| case models.ErrAuthenticationUserUsed: | |||
| ctx.Flash.Error("This authentication still has used by some users, you should move them and then delete again.") | |||
| ctx.Flash.Error("form.still_own_user") | |||
| ctx.Redirect("/admin/auths/" + ctx.Params(":authid")) | |||
| default: | |||
| ctx.Handle(500, "admin.auths.DeleteAuth(DelLoginSource)", err) | |||
| ctx.Handle(500, "DelLoginSource", err) | |||
| } | |||
| return | |||
| } | |||
| log.Trace("%s Authentication deleted by admin(%s): %s", ctx.Req.RequestURI, | |||
| ctx.User.LowerName, ctx.User.LowerName) | |||
| log.Trace("Authentication deleted by admin(%s): %s", ctx.User.Name, a.Name) | |||
| ctx.Redirect("/admin/auths") | |||
| } | |||
| @@ -0,0 +1,32 @@ | |||
| // Copyright 2014 The Gogs 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 admin | |||
| import ( | |||
| "github.com/gogits/gogs/models" | |||
| "github.com/gogits/gogs/modules/base" | |||
| "github.com/gogits/gogs/modules/middleware" | |||
| ) | |||
| const ( | |||
| ORGS base.TplName = "admin/org/list" | |||
| ) | |||
| func Organizations(ctx *middleware.Context) { | |||
| ctx.Data["Title"] = ctx.Tr("admin.orgs") | |||
| ctx.Data["PageIsAdmin"] = true | |||
| ctx.Data["PageIsAdminOrganizations"] = true | |||
| pageNum := 50 | |||
| p := pagination(ctx, models.CountOrganizations(), pageNum) | |||
| var err error | |||
| ctx.Data["Orgs"], err = models.GetOrganizations(pageNum, (p-1)*pageNum) | |||
| if err != nil { | |||
| ctx.Handle(500, "GetUsers", err) | |||
| return | |||
| } | |||
| ctx.HTML(200, ORGS) | |||
| } | |||
| @@ -0,0 +1,32 @@ | |||
| // Copyright 2014 The Gogs 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 admin | |||
| import ( | |||
| "github.com/gogits/gogs/models" | |||
| "github.com/gogits/gogs/modules/base" | |||
| "github.com/gogits/gogs/modules/middleware" | |||
| ) | |||
| const ( | |||
| REPOS base.TplName = "admin/repo/list" | |||
| ) | |||
| func Repositories(ctx *middleware.Context) { | |||
| ctx.Data["Title"] = ctx.Tr("admin.repositories") | |||
| ctx.Data["PageIsAdmin"] = true | |||
| ctx.Data["PageIsAdminRepositories"] = true | |||
| pageNum := 50 | |||
| p := pagination(ctx, models.CountRepositories(), pageNum) | |||
| var err error | |||
| ctx.Data["Repos"], err = models.GetRepositoriesWithUsers(pageNum, (p-1)*pageNum) | |||
| if err != nil { | |||
| ctx.Handle(500, "GetRepositoriesWithUsers", err) | |||
| return | |||
| } | |||
| ctx.HTML(200, REPOS) | |||
| } | |||
| @@ -22,17 +22,11 @@ const ( | |||
| USER_EDIT base.TplName = "admin/user/edit" | |||
| ) | |||
| func Users(ctx *middleware.Context) { | |||
| ctx.Data["Title"] = ctx.Tr("admin.users") | |||
| ctx.Data["PageIsAdmin"] = true | |||
| ctx.Data["PageIsAdminUsers"] = true | |||
| func pagination(ctx *middleware.Context, count int64, pageNum int) int { | |||
| p := com.StrTo(ctx.Query("p")).MustInt() | |||
| if p < 1 { | |||
| p = 1 | |||
| } | |||
| pageNum := 50 | |||
| count := models.CountUsers() | |||
| curCount := int64((p-1)*pageNum + pageNum) | |||
| if curCount > count { | |||
| p = int(count) / pageNum | |||
| @@ -42,11 +36,21 @@ func Users(ctx *middleware.Context) { | |||
| if p > 1 { | |||
| ctx.Data["LastPageNum"] = p - 1 | |||
| } | |||
| return p | |||
| } | |||
| func Users(ctx *middleware.Context) { | |||
| ctx.Data["Title"] = ctx.Tr("admin.users") | |||
| ctx.Data["PageIsAdmin"] = true | |||
| ctx.Data["PageIsAdminUsers"] = true | |||
| pageNum := 50 | |||
| p := pagination(ctx, models.CountUsers(), pageNum) | |||
| var err error | |||
| ctx.Data["Users"], err = models.GetUsers(pageNum, (p-1)*pageNum) | |||
| if err != nil { | |||
| ctx.Handle(500, "admin.Users(GetUsers)", err) | |||
| ctx.Handle(500, "GetUsers", err) | |||
| return | |||
| } | |||
| ctx.HTML(200, USERS) | |||
| @@ -1 +1 @@ | |||
| 0.4.7.0829 Alpha | |||
| 0.4.8.0829 Alpha | |||
| @@ -1,165 +1,113 @@ | |||
| {{template "base/head" .}} | |||
| {{template "base/navbar" .}} | |||
| <div id="body" class="container" data-page="admin"> | |||
| {{template "admin/nav" .}} | |||
| <div id="admin-container" class="col-md-9"> | |||
| <div class="panel panel-default"> | |||
| <div class="panel-heading"> | |||
| Edit Authentication | |||
| </div> | |||
| <div class="panel-body"> | |||
| <br/> | |||
| <form action="/admin/auths/{{.Source.Id}}" method="post" class="form-horizontal"> | |||
| {{.CsrfTokenHtml}} | |||
| {{template "base/alert" .}} | |||
| <input type="hidden" value="{{.Source.Id}}" name="id"/> | |||
| {{$type := .Source.Type}} | |||
| <div class="form-group"> | |||
| <label class="col-md-3 control-label">Auth Type: </label> | |||
| <input type="hidden" name="type" value="{{.Source.Type}}"/> | |||
| <label class="control-label"> | |||
| {{range $key, $val := .LoginTypes}} | |||
| {{if eq $key $type}}{{$val}}{{end}} | |||
| {{end}} | |||
| </label> | |||
| </div> | |||
| <div class="form-group {{if .Err_AuthName}}has-error has-feedback{{end}}"> | |||
| <label class="col-md-3 control-label">Name: </label> | |||
| <div class="col-md-7"> | |||
| <input name="name" class="form-control" placeholder="Type authentication's name" value="{{.Source.Name}}" required="required"> | |||
| </div> | |||
| </div> | |||
| {{if eq $type 2}} | |||
| <div class="form-group {{if .Err_Domain}}has-error has-feedback{{end}}"> | |||
| <label class="col-md-3 control-label">Domain: </label> | |||
| <div class="col-md-7"> | |||
| <input name="domain" class="form-control" placeholder="Type domain name" value="{{.Source.LDAP.Name}}" required="required"> | |||
| </div> | |||
| </div> | |||
| <div class="form-group {{if .Err_Host}}has-error has-feedback{{end}}"> | |||
| <label class="col-md-3 control-label">Host: </label> | |||
| <div class="col-md-7"> | |||
| <input name="host" class="form-control" placeholder="Type host address" value="{{.Source.LDAP.Host}}" required="required"> | |||
| </div> | |||
| </div> | |||
| <div class="form-group {{if .Err_Port}}has-error has-feedback{{end}}"> | |||
| <label class="col-md-3 control-label">Port: </label> | |||
| <div class="col-md-7"> | |||
| <input name="port" class="form-control" placeholder="Type port number" value="{{.Source.LDAP.Port}}" required="required"> | |||
| </div> | |||
| </div> | |||
| <div class="form-group {{if .Err_UseSSL}}has-error has-feedback{{end}}"> | |||
| <label class="col-md-3 control-label">Use SSL: </label> | |||
| <div class="col-md-7"> | |||
| <input name="usessl" class="form-control" type="checkbox" {{if .Source.LDAP.UseSSL}}checked{{end}}> | |||
| </div> | |||
| </div> | |||
| <div class="form-group {{if .Err_BaseDN}}has-error has-feedback{{end}}"> | |||
| <label class="col-md-3 control-label">Base DN: </label> | |||
| <div class="col-md-7"> | |||
| <input name="base_dn" class="form-control" placeholder="Type base DN" value="{{.Source.LDAP.BaseDN}}" required="required"> | |||
| </div> | |||
| </div> | |||
| <div class="form-group {{if .Err_Attributes}}has-error has-feedback{{end}}"> | |||
| <label class="col-md-3 control-label">Search Attributes: </label> | |||
| <div class="col-md-7"> | |||
| <input name="attributes" class="form-control" placeholder="Type search attributes" value="{{.Source.LDAP.Attributes}}"> | |||
| </div> | |||
| </div> | |||
| <div class="form-group {{if .Err_Filter}}has-error has-feedback{{end}}"> | |||
| <label class="col-md-3 control-label">Search Filter: </label> | |||
| <div class="col-md-7"> | |||
| <input name="filter" class="form-control" placeholder="Type search filter" value="{{.Source.LDAP.Filter}}"> | |||
| </div> | |||
| </div> | |||
| <div class="form-group {{if .Err_MsAdSA}}has-error has-feedback{{end}}"> | |||
| <label class="col-md-3 control-label">Ms Ad SA: </label> | |||
| <div class="col-md-7"> | |||
| <input name="ms_ad_sa" class="form-control" placeholder="Type Ms Ad SA" value="{{.Source.LDAP.MsAdSAFormat}}"> | |||
| </div> | |||
| </div> | |||
| {{else if eq $type 3}} | |||
| <div class="form-group {{if .Err_TLS}}has-error has-feedback{{end}}"> | |||
| <label class="col-md-3 control-label">SMTP Auth: </label> | |||
| <div class="col-md-7"> | |||
| <select name="smtpauth" class="form-control"> | |||
| {{$auth := .Source.SMTP.Auth}} | |||
| {{range .SMTPAuths}} | |||
| <option value="{{.}}" | |||
| {{if eq . $auth}} selected{{end}}>{{.}}</option> | |||
| {{end}} | |||
| </select> | |||
| </div> | |||
| </div> | |||
| <div class="form-group {{if .Err_SmtpHost}}has-error has-feedback{{end}}"> | |||
| <label class="col-md-3 control-label">Host: </label> | |||
| <div class="col-md-7"> | |||
| <input name="smtphost" class="form-control" placeholder="Type host address" value="{{.Source.SMTP.Host}}"> | |||
| </div> | |||
| </div> | |||
| <div class="form-group {{if .Err_SmtpPort}}has-error has-feedback{{end}}"> | |||
| <label class="col-md-3 control-label">Port: </label> | |||
| <div class="col-md-7"> | |||
| <input name="smtpport" class="form-control" placeholder="Type port number" value="{{.Source.SMTP.Port}}"> | |||
| </div> | |||
| </div> | |||
| {{end}} | |||
| <div class="form-group"> | |||
| {{if eq $type 3}} | |||
| <div class="col-md-offset-3 col-md-7"> | |||
| <div class="checkbox"> | |||
| <label> | |||
| <input name="tls" type="checkbox" class="form-control" {{if .Source.SMTP.TLS}}checked{{end}}> | |||
| <strong>Enable TLS Encryption</strong> | |||
| </label> | |||
| {{template "ng/base/head" .}} | |||
| {{template "ng/base/header" .}} | |||
| <div id="admin-wrapper"> | |||
| <div id="setting-wrapper" class="main-wrapper"> | |||
| <div id="admin-setting" class="container clear"> | |||
| {{template "admin/nav" .}} | |||
| <div class="grid-4-5 left"> | |||
| <div class="setting-content"> | |||
| {{template "ng/base/alert" .}} | |||
| <div id="setting-content"> | |||
| <div class="panel panel-radius"> | |||
| <div class="panel-header"> | |||
| <strong>{{.i18n.Tr "admin.auths.edit"}}</strong> | |||
| </div> | |||
| </div> | |||
| {{end}} | |||
| <form class="form form-align panel-body" id="auth-setting-form" action="/admin/auths/{{.Source.Id}}" data-delete-url="/admin/auths/{{.Source.Id}}/delete" method="post"> | |||
| {{.CsrfTokenHtml}} | |||
| <input type="hidden" value="{{.Source.Id}}" name="id"/> | |||
| {{$type := .Source.Type}} | |||
| <div class="field"> | |||
| <label>{{.i18n.Tr "admin.auths.auth_type"}}</label> | |||
| <input type="hidden" name="type" value="{{.Source.Type}}"/> | |||
| <label class="control-label"> | |||
| {{range $key, $val := .LoginTypes}} | |||
| {{if eq $key $type}}{{$val}}{{end}} | |||
| {{end}} | |||
| </label> | |||
| </div> | |||
| <div class="field"> | |||
| <label class="req" for="name">{{.i18n.Tr "admin.auths.auth_name"}}</label> | |||
| <input class="ipt ipt-large ipt-radius {{if .Err_AuthName}}ipt-error{{end}}" id="name" name="name" value="{{.Source.Name}}" required /> | |||
| </div> | |||
| {{if eq $type 2}} | |||
| <div class="field"> | |||
| <label class="req" for="domain">{{.i18n.Tr "admin.auths.domain"}}</label> | |||
| <input class="ipt ipt-large ipt-radius {{if .Err_Domain}}ipt-error{{end}}" id="domain" name="domain" value="{{.Source.LDAP.Name}}" required /> | |||
| </div> | |||
| <div class="field"> | |||
| <label class="req" for="host">{{.i18n.Tr "admin.auths.host"}}</label> | |||
| <input class="ipt ipt-large ipt-radius {{if .Err_Host}}ipt-error{{end}}" id="host" name="host" value="{{.Source.LDAP.Host}}" required /> | |||
| </div> | |||
| <div class="field"> | |||
| <label class="req" for="port">{{.i18n.Tr "admin.auths.port"}}</label> | |||
| <input class="ipt ipt-large ipt-radius {{if .Err_Port}}ipt-error{{end}}" id="port" name="port" value="{{.Source.LDAP.Port}}" required /> | |||
| </div> | |||
| <div class="field"> | |||
| <label class="req" for="base_dn">{{.i18n.Tr "admin.auths.base_dn"}}</label> | |||
| <input class="ipt ipt-large ipt-radius {{if .Err_BaseDN}}ipt-error{{end}}" id="base_dn" name="base_dn" value="{{.Source.LDAP.BaseDN}}" /> | |||
| </div> | |||
| <div class="field"> | |||
| <label class="req" for="attributes">{{.i18n.Tr "admin.auths.attributes"}}</label> | |||
| <input class="ipt ipt-large ipt-radius {{if .Err_Attributes}}ipt-error{{end}}" id="attributes" name="attributes" value="{{.Source.LDAP.Attributes}}" /> | |||
| </div> | |||
| <div class="field"> | |||
| <label class="req" for="filter">{{.i18n.Tr "admin.auths.filter"}}</label> | |||
| <input class="ipt ipt-large ipt-radius {{if .Err_Filter}}ipt-error{{end}}" id="filter" name="filter" value="{{.Source.LDAP.Filter}}" /> | |||
| </div> | |||
| <div class="field"> | |||
| <label class="req" for="ms_ad_sa">{{.i18n.Tr "admin.auths.ms_ad_sa"}}</label> | |||
| <input class="ipt ipt-large ipt-radius {{if .Err_MsAdSA}}ipt-error{{end}}" id="ms_ad_sa" name="ms_ad_sa" value="{{.Source.LDAP.MsAdSAFormat}}" /> | |||
| </div> | |||
| {{else if eq $type 3}} | |||
| <div class="field"> | |||
| <label class="req">{{.i18n.Tr "admin.auths.smtp_auth"}}</label> | |||
| <select name="smtpauth"> | |||
| {{$auth := .Source.SMTP.Auth}} | |||
| {{range .SMTPAuths}} | |||
| <option value="{{.}}" | |||
| {{if eq . $auth}} selected{{end}}>{{.}}</option> | |||
| {{end}} | |||
| </select> | |||
| </div> | |||
| <div class="field"> | |||
| <label class="req" for="smtphost">{{.i18n.Tr "admin.auths.smtphost"}}</label> | |||
| <input class="ipt ipt-large ipt-radius {{if .Err_SmtpHost}}ipt-error{{end}}" id="smtphost" name="smtphost" value="{{.Source.SMTP.Host}}" /> | |||
| </div> | |||
| <div class="field"> | |||
| <label class="req" for="smtpport">{{.i18n.Tr "admin.auths.smtpport"}}</label> | |||
| <input class="ipt ipt-large ipt-radius {{if .Err_SmtpPort}}ipt-error{{end}}" id="smtpport" name="smtpport" value="{{.Source.SMTP.Port}}" /> | |||
| </div> | |||
| {{end}} | |||
| <div class="col-md-offset-3 col-md-7"> | |||
| <div class="checkbox"> | |||
| <label> | |||
| <div class="field"> | |||
| {{if eq $type 3}} | |||
| <label></label> | |||
| <input name="tls" type="checkbox" {{if .Source.SMTP.TLS}}checked{{end}}> | |||
| <strong>{{.i18n.Tr "admin.auths.enable_tls"}}</strong> | |||
| <br> | |||
| {{end}} | |||
| <label></label> | |||
| <input name="allowautoregister" type="checkbox" {{if .Source.AllowAutoRegister}}checked{{end}}> | |||
| <strong>Enable Auto Registration</strong> | |||
| </label> | |||
| </div> | |||
| </div> | |||
| <div class="col-md-7 col-md-offset-3"> | |||
| <div class="checkbox"> | |||
| <label> | |||
| <input type="checkbox" name="is_actived" {{if .Source.IsActived}}checked{{end}}> | |||
| <strong>This authentication has activated.</strong> | |||
| </label> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| <hr/> | |||
| <div class="form-group"> | |||
| <div class="col-md-offset-3 col-md-6"> | |||
| <button type="submit" class="btn btn-lg btn-primary btn-block">Update authentication config</button> | |||
| <a type="button" href="/admin/auths/{{.Source.Id}}/delete" class="btn btn-lg btn-danger btn-block">Delete this authentication</a> | |||
| <strong>{{.i18n.Tr "admin.auths.enable_auto_register"}}</strong> | |||
| <br> | |||
| <label></label> | |||
| <input name="is_actived" type="checkbox" {{if .Source.IsActived}}checked{{end}}> | |||
| <strong>{{.i18n.Tr "admin.auths.activated"}}</strong> | |||
| </div> | |||
| <div class="field"> | |||
| <label></label> | |||
| <button class="btn btn-green btn-large btn-radius">{{.i18n.Tr "admin.auths.update"}}</button> | |||
| | |||
| <button class="btn btn-large btn-red btn-radius" id="auth-delete">{{.i18n.Tr "admin.auths.delete"}}</button> | |||
| </div> | |||
| </form> | |||
| </div> | |||
| </div> | |||
| </form> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| {{template "base/footer" .}} | |||
| {{template "ng/base/footer" .}} | |||
| @@ -0,0 +1,59 @@ | |||
| {{template "ng/base/head" .}} | |||
| {{template "ng/base/header" .}} | |||
| <div id="admin-wrapper"> | |||
| <div id="setting-wrapper" class="main-wrapper"> | |||
| <div id="admin-setting" class="container clear"> | |||
| {{template "admin/nav" .}} | |||
| <div class="grid-4-5 left"> | |||
| <div class="setting-content"> | |||
| {{template "ng/base/alert" .}} | |||
| <div id="setting-content"> | |||
| <div class="panel panel-radius"> | |||
| <div class="panel-header"> | |||
| <strong>{{.i18n.Tr "admin.auths.auth_manage_panel"}}</strong> | |||
| </div> | |||
| <div class="panel-body admin-panel"> | |||
| <a class="btn-blue btn-medium btn-link btn-radius" href="/admin/auths/new">{{.i18n.Tr "admin.auths.new"}}</a> | |||
| <div class="admin-table"> | |||
| <table class="table table-striped"> | |||
| <thead> | |||
| <tr> | |||
| <th>Id</th> | |||
| <th>{{.i18n.Tr "admin.auths.name"}}</th> | |||
| <th>{{.i18n.Tr "admin.auths.type"}}</th> | |||
| <th>{{.i18n.Tr "admin.auths.enabled"}}</th> | |||
| <th>{{.i18n.Tr "admin.auths.updated"}}</th> | |||
| <th>{{.i18n.Tr "admin.users.created"}}</th> | |||
| <th>{{.i18n.Tr "admin.users.edit"}}</th> | |||
| </tr> | |||
| </thead> | |||
| <tbody> | |||
| {{range .Sources}} | |||
| <tr> | |||
| <td>{{.Id}}</td> | |||
| <td><a href="/admin/auths/{{.Id}}">{{.Name}}</a></td> | |||
| <td>{{.TypeString}}</td> | |||
| <td><i class="fa fa{{if .IsActived}}-check{{end}}-square-o"></i></td> | |||
| <td>{{DateFormat .Updated "M d, Y"}}</td> | |||
| <td>{{DateFormat .Created "M d, Y"}}</td> | |||
| <td><a href="/admin/auths/{{.Id}}"><i class="fa fa-pencil-square-o"></i></a></td> | |||
| </tr> | |||
| {{end}} | |||
| </tbody> | |||
| </table> | |||
| {{if or .LastPageNum .NextPageNum}} | |||
| <ul class="pagination"> | |||
| {{if .LastPageNum}}<li><a class="btn btn-medium btn-gray btn-radius" href="/admin/auths?p={{.LastPageNum}}">« Prev.</a></li>{{end}} | |||
| {{if .NextPageNum}}<li><a class="btn btn-medium btn-gray btn-radius" href="/admin/auths?p={{.NextPageNum}}">» Next</a></li>{{end}} | |||
| </ul> | |||
| {{end}} | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| {{template "ng/base/footer" .}} | |||
| @@ -1,178 +1,110 @@ | |||
| {{template "base/head" .}} | |||
| {{template "base/navbar" .}} | |||
| <div id="body" class="container" data-page="admin"> | |||
| {{template "admin/nav" .}} | |||
| <div id="admin-container" class="col-md-9"> | |||
| <div class="panel panel-default"> | |||
| <div class="panel-heading"> | |||
| New Authentication | |||
| </div> | |||
| <div class="panel-body"> | |||
| <br/> | |||
| <form action="/admin/auths/new" method="post" class="form-horizontal"> | |||
| {{.CsrfTokenHtml}} | |||
| {{template "base/alert" .}} | |||
| <div class="form-group"> | |||
| <label class="col-md-3 control-label">Auth Type: </label> | |||
| <div class="col-md-7"> | |||
| <select name="type" class="form-control" id="auth-type"> | |||
| {{range $key, $val := .LoginTypes}} | |||
| <option value="{{$key}}">{{$val}}</option> | |||
| {{end}} | |||
| </select> | |||
| </div> | |||
| </div> | |||
| <div class="form-group {{if .Err_AuthName}}has-error has-feedback{{end}}"> | |||
| <label class="col-md-3 control-label">Name: </label> | |||
| <div class="col-md-7"> | |||
| <input name="name" class="form-control" placeholder="Type authentication's name" value="{{.name}}"> | |||
| </div> | |||
| </div> | |||
| <div class="ldap"> | |||
| <div class="form-group {{if .Err_Domain}}has-error has-feedback{{end}}"> | |||
| <label class="col-md-3 control-label">Domain: </label> | |||
| <div class="col-md-7"> | |||
| <input name="domain" class="form-control" placeholder="Type domain name" value="{{.domain}}"> | |||
| </div> | |||
| </div> | |||
| <div class="form-group {{if .Err_Host}}has-error has-feedback{{end}}"> | |||
| <label class="col-md-3 control-label">Host: </label> | |||
| <div class="col-md-7"> | |||
| <input name="host" class="form-control" placeholder="Type host address" value="{{.host}}"> | |||
| </div> | |||
| </div> | |||
| <div class="form-group {{if .Err_Port}}has-error has-feedback{{end}}"> | |||
| <label class="col-md-3 control-label">Port: </label> | |||
| <div class="col-md-7"> | |||
| <input name="port" class="form-control" placeholder="Type port number" value="{{.port}}"> | |||
| </div> | |||
| </div> | |||
| <div class="form-group {{if .Err_UseSSL}}has-error has-feedback{{end}}"> | |||
| <label class="col-md-3 control-label">Use SSL: </label> | |||
| <div class="col-md-7"> | |||
| <input name="usessl" class="form-control" type="checkbox" {{if .usessl}}checked{{end}}> | |||
| </div> | |||
| </div> | |||
| <div class="form-group {{if .Err_BaseDN}}has-error has-feedback{{end}}"> | |||
| <label class="col-md-3 control-label">Base DN: </label> | |||
| <div class="col-md-7"> | |||
| <input name="base_dn" class="form-control" placeholder="Type base DN" value="{{.base_dn}}"> | |||
| </div> | |||
| </div> | |||
| <div class="form-group {{if .Err_Attributes}}has-error has-feedback{{end}}"> | |||
| <label class="col-md-3 control-label">Search Attributes: </label> | |||
| <div class="col-md-7"> | |||
| <input name="attributes" class="form-control" placeholder="Type search attributes" value="{{.attributes}}"> | |||
| </div> | |||
| </div> | |||
| <div class="form-group {{if .Err_Filter}}has-error has-feedback{{end}}"> | |||
| <label class="col-md-3 control-label">Search Filter: </label> | |||
| <div class="col-md-7"> | |||
| <input name="filter" class="form-control" placeholder="Type search filter" value="{{.filter}}"> | |||
| </div> | |||
| </div> | |||
| <div class="form-group {{if .Err_MsAdSA}}has-error has-feedback{{end}}"> | |||
| <label class="col-md-3 control-label">Ms Ad SA: </label> | |||
| <div class="col-md-7"> | |||
| <input name="ms_ad_sa" class="form-control" placeholder="Type Ms Ad SA" value="{{.ms_ad_sa}}"> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| <div class="smtp hidden"> | |||
| <div class="form-group"> | |||
| <label class="col-md-3 control-label">SMTP Auth: </label> | |||
| <div class="col-md-7"> | |||
| <select name="smtpauth" class="form-control"> | |||
| {{range .SMTPAuths}} | |||
| <option value="{{.}}">{{.}}</option> | |||
| {{end}} | |||
| </select> | |||
| {{template "ng/base/head" .}} | |||
| {{template "ng/base/header" .}} | |||
| <div id="admin-wrapper"> | |||
| <div id="setting-wrapper" class="main-wrapper"> | |||
| <div id="admin-setting" class="container clear"> | |||
| {{template "admin/nav" .}} | |||
| <div class="grid-4-5 left"> | |||
| <div class="setting-content"> | |||
| {{template "ng/base/alert" .}} | |||
| <div id="setting-content"> | |||
| <div class="panel panel-radius"> | |||
| <div class="panel-header"> | |||
| <strong>{{.i18n.Tr "admin.auths.new"}}</strong> | |||
| </div> | |||
| </div> | |||
| <div class="form-group {{if .Err_SmtpHost}}has-error has-feedback{{end}}"> | |||
| <label class="col-md-3 control-label">Host: </label> | |||
| <div class="col-md-7"> | |||
| <input name="smtphost" class="form-control" placeholder="Type host address" value="{{.smtphost}}"> | |||
| </div> | |||
| </div> | |||
| <div class="form-group {{if .Err_SmtpPort}}has-error has-feedback{{end}}"> | |||
| <label class="col-md-3 control-label">Port: </label> | |||
| <div class="col-md-7"> | |||
| <input name="smtpport" class="form-control" placeholder="Type port number" value="{{.smtpport}}"> | |||
| </div> | |||
| </div> | |||
| <div class="form-group"> | |||
| <div class="col-md-offset-3 col-md-7"> | |||
| <div class="checkbox"> | |||
| <label> | |||
| <form class="form form-align panel-body" id="repo-setting-form" action="/admin/auths/new" method="post"> | |||
| {{.CsrfTokenHtml}} | |||
| <div class="field"> | |||
| <label class="req">{{.i18n.Tr "admin.auths.auth_type"}}</label> | |||
| <select id="auth-type" name="type"> | |||
| {{range $key, $val := .LoginTypes}} | |||
| <option value="{{$key}}">{{$val}}</option> | |||
| {{end}} | |||
| </select> | |||
| </div> | |||
| <div class="field"> | |||
| <label class="req" for="name">{{.i18n.Tr "admin.auths.auth_name"}}</label> | |||
| <input class="ipt ipt-large ipt-radius {{if .Err_AuthName}}ipt-error{{end}}" id="name" name="name" value="{{.name}}" required /> | |||
| </div> | |||
| <div class="ldap"> | |||
| <div class="field"> | |||
| <label class="req" for="domain">{{.i18n.Tr "admin.auths.domain"}}</label> | |||
| <input class="ipt ipt-large ipt-radius {{if .Err_Domain}}ipt-error{{end}}" id="domain" name="domain" value="{{.domain}}" /> | |||
| </div> | |||
| <div class="field"> | |||
| <label class="req" for="host">{{.i18n.Tr "admin.auths.host"}}</label> | |||
| <input class="ipt ipt-large ipt-radius {{if .Err_Host}}ipt-error{{end}}" id="host" name="host" value="{{.host}}" /> | |||
| </div> | |||
| <div class="field"> | |||
| <label class="req" for="port">{{.i18n.Tr "admin.auths.port"}}</label> | |||
| <input class="ipt ipt-large ipt-radius {{if .Err_Port}}ipt-error{{end}}" id="port" name="port" value="{{.port}}" /> | |||
| </div> | |||
| <div class="field"> | |||
| <label class="req" for="base_dn">{{.i18n.Tr "admin.auths.base_dn"}}</label> | |||
| <input class="ipt ipt-large ipt-radius {{if .Err_BaseDN}}ipt-error{{end}}" id="base_dn" name="base_dn" value="{{.base_dn}}" /> | |||
| </div> | |||
| <div class="field"> | |||
| <label class="req" for="attributes">{{.i18n.Tr "admin.auths.attributes"}}</label> | |||
| <input class="ipt ipt-large ipt-radius {{if .Err_Attributes}}ipt-error{{end}}" id="attributes" name="attributes" value="{{.attributes}}" /> | |||
| </div> | |||
| <div class="field"> | |||
| <label class="req" for="filter">{{.i18n.Tr "admin.auths.filter"}}</label> | |||
| <input class="ipt ipt-large ipt-radius {{if .Err_Filter}}ipt-error{{end}}" id="filter" name="filter" value="{{.filter}}" /> | |||
| </div> | |||
| <div class="field"> | |||
| <label class="req" for="ms_ad_sa">{{.i18n.Tr "admin.auths.ms_ad_sa"}}</label> | |||
| <input class="ipt ipt-large ipt-radius {{if .Err_MsAdSA}}ipt-error{{end}}" id="ms_ad_sa" name="ms_ad_sa" value="{{.ms_ad_sa}}" /> | |||
| </div> | |||
| </div> | |||
| <div class="smtp hidden"> | |||
| <div class="field"> | |||
| <label class="req">{{.i18n.Tr "admin.auths.smtp_auth"}}</label> | |||
| <select name="smtpauth"> | |||
| {{range .SMTPAuths}} | |||
| <option value="{{.}}">{{.}}</option> | |||
| {{end}} | |||
| </select> | |||
| </div> | |||
| <div class="field"> | |||
| <label class="req" for="smtphost">{{.i18n.Tr "admin.auths.smtphost"}}</label> | |||
| <input class="ipt ipt-large ipt-radius {{if .Err_SmtpHost}}ipt-error{{end}}" id="smtphost" name="smtphost" value="{{.smtphost}}" /> | |||
| </div> | |||
| <div class="field"> | |||
| <label class="req" for="smtpport">{{.i18n.Tr "admin.auths.smtpport"}}</label> | |||
| <input class="ipt ipt-large ipt-radius {{if .Err_SmtpPort}}ipt-error{{end}}" id="smtpport" name="smtpport" value="{{.smtpport}}" /> | |||
| </div> | |||
| </div> | |||
| <div class="field"> | |||
| <div class="smtp hidden"> | |||
| <label></label> | |||
| <input name="tls" type="checkbox" {{if .tls}}checked{{end}}> | |||
| <strong>Enable TLS Encryption</strong> | |||
| </label> | |||
| <strong>{{.i18n.Tr "admin.auths.enable_tls"}}</strong> | |||
| <br> | |||
| </div> | |||
| <label></label> | |||
| <input name="allowautoregister" type="checkbox" {{if .allowautoregister}}checked{{end}}> | |||
| <strong>{{.i18n.Tr "admin.auths.enable_auto_register"}}</strong> | |||
| </div> | |||
| </div> | |||
| <div class="field"> | |||
| <label></label> | |||
| <button class="btn btn-blue btn-large btn-radius">{{.i18n.Tr "admin.auths.new"}}</button> | |||
| </div> | |||
| </form> | |||
| </div> | |||
| </div> | |||
| <div class="form-group"> | |||
| <div class="col-md-offset-3 col-md-7"> | |||
| <div class="checkbox"> | |||
| <label> | |||
| <input name="allowautoregister" type="checkbox" {{if .allowautoregister}}checked{{end}}> | |||
| <strong>Enable Auto Registration</strong> | |||
| </label> | |||
| <br> | |||
| <div class="panel panel-radius"> | |||
| <div class="panel-header"> | |||
| {{.i18n.Tr "admin.auths.tips"}} | |||
| </div> | |||
| <div class="panel-body admin-panel"> | |||
| <h5>GMail Setting:</h5> | |||
| <p>Host: smtp.gmail.com, Post: 587, Enable TLS Encryption: true</p> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| <hr/> | |||
| <div class="form-group"> | |||
| <div class="col-md-offset-3 col-md-7"> | |||
| <button type="submit" class="btn btn-lg btn-primary">Create new authentication</button> | |||
| </div> | |||
| </div> | |||
| </form> | |||
| </div> | |||
| </div> | |||
| <div class="panel panel-info"> | |||
| <div class="panel-heading"> | |||
| Tips | |||
| </div> | |||
| <div class="panel-body"> | |||
| <h5>GMail Setting:</h5> | |||
| <p>Host: smtp.gmail.com, Post: 587, Enable TLS Encryption: true</p> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| <script> | |||
| $(function () { | |||
| $('#auth-type').on("change", function () { | |||
| var v = $(this).val(); | |||
| if (v == 2) { | |||
| $('.ldap').toggleShow(); | |||
| $('.smtp').toggleHide(); | |||
| } | |||
| if (v == 3) { | |||
| $('.smtp').toggleShow(); | |||
| $('.ldap').toggleHide(); | |||
| } | |||
| }); | |||
| }); | |||
| </script> | |||
| {{template "base/footer" .}} | |||
| {{template "ng/base/footer" .}} | |||
| @@ -1,43 +0,0 @@ | |||
| {{template "base/head" .}} | |||
| {{template "base/navbar" .}} | |||
| <div id="body" class="container" data-page="admin"> | |||
| {{template "admin/nav" .}} | |||
| <div id="admin-container" class="col-md-10"> | |||
| <div class="panel panel-default"> | |||
| <div class="panel-heading"> | |||
| Authentication Management | |||
| </div> | |||
| <div class="panel-body"> | |||
| <a href="/admin/auths/new" class="btn btn-primary">New Auth Source</a> | |||
| <table class="table table-striped"> | |||
| <thead> | |||
| <tr> | |||
| <th>Id</th> | |||
| <th>Name</th> | |||
| <th>Type</th> | |||
| <th>Actived</th> | |||
| <th>Updated</th> | |||
| <th>Created</th> | |||
| <th>Edit</th> | |||
| </tr> | |||
| </thead> | |||
| <tbody> | |||
| {{range .Sources}} | |||
| <tr> | |||
| <td>{{.Id}}</td> | |||
| <td><a href="/admin/auths/{{.Id}}">{{.Name}}</a></td> | |||
| <td>{{.TypeString}}</td> | |||
| <td><i class="fa fa{{if .IsActived}}-check{{end}}-square-o"></i></td> | |||
| <td>{{DateFormat .Updated "M d, Y"}}</td> | |||
| <td>{{DateFormat .Created "M d, Y"}}</td> | |||
| <td><a href="/admin/auths/{{.Id}}"><i class="fa fa-pencil-square-o"></i></a></td> | |||
| </tr> | |||
| {{end}} | |||
| </tbody> | |||
| </table> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| {{template "base/footer" .}} | |||
| @@ -6,7 +6,7 @@ | |||
| <li {{if .PageIsAdminUsers}}class="current"{{end}}><a href="/admin/users">{{.i18n.Tr "admin.users"}}</a></li> | |||
| <li {{if .PageIsAdminOrganizations}}class="current"{{end}}><a href="/admin/orgs">{{.i18n.Tr "admin.organizations"}}</a></li> | |||
| <li {{if .PageIsAdminRepositories}}class="current"{{end}}><a href="/admin/repos">{{.i18n.Tr "admin.repositories"}}</a></li> | |||
| <li {{if .PageIsAdminAuthentication}}class="current"{{end}}><a href="/admin/auths">{{.i18n.Tr "admin.authentication"}}</a></li> | |||
| <li {{if .PageIsAdminAuthentications}}class="current"{{end}}><a href="/admin/auths">{{.i18n.Tr "admin.authentication"}}</a></li> | |||
| <li {{if .PageIsAdminConfig}}class="current"{{end}}><a href="/admin/config">{{.i18n.Tr "admin.config"}}</a></li> | |||
| <li {{if .PageIsAdminMonitor}}class="current"{{end}}><a href="/admin/monitor">{{.i18n.Tr "admin.monitor"}}</a></li> | |||
| </ul> | |||
| @@ -0,0 +1,58 @@ | |||
| {{template "ng/base/head" .}} | |||
| {{template "ng/base/header" .}} | |||
| <div id="admin-wrapper"> | |||
| <div id="setting-wrapper" class="main-wrapper"> | |||
| <div id="admin-setting" class="container clear"> | |||
| {{template "admin/nav" .}} | |||
| <div class="grid-4-5 left"> | |||
| <div class="setting-content"> | |||
| {{template "ng/base/alert" .}} | |||
| <div id="setting-content"> | |||
| <div class="panel panel-radius"> | |||
| <div class="panel-header"> | |||
| <strong>{{.i18n.Tr "admin.orgs.org_manage_panel"}}</strong> | |||
| </div> | |||
| <div class="panel-body admin-panel"> | |||
| <div class="admin-table"> | |||
| <table class="table table-striped"> | |||
| <thead> | |||
| <tr> | |||
| <th>Id</th> | |||
| <th>{{.i18n.Tr "admin.orgs.name"}}</th> | |||
| <th>{{.i18n.Tr "email"}}</th> | |||
| <th>{{.i18n.Tr "admin.orgs.teams"}}</th> | |||
| <th>{{.i18n.Tr "admin.orgs.members"}}</th> | |||
| <th>{{.i18n.Tr "admin.users.repos"}}</th> | |||
| <th>{{.i18n.Tr "admin.users.created"}}</th> | |||
| </tr> | |||
| </thead> | |||
| <tbody> | |||
| {{range .Orgs}} | |||
| <tr> | |||
| <td>{{.Id}}</td> | |||
| <td><a href="/org/{{.Name}}">{{.Name}}</a></td> | |||
| <td>{{.Email}}</td> | |||
| <td>{{.NumTeams}}</td> | |||
| <td>{{.NumMembers}}</td> | |||
| <td>{{.NumRepos}}</td> | |||
| <td>{{DateFormat .Created "M d, Y"}}</td> | |||
| </tr> | |||
| {{end}} | |||
| </tbody> | |||
| </table> | |||
| {{if or .LastPageNum .NextPageNum}} | |||
| <ul class="pagination"> | |||
| {{if .LastPageNum}}<li><a class="btn btn-medium btn-gray btn-radius" href="/admin/orgs?p={{.LastPageNum}}">« {{.i18n.Tr "admin.prev"}}</a></li>{{end}} | |||
| {{if .NextPageNum}}<li><a class="btn btn-medium btn-gray btn-radius" href="/admin/orgs?p={{.NextPageNum}}">» {{.i18n.Tr "admin.next"}}</a></li>{{end}} | |||
| </ul> | |||
| {{end}} | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| {{template "ng/base/footer" .}} | |||
| @@ -0,0 +1,60 @@ | |||
| {{template "ng/base/head" .}} | |||
| {{template "ng/base/header" .}} | |||
| <div id="admin-wrapper"> | |||
| <div id="setting-wrapper" class="main-wrapper"> | |||
| <div id="admin-setting" class="container clear"> | |||
| {{template "admin/nav" .}} | |||
| <div class="grid-4-5 left"> | |||
| <div class="setting-content"> | |||
| {{template "ng/base/alert" .}} | |||
| <div id="setting-content"> | |||
| <div class="panel panel-radius"> | |||
| <div class="panel-header"> | |||
| <strong>{{.i18n.Tr "admin.repos.repo_manage_panel"}}</strong> | |||
| </div> | |||
| <div class="panel-body admin-panel"> | |||
| <div class="admin-table"> | |||
| <table class="table table-striped"> | |||
| <thead> | |||
| <tr> | |||
| <th>Id</th> | |||
| <th>{{.i18n.Tr "admin.repos.owner"}}</th> | |||
| <th>{{.i18n.Tr "admin.repos.name"}}</th> | |||
| <th>{{.i18n.Tr "admin.repos.private"}}</th> | |||
| <th>{{.i18n.Tr "admin.repos.watches"}}</th> | |||
| <th>{{.i18n.Tr "admin.repos.stars"}}</th> | |||
| <th>{{.i18n.Tr "admin.repos.issues"}}</th> | |||
| <th>{{.i18n.Tr "admin.users.created"}}</th> | |||
| </tr> | |||
| </thead> | |||
| <tbody> | |||
| {{range .Repos}} | |||
| <tr> | |||
| <td>{{.Id}}</td> | |||
| <td><a href="/user/{{.Owner.Name}}">{{.Owner.Name}}</a></td> | |||
| <td><a href="/{{.Owner.Name}}/{{.Name}}">{{.Name}}</a></td> | |||
| <td><i class="fa fa{{if .IsPrivate}}-check{{end}}-square-o"></i></td> | |||
| <td>{{.NumWatches}}</td> | |||
| <td>{{.NumIssues}}</td> | |||
| <td>{{.NumStars}}</td> | |||
| <td>{{DateFormat .Created "M d, Y"}}</td> | |||
| </tr> | |||
| {{end}} | |||
| </tbody> | |||
| </table> | |||
| {{if or .LastPageNum .NextPageNum}} | |||
| <ul class="pagination"> | |||
| {{if .LastPageNum}}<li><a class="btn btn-medium btn-gray btn-radius" href="/admin/repos?p={{.LastPageNum}}">« Prev.</a></li>{{end}} | |||
| {{if .NextPageNum}}<li><a class="btn btn-medium btn-gray btn-radius" href="/admin/repos?p={{.NextPageNum}}">» Next</a></li>{{end}} | |||
| </ul> | |||
| {{end}} | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| {{template "ng/base/footer" .}} | |||
| @@ -1,48 +0,0 @@ | |||
| {{template "base/head" .}} | |||
| {{template "base/navbar" .}} | |||
| <div id="body" class="container" data-page="admin"> | |||
| {{template "admin/nav" .}} | |||
| <div id="admin-container" class="col-md-10"> | |||
| <div class="panel panel-default"> | |||
| <div class="panel-heading"> | |||
| Repository Management | |||
| </div> | |||
| <div class="panel-body"> | |||
| <table class="table table-striped"> | |||
| <thead> | |||
| <tr> | |||
| <th>Id</th> | |||
| <th>Owner</th> | |||
| <th>Name</th> | |||
| <th>Private</th> | |||
| <th>Watches</th> | |||
| <th>Issues</th> | |||
| <th>Forks</th> | |||
| <th>Created</th> | |||
| </tr> | |||
| </thead> | |||
| <tbody> | |||
| {{range .Repos}} | |||
| <tr> | |||
| <td>{{.Id}}</td> | |||
| <th>{{.Owner.Name}}</th> | |||
| <td><a href="/{{.Owner.Name}}/{{.Name}}">{{.Name}}</a></td> | |||
| <td><i class="fa fa{{if .IsPrivate}}-check{{end}}-square-o"></i></td> | |||
| <td>{{.NumWatches}}</td> | |||
| <td>{{.NumIssues}}</td> | |||
| <td>{{.NumForks}}</td> | |||
| <td>{{DateFormat .Created "M d, Y"}}</td> | |||
| </tr> | |||
| {{end}} | |||
| </tbody> | |||
| </table> | |||
| <ul class="pagination"> | |||
| {{if .LastPageNum}}<li><a href="/admin/repos?p={{.LastPageNum}}">« Prev.</a></li>{{end}} | |||
| {{if .NextPageNum}}<li><a href="/admin/repos?p={{.NextPageNum}}">» Next</a></li>{{end}} | |||
| </ul> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| {{template "base/footer" .}} | |||
| @@ -20,7 +20,7 @@ | |||
| <tr> | |||
| <th>Id</th> | |||
| <th>{{.i18n.Tr "admin.users.name"}}</th> | |||
| <th>{{.i18n.Tr "admin.users.email"}}</th> | |||
| <th>{{.i18n.Tr "email"}}</th> | |||
| <th>{{.i18n.Tr "admin.users.activated"}}</th> | |||
| <th>{{.i18n.Tr "admin.users.admin"}}</th> | |||
| <th>{{.i18n.Tr "admin.users.repos"}}</th> | |||
| @@ -51,7 +51,6 @@ | |||
| {{end}} | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| @@ -44,7 +44,7 @@ | |||
| <input class="ipt ipt-large ipt-radius {{if .Err_Password}}ipt-error{{end}}" id="re-type" name="retype" type="password" required/> | |||
| </div> | |||
| <div class="field"> | |||
| <span class="form-label"></span> | |||
| <label></label> | |||
| <button class="btn btn-blue btn-large btn-radius">{{.i18n.Tr "admin.users.new_account"}}</button> | |||
| </div> | |||
| </form> | |||