// Post ... func (ua *UserAPI) Post() { if !(ua.AuthMode == "db_auth") { ua.CustomAbort(http.StatusForbidden, "") } if !(ua.SelfRegistration || ua.IsAdmin) { log.Warning("Registration can only be used by admin role user when self-registration is off.") ua.CustomAbort(http.StatusForbidden, "") } user := models.User{} ua.DecodeJSONReq(&user) err := validate(user) if err != nil { log.Warningf("Bad request in Register: %v", err) ua.RenderError(http.StatusBadRequest, "register error:"+err.Error()) return } userExist, err := dao.UserExists(user, "username") if err != nil { log.Errorf("Error occurred in Register: %v", err) ua.CustomAbort(http.StatusInternalServerError, "Internal error.") } if userExist { log.Warning("username has already been used!") ua.RenderError(http.StatusConflict, "username has already been used!") return } emailExist, err := dao.UserExists(user, "email") if err != nil { log.Errorf("Error occurred in change user profile: %v", err) ua.CustomAbort(http.StatusInternalServerError, "Internal error.") } if emailExist { log.Warning("email has already been used!") ua.RenderError(http.StatusConflict, "email has already been used!") return } userID, err := dao.Register(user) if err != nil { log.Errorf("Error occurred in Register: %v", err) ua.CustomAbort(http.StatusInternalServerError, "Internal error.") } ua.Redirect(http.StatusCreated, strconv.FormatInt(userID, 10)) }
// Put ... func (ua *UserAPI) Put() { ldapAdminUser := (ua.AuthMode == "ldap_auth" && ua.userID == 1 && ua.userID == ua.currentUserID) if !(ua.AuthMode == "db_auth" || ldapAdminUser) { ua.CustomAbort(http.StatusForbidden, "") } if !ua.IsAdmin { if ua.userID != ua.currentUserID { log.Warning("Guests can only change their own account.") ua.CustomAbort(http.StatusForbidden, "Guests can only change their own account.") } } user := models.User{UserID: ua.userID} ua.DecodeJSONReq(&user) err := commonValidate(user) if err != nil { log.Warningf("Bad request in change user profile: %v", err) ua.RenderError(http.StatusBadRequest, "change user profile error:"+err.Error()) return } userQuery := models.User{UserID: ua.userID} u, err := dao.GetUser(userQuery) if err != nil { log.Errorf("Error occurred in GetUser, error: %v", err) ua.CustomAbort(http.StatusInternalServerError, "Internal error.") } if u == nil { log.Errorf("User with Id: %d does not exist", ua.userID) ua.CustomAbort(http.StatusNotFound, "") } if u.Email != user.Email { emailExist, err := dao.UserExists(user, "email") if err != nil { log.Errorf("Error occurred in change user profile: %v", err) ua.CustomAbort(http.StatusInternalServerError, "Internal error.") } if emailExist { log.Warning("email has already been used!") ua.RenderError(http.StatusConflict, "email has already been used!") return } } if err := dao.ChangeUserProfile(user); err != nil { log.Errorf("Failed to update user profile, error: %v", err) ua.CustomAbort(http.StatusInternalServerError, err.Error()) } }
// UserExists checks if user exists when user input value in sign in form. func (cc *CommonController) UserExists() { target := cc.GetString("target") value := cc.GetString("value") user := models.User{} switch target { case "username": user.Username = value case "email": user.Email = value } exist, err := dao.UserExists(user, target) if err != nil { log.Errorf("Error occurred in UserExists: %v", err) cc.CustomAbort(http.StatusInternalServerError, "Internal error.") } cc.Data["json"] = exist cc.ServeJSON() }
// SendEmail verifies the Email address and contact SMTP server to send reset password Email. func (cc *CommonController) SendEmail() { email := cc.GetString("email") pass, _ := regexp.MatchString(`^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$`, email) if !pass { cc.CustomAbort(http.StatusBadRequest, "email_content_illegal") } else { queryUser := models.User{Email: email} exist, err := dao.UserExists(queryUser, "email") if err != nil { log.Errorf("Error occurred in UserExists: %v", err) cc.CustomAbort(http.StatusInternalServerError, "Internal error.") } if !exist { cc.CustomAbort(http.StatusNotFound, "email_does_not_exist") } messageTemplate, err := template.ParseFiles("views/reset-password-mail.tpl") if err != nil { log.Errorf("Parse email template file failed: %v", err) cc.CustomAbort(http.StatusInternalServerError, err.Error()) } message := new(bytes.Buffer) harborURL := os.Getenv("HARBOR_URL") if harborURL == "" { harborURL = "localhost" } uuid := utils.GenerateRandomString() err = messageTemplate.Execute(message, messageDetail{ Hint: cc.Tr("reset_email_hint"), URL: harborURL, UUID: uuid, }) if err != nil { log.Errorf("Message template error: %v", err) cc.CustomAbort(http.StatusInternalServerError, "internal_error") } config, err := beego.AppConfig.GetSection("mail") if err != nil { log.Errorf("Can not load app.conf: %v", err) cc.CustomAbort(http.StatusInternalServerError, "internal_error") } mail := utils.Mail{ From: config["from"], To: []string{email}, Subject: cc.Tr("reset_email_subject"), Message: message.String()} err = mail.SendMail() if err != nil { log.Errorf("Send email failed: %v", err) cc.CustomAbort(http.StatusInternalServerError, "send_email_failed") } user := models.User{ResetUUID: uuid, Email: email} dao.UpdateUserResetUUID(user) } }
// Authenticate checks user's credential against LDAP based on basedn template and LDAP URL, // if the check is successful a dummy record will be inserted into DB, such that this user can // be associated to other entities in the system. func (l *Auth) Authenticate(m models.AuthModel) (*models.User, error) { p := m.Principal for _, c := range metaChars { if strings.ContainsRune(p, c) { return nil, fmt.Errorf("the principal contains meta char: %q", c) } } ldapURL := config.LDAP().URL if ldapURL == "" { return nil, errors.New("can not get any available LDAP_URL") } log.Debug("ldapURL:", ldapURL) ldap, err := openldap.Initialize(ldapURL) if err != nil { return nil, err } ldap.SetOption(openldap.LDAP_OPT_PROTOCOL_VERSION, openldap.LDAP_VERSION3) ldapBaseDn := config.LDAP().BaseDn if ldapBaseDn == "" { return nil, errors.New("can not get any available LDAP_BASE_DN") } log.Debug("baseDn:", ldapBaseDn) ldapSearchDn := config.LDAP().SearchDn if ldapSearchDn != "" { log.Debug("Search DN: ", ldapSearchDn) ldapSearchPwd := config.LDAP().SearchPwd err = ldap.Bind(ldapSearchDn, ldapSearchPwd) if err != nil { log.Debug("Bind search dn error", err) return nil, err } } attrName := config.LDAP().UID filter := config.LDAP().Filter if filter != "" { filter = "(&" + filter + "(" + attrName + "=" + m.Principal + "))" } else { filter = "(" + attrName + "=" + m.Principal + ")" } log.Debug("one or more filter", filter) ldapScope := config.LDAP().Scope var scope int if ldapScope == "1" { scope = openldap.LDAP_SCOPE_BASE } else if ldapScope == "2" { scope = openldap.LDAP_SCOPE_ONELEVEL } else { scope = openldap.LDAP_SCOPE_SUBTREE } attributes := []string{"uid", "cn", "mail", "email"} result, err := ldap.SearchAll(ldapBaseDn, scope, filter, attributes) if err != nil { return nil, err } if len(result.Entries()) == 0 { log.Warningf("Not found an entry.") return nil, nil } else if len(result.Entries()) != 1 { log.Warningf("Found more than one entry.") return nil, nil } en := result.Entries()[0] bindDN := en.Dn() log.Debug("found entry:", en) err = ldap.Bind(bindDN, m.Password) if err != nil { log.Debug("Bind user error", err) return nil, err } defer ldap.Close() u := models.User{} for _, attr := range en.Attributes() { val := attr.Values()[0] switch attr.Name() { case "uid": u.Realname = val case "cn": u.Realname = val case "mail": u.Email = val case "email": u.Email = val } } u.Username = m.Principal log.Debug("username:"******",email:", u.Email) exist, err := dao.UserExists(u, "username") if err != nil { return nil, err } if exist { currentUser, err := dao.GetUser(u) if err != nil { return nil, err } u.UserID = currentUser.UserID } else { u.Realname = m.Principal u.Password = "******" u.Comment = "registered from LDAP." if u.Email == "" { u.Email = u.Username + "@placeholder.com" } userID, err := dao.Register(u) if err != nil { return nil, err } u.UserID = int(userID) } return &u, nil }