aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md2
-rw-r--r--README_ZH.md2
-rw-r--r--cmd/web.go8
-rw-r--r--gogs.go2
-rw-r--r--models/issue.go2
-rw-r--r--models/login.go4
-rw-r--r--models/repo.go39
-rw-r--r--models/user.go29
-rw-r--r--modules/auth/user.go34
-rw-r--r--modules/mailer/mail.go60
-rw-r--r--modules/setting/setting.go2
-rw-r--r--routers/repo/setting.go2
-rw-r--r--routers/user/user.go18
-rw-r--r--templates/VERSION2
-rw-r--r--templates/admin/auths/edit.tmpl6
15 files changed, 120 insertions, 92 deletions
diff --git a/README.md b/README.md
index 2de797af..88870819 100644
--- a/README.md
+++ b/README.md
@@ -5,7 +5,7 @@ Gogs(Go Git Service) is a Self Hosted Git Service in the Go Programming Language
![Demo](http://gowalker.org/public/gogs_demo.gif)
-##### Current version: 0.4.0 Alpha
+##### Current version: 0.4.2 Alpha
### NOTICES
diff --git a/README_ZH.md b/README_ZH.md
index f3be4418..84af15a6 100644
--- a/README_ZH.md
+++ b/README_ZH.md
@@ -5,7 +5,7 @@ Gogs(Go Git Service) 是一个由 Go 语言编写的自助 Git 托管服务。
![Demo](http://gowalker.org/public/gogs_demo.gif)
-##### 当前版本:0.4.0 Alpha
+##### 当前版本:0.4.2 Alpha
## 开发目的
diff --git a/cmd/web.go b/cmd/web.go
index dc4daca0..30db037a 100644
--- a/cmd/web.go
+++ b/cmd/web.go
@@ -89,9 +89,11 @@ func runWeb(*cli.Context) {
m.Get("/", ignSignIn, routers.Home)
m.Get("/install", bindIgnErr(auth.InstallForm{}), routers.Install)
m.Post("/install", bindIgnErr(auth.InstallForm{}), routers.InstallPost)
- m.Get("/issues", reqSignIn, user.Issues)
- m.Get("/pulls", reqSignIn, user.Pulls)
- m.Get("/stars", reqSignIn, user.Stars)
+ m.Group("", func(r martini.Router) {
+ r.Get("/issues", user.Issues)
+ r.Get("/pulls", user.Pulls)
+ r.Get("/stars", user.Stars)
+ }, reqSignIn)
m.Group("/api", func(r martini.Router) {
m.Group("/v1", func(r martini.Router) {
diff --git a/gogs.go b/gogs.go
index 963cd587..aabcbe82 100644
--- a/gogs.go
+++ b/gogs.go
@@ -17,7 +17,7 @@ import (
"github.com/gogits/gogs/modules/setting"
)
-const APP_VER = "0.4.1.0601 Alpha"
+const APP_VER = "0.4.2.0605 Alpha"
func init() {
runtime.GOMAXPROCS(runtime.NumCPU())
diff --git a/models/issue.go b/models/issue.go
index 18057985..7db728ec 100644
--- a/models/issue.go
+++ b/models/issue.go
@@ -771,7 +771,7 @@ type Comment struct {
IssueId int64
CommitId int64
Line int64
- Content string
+ Content string `xorm:"TEXT"`
Created time.Time `xorm:"CREATED"`
}
diff --git a/models/login.go b/models/login.go
index 3efef2f7..984a9f8c 100644
--- a/models/login.go
+++ b/models/login.go
@@ -150,8 +150,8 @@ func DelLoginSource(source *LoginSource) error {
return err
}
-// login a user
-func LoginUser(uname, passwd string) (*User, error) {
+// UserSignIn validates user name and password.
+func UserSignIn(uname, passwd string) (*User, error) {
var u *User
if strings.Contains(uname, "@") {
u = &User{Email: uname}
diff --git a/models/repo.go b/models/repo.go
index 90e5e36b..869059fa 100644
--- a/models/repo.go
+++ b/models/repo.go
@@ -12,6 +12,7 @@ import (
"os/exec"
"path"
"path/filepath"
+ "sort"
"strings"
"time"
"unicode/utf8"
@@ -30,9 +31,9 @@ import (
var (
ErrRepoAlreadyExist = errors.New("Repository already exist")
ErrRepoNotExist = errors.New("Repository does not exist")
- ErrRepoFileNotExist = errors.New("Target Repo file does not exist")
+ ErrRepoFileNotExist = errors.New("Repository file does not exist")
ErrRepoNameIllegal = errors.New("Repository name contains illegal characters")
- ErrRepoFileNotLoaded = errors.New("repo file not loaded")
+ ErrRepoFileNotLoaded = errors.New("Repository file not loaded")
ErrMirrorNotExist = errors.New("Mirror does not exist")
)
@@ -45,7 +46,7 @@ func getAssetList(prefix string) []string {
assets := make([]string, 0, 15)
for _, name := range bin.AssetNames() {
if strings.HasPrefix(name, prefix) {
- assets = append(assets, name)
+ assets = append(assets, strings.TrimPrefix(name, prefix+"/"))
}
}
return assets
@@ -75,6 +76,8 @@ func LoadRepoConfig() {
LanguageIgns = typeFiles[0]
Licenses = typeFiles[1]
+ sort.Strings(LanguageIgns)
+ sort.Strings(Licenses)
}
func NewRepoContext() {
@@ -486,22 +489,40 @@ func initRepository(f string, user *User, repo *Repository, initReadme bool, rep
// .gitignore
if repoLang != "" {
filePath := "conf/gitignore/" + repoLang
- if com.IsFile(filePath) {
- if err := com.Copy(filePath,
- filepath.Join(tmpDir, fileName["gitign"])); err != nil {
+ targetPath := path.Join(tmpDir, fileName["gitign"])
+ data, err := bin.Asset(filePath)
+ if err == nil {
+ if err = ioutil.WriteFile(targetPath, data, os.ModePerm); err != nil {
return err
}
+ } else {
+ // Check custom files.
+ filePath = path.Join(setting.CustomPath, "conf/gitignore", repoLang)
+ if com.IsFile(filePath) {
+ if err := com.Copy(filePath, targetPath); err != nil {
+ return err
+ }
+ }
}
}
// LICENSE
if license != "" {
filePath := "conf/license/" + license
- if com.IsFile(filePath) {
- if err := com.Copy(filePath,
- filepath.Join(tmpDir, fileName["license"])); err != nil {
+ targetPath := path.Join(tmpDir, fileName["license"])
+ data, err := bin.Asset(filePath)
+ if err == nil {
+ if err = ioutil.WriteFile(targetPath, data, os.ModePerm); err != nil {
return err
}
+ } else {
+ // Check custom files.
+ filePath = path.Join(setting.CustomPath, "conf/license", license)
+ if com.IsFile(filePath) {
+ if err := com.Copy(filePath, targetPath); err != nil {
+ return err
+ }
+ }
}
}
diff --git a/models/user.go b/models/user.go
index dd70a35f..78ab4642 100644
--- a/models/user.go
+++ b/models/user.go
@@ -72,7 +72,7 @@ func (user *User) HomeLink() string {
return "/user/" + user.Name
}
-// AvatarLink returns the user gravatar link.
+// AvatarLink returns user gravatar link.
func (user *User) AvatarLink() string {
if setting.DisableGravatar {
return "/img/avatar_default.jpg"
@@ -121,7 +121,7 @@ func IsEmailUsed(email string) (bool, error) {
return orm.Get(&User{Email: email})
}
-// return a user salt token
+// GetUserSalt returns a user salt token
func GetUserSalt() string {
return base.GetRandomString(10)
}
@@ -268,17 +268,17 @@ func ChangeUserName(user *User, newUserName string) (err error) {
}
// UpdateUser updates user's information.
-func UpdateUser(user *User) (err error) {
- user.LowerName = strings.ToLower(user.Name)
+func UpdateUser(u *User) (err error) {
+ u.LowerName = strings.ToLower(u.Name)
- if len(user.Location) > 255 {
- user.Location = user.Location[:255]
+ if len(u.Location) > 255 {
+ u.Location = u.Location[:255]
}
- if len(user.Website) > 255 {
- user.Website = user.Website[:255]
+ if len(u.Website) > 255 {
+ u.Website = u.Website[:255]
}
- _, err = orm.Id(user.Id).AllCols().Update(user)
+ _, err = orm.Id(u.Id).AllCols().Update(u)
return err
}
@@ -356,17 +356,16 @@ func GetUserByKeyId(keyId int64) (*User, error) {
return user, nil
}
-// GetUserById returns the user object by given id if exists.
+// GetUserById returns the user object by given ID if exists.
func GetUserById(id int64) (*User, error) {
- user := new(User)
- has, err := orm.Id(id).Get(user)
+ u := new(User)
+ has, err := orm.Id(id).Get(u)
if err != nil {
return nil, err
- }
- if !has {
+ } else if !has {
return nil, ErrUserNotExist
}
- return user, nil
+ return u, nil
}
// GetUserByName returns the user object by given name if exists.
diff --git a/modules/auth/user.go b/modules/auth/user.go
index e672a9c1..3763c0fc 100644
--- a/modules/auth/user.go
+++ b/modules/auth/user.go
@@ -19,54 +19,54 @@ import (
)
// SignedInId returns the id of signed in user.
-func SignedInId(session session.SessionStore) int64 {
+func SignedInId(sess session.SessionStore) int64 {
if !models.HasEngine {
return 0
}
- userId := session.Get("userId")
- if userId == nil {
+ uid := sess.Get("userId")
+ if uid == nil {
return 0
}
- if s, ok := userId.(int64); ok {
- if _, err := models.GetUserById(s); err != nil {
+ if id, ok := uid.(int64); ok {
+ if _, err := models.GetUserById(id); err != nil {
return 0
}
- return s
+ return id
}
return 0
}
// SignedInName returns the name of signed in user.
-func SignedInName(session session.SessionStore) string {
- userName := session.Get("userName")
- if userName == nil {
+func SignedInName(sess session.SessionStore) string {
+ uname := sess.Get("userName")
+ if uname == nil {
return ""
}
- if s, ok := userName.(string); ok {
+ if s, ok := uname.(string); ok {
return s
}
return ""
}
// SignedInUser returns the user object of signed user.
-func SignedInUser(session session.SessionStore) *models.User {
- id := SignedInId(session)
- if id <= 0 {
+func SignedInUser(sess session.SessionStore) *models.User {
+ uid := SignedInId(sess)
+ if uid <= 0 {
return nil
}
- user, err := models.GetUserById(id)
+ u, err := models.GetUserById(uid)
if err != nil {
log.Error("user.SignedInUser: %v", err)
return nil
}
- return user
+ return u
}
// IsSignedIn check if any user has signed in.
-func IsSignedIn(session session.SessionStore) bool {
- return SignedInId(session) > 0
+func IsSignedIn(sess session.SessionStore) bool {
+ return SignedInId(sess) > 0
}
type FeedsForm struct {
diff --git a/modules/mailer/mail.go b/modules/mailer/mail.go
index 6e34439e..e212d006 100644
--- a/modules/mailer/mail.go
+++ b/modules/mailer/mail.go
@@ -26,10 +26,10 @@ func NewMailMessageFrom(To []string, from, subject, body string) Message {
// Create New mail message use MailFrom and MailUser
func NewMailMessage(To []string, subject, body string) Message {
- return NewMailMessageFrom(To, setting.MailService.User, subject, body)
+ return NewMailMessageFrom(To, setting.MailService.From, subject, body)
}
-func GetMailTmplData(user *models.User) map[interface{}]interface{} {
+func GetMailTmplData(u *models.User) map[interface{}]interface{} {
data := make(map[interface{}]interface{}, 10)
data["AppName"] = setting.AppName
data["AppVer"] = setting.AppVer
@@ -37,29 +37,29 @@ func GetMailTmplData(user *models.User) map[interface{}]interface{} {
data["AppLogo"] = setting.AppLogo
data["ActiveCodeLives"] = setting.Service.ActiveCodeLives / 60
data["ResetPwdCodeLives"] = setting.Service.ResetPwdCodeLives / 60
- if user != nil {
- data["User"] = user
+ if u != nil {
+ data["User"] = u
}
return data
}
// create a time limit code for user active
-func CreateUserActiveCode(user *models.User, startInf interface{}) string {
+func CreateUserActiveCode(u *models.User, startInf interface{}) string {
minutes := setting.Service.ActiveCodeLives
- data := base.ToStr(user.Id) + user.Email + user.LowerName + user.Passwd + user.Rands
+ data := base.ToStr(u.Id) + u.Email + u.LowerName + u.Passwd + u.Rands
code := base.CreateTimeLimitCode(data, minutes, startInf)
// add tail hex username
- code += hex.EncodeToString([]byte(user.LowerName))
+ code += hex.EncodeToString([]byte(u.LowerName))
return code
}
// Send user register mail with active code
-func SendRegisterMail(r *middleware.Render, user *models.User) {
- code := CreateUserActiveCode(user, nil)
+func SendRegisterMail(r *middleware.Render, u *models.User) {
+ code := CreateUserActiveCode(u, nil)
subject := "Register success, Welcome"
- data := GetMailTmplData(user)
+ data := GetMailTmplData(u)
data["Code"] = code
body, err := r.HTMLString("mail/auth/register_success", data)
if err != nil {
@@ -67,19 +67,19 @@ func SendRegisterMail(r *middleware.Render, user *models.User) {
return
}
- msg := NewMailMessage([]string{user.Email}, subject, body)
- msg.Info = fmt.Sprintf("UID: %d, send register mail", user.Id)
+ msg := NewMailMessage([]string{u.Email}, subject, body)
+ msg.Info = fmt.Sprintf("UID: %d, send register mail", u.Id)
SendAsync(&msg)
}
// Send email verify active email.
-func SendActiveMail(r *middleware.Render, user *models.User) {
- code := CreateUserActiveCode(user, nil)
+func SendActiveMail(r *middleware.Render, u *models.User) {
+ code := CreateUserActiveCode(u, nil)
subject := "Verify your e-mail address"
- data := GetMailTmplData(user)
+ data := GetMailTmplData(u)
data["Code"] = code
body, err := r.HTMLString("mail/auth/active_email", data)
if err != nil {
@@ -87,19 +87,19 @@ func SendActiveMail(r *middleware.Render, user *models.User) {
return
}
- msg := NewMailMessage([]string{user.Email}, subject, body)
- msg.Info = fmt.Sprintf("UID: %d, send active mail", user.Id)
+ msg := NewMailMessage([]string{u.Email}, subject, body)
+ msg.Info = fmt.Sprintf("UID: %d, send active mail", u.Id)
SendAsync(&msg)
}
// Send reset password email.
-func SendResetPasswdMail(r *middleware.Render, user *models.User) {
- code := CreateUserActiveCode(user, nil)
+func SendResetPasswdMail(r *middleware.Render, u *models.User) {
+ code := CreateUserActiveCode(u, nil)
subject := "Reset your password"
- data := GetMailTmplData(user)
+ data := GetMailTmplData(u)
data["Code"] = code
body, err := r.HTMLString("mail/auth/reset_passwd", data)
if err != nil {
@@ -107,14 +107,14 @@ func SendResetPasswdMail(r *middleware.Render, user *models.User) {
return
}
- msg := NewMailMessage([]string{user.Email}, subject, body)
- msg.Info = fmt.Sprintf("UID: %d, send reset password email", user.Id)
+ msg := NewMailMessage([]string{u.Email}, subject, body)
+ msg.Info = fmt.Sprintf("UID: %d, send reset password email", u.Id)
SendAsync(&msg)
}
// SendIssueNotifyMail sends mail notification of all watchers of repository.
-func SendIssueNotifyMail(user, owner *models.User, repo *models.Repository, issue *models.Issue) ([]string, error) {
+func SendIssueNotifyMail(u, owner *models.User, repo *models.Repository, issue *models.Issue) ([]string, error) {
ws, err := models.GetWatchers(repo.Id)
if err != nil {
return nil, errors.New("mail.NotifyWatchers(GetWatchers): " + err.Error())
@@ -123,7 +123,7 @@ func SendIssueNotifyMail(user, owner *models.User, repo *models.Repository, issu
tos := make([]string, 0, len(ws))
for i := range ws {
uid := ws[i].UserId
- if user.Id == uid {
+ if u.Id == uid {
continue
}
u, err := models.GetUserById(uid)
@@ -141,14 +141,14 @@ func SendIssueNotifyMail(user, owner *models.User, repo *models.Repository, issu
content := fmt.Sprintf("%s<br>-<br> <a href=\"%s%s/%s/issues/%d\">View it on Gogs</a>.",
base.RenderSpecialLink([]byte(issue.Content), owner.Name+"/"+repo.Name),
setting.AppUrl, owner.Name, repo.Name, issue.Index)
- msg := NewMailMessageFrom(tos, user.Email, subject, content)
+ msg := NewMailMessageFrom(tos, u.Email, subject, content)
msg.Info = fmt.Sprintf("Subject: %s, send issue notify emails", subject)
SendAsync(&msg)
return tos, nil
}
// SendIssueMentionMail sends mail notification for who are mentioned in issue.
-func SendIssueMentionMail(r *middleware.Render, user, owner *models.User,
+func SendIssueMentionMail(r *middleware.Render, u, owner *models.User,
repo *models.Repository, issue *models.Issue, tos []string) error {
if len(tos) == 0 {
@@ -166,14 +166,14 @@ func SendIssueMentionMail(r *middleware.Render, user, owner *models.User,
return fmt.Errorf("mail.SendIssueMentionMail(fail to render): %v", err)
}
- msg := NewMailMessageFrom(tos, user.Email, subject, body)
+ msg := NewMailMessageFrom(tos, u.Email, subject, body)
msg.Info = fmt.Sprintf("Subject: %s, send issue mention emails", subject)
SendAsync(&msg)
return nil
}
// SendCollaboratorMail sends mail notification to new collaborator.
-func SendCollaboratorMail(r *middleware.Render, user, owner *models.User,
+func SendCollaboratorMail(r *middleware.Render, u, owner *models.User,
repo *models.Repository) error {
subject := fmt.Sprintf("%s added you to %s", owner.Name, repo.Name)
@@ -187,8 +187,8 @@ func SendCollaboratorMail(r *middleware.Render, user, owner *models.User,
return fmt.Errorf("mail.SendCollaboratorMail(fail to render): %v", err)
}
- msg := NewMailMessage([]string{user.Email}, subject, body)
- msg.Info = fmt.Sprintf("UID: %d, send register mail", user.Id)
+ msg := NewMailMessage([]string{u.Email}, subject, body)
+ msg.Info = fmt.Sprintf("UID: %d, send register mail", u.Id)
SendAsync(&msg)
return nil
diff --git a/modules/setting/setting.go b/modules/setting/setting.go
index 8cca57ef..2f64511a 100644
--- a/modules/setting/setting.go
+++ b/modules/setting/setting.go
@@ -330,6 +330,7 @@ func newSessionService() {
type Mailer struct {
Name string
Host string
+ From string
User, Passwd string
}
@@ -363,6 +364,7 @@ func newMailService() {
User: Cfg.MustValue("mailer", "USER"),
Passwd: Cfg.MustValue("mailer", "PASSWD"),
}
+ MailService.From = Cfg.MustValue("mailer", "FROM", MailService.User)
log.Info("Mail Service Enabled")
}
diff --git a/routers/repo/setting.go b/routers/repo/setting.go
index fe248992..0232dbcf 100644
--- a/routers/repo/setting.go
+++ b/routers/repo/setting.go
@@ -7,6 +7,7 @@ package repo
import (
"fmt"
"strings"
+ "time"
"github.com/go-martini/martini"
@@ -72,6 +73,7 @@ func SettingPost(ctx *middleware.Context, form auth.RepoSettingForm) {
if ctx.Repo.Repository.IsMirror {
if form.Interval > 0 {
ctx.Repo.Mirror.Interval = form.Interval
+ ctx.Repo.Mirror.NextUpdate = time.Now().Add(time.Duration(form.Interval) * time.Hour)
if err := models.UpdateMirror(ctx.Repo.Mirror); err != nil {
log.Error("setting.SettingPost(UpdateMirror): %v", err)
}
diff --git a/routers/user/user.go b/routers/user/user.go
index a5b3e792..8fcbeb6a 100644
--- a/routers/user/user.go
+++ b/routers/user/user.go
@@ -32,8 +32,8 @@ func SignIn(ctx *middleware.Context) {
}
// Check auto-login.
- userName := ctx.GetCookie(setting.CookieUserName)
- if len(userName) == 0 {
+ uname := ctx.GetCookie(setting.CookieUserName)
+ if len(uname) == 0 {
ctx.HTML(200, "user/signin")
return
}
@@ -41,14 +41,14 @@ func SignIn(ctx *middleware.Context) {
isSucceed := false
defer func() {
if !isSucceed {
- log.Trace("user.SignIn(auto-login cookie cleared): %s", userName)
+ log.Trace("user.SignIn(auto-login cookie cleared): %s", uname)
ctx.SetCookie(setting.CookieUserName, "", -1)
ctx.SetCookie(setting.CookieRememberName, "", -1)
return
}
}()
- user, err := models.GetUserByName(userName)
+ user, err := models.GetUserByName(uname)
if err != nil {
ctx.Handle(500, "user.SignIn(GetUserByName)", err)
return
@@ -90,7 +90,7 @@ func SignInPost(ctx *middleware.Context, form auth.LogInForm) {
return
}
- user, err := models.LoginUser(form.UserName, form.Password)
+ user, err := models.UserSignIn(form.UserName, form.Password)
if err != nil {
if err == models.ErrUserNotExist {
log.Trace("%s Log in failed: %s", ctx.Req.RequestURI, form.UserName)
@@ -98,7 +98,7 @@ func SignInPost(ctx *middleware.Context, form auth.LogInForm) {
return
}
- ctx.Handle(500, "user.SignIn", err)
+ ctx.Handle(500, "user.SignInPost(UserSignIn)", err)
return
}
@@ -220,17 +220,18 @@ func SignUpPost(ctx *middleware.Context, form auth.RegisterForm) {
if u, err = models.RegisterUser(u); err != nil {
switch err {
case models.ErrUserAlreadyExist:
+ ctx.Data["Err_UserName"] = true
ctx.RenderWithErr("Username has been already taken", "user/signup", &form)
case models.ErrEmailAlreadyUsed:
+ ctx.Data["Err_Email"] = true
ctx.RenderWithErr("E-mail address has been already used", "user/signup", &form)
case models.ErrUserNameIllegal:
ctx.RenderWithErr(models.ErrRepoNameIllegal.Error(), "user/signup", &form)
default:
- ctx.Handle(500, "user.SignUp(RegisterUser)", err)
+ ctx.Handle(500, "user.SignUpPost(RegisterUser)", err)
}
return
}
-
log.Trace("%s User created: %s", ctx.Req.RequestURI, form.UserName)
// Bind social account.
@@ -256,6 +257,7 @@ func SignUpPost(ctx *middleware.Context, form auth.RegisterForm) {
}
return
}
+
ctx.Redirect("/user/login")
}
diff --git a/templates/VERSION b/templates/VERSION
index 81b60321..7ba2c25f 100644
--- a/templates/VERSION
+++ b/templates/VERSION
@@ -1 +1 @@
-0.4.1.0601 Alpha \ No newline at end of file
+0.4.2.0605 Alpha \ No newline at end of file
diff --git a/templates/admin/auths/edit.tmpl b/templates/admin/auths/edit.tmpl
index deea447c..a2c2ddc6 100644
--- a/templates/admin/auths/edit.tmpl
+++ b/templates/admin/auths/edit.tmpl
@@ -71,21 +71,21 @@
<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}}" required="required">
+ <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}}" required="required">
+ <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}}" required="required">
+ <input name="ms_ad_sa" class="form-control" placeholder="Type Ms Ad SA" value="{{.Source.LDAP.MsAdSAFormat}}">
</div>
</div>
{{else if eq $type 3}}