github.com/haalcala/mattermost-server-change-repo/v5@v5.33.2/app/ldap.go (about) 1 // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. 2 // See LICENSE.txt for license information. 3 4 package app 5 6 import ( 7 "io/ioutil" 8 "mime/multipart" 9 "net/http" 10 11 "github.com/mattermost/mattermost-server/v5/mlog" 12 "github.com/mattermost/mattermost-server/v5/model" 13 "github.com/mattermost/mattermost-server/v5/utils" 14 ) 15 16 func (a *App) SyncLdap() { 17 a.Srv().Go(func() { 18 19 if license := a.Srv().License(); license != nil && *license.Features.LDAP && *a.Config().LdapSettings.EnableSync { 20 if ldapI := a.Ldap(); ldapI != nil { 21 ldapI.StartSynchronizeJob(false) 22 } else { 23 mlog.Error("Not executing ldap sync because ldap is not available") 24 } 25 } 26 }) 27 } 28 29 func (a *App) TestLdap() *model.AppError { 30 license := a.Srv().License() 31 if ldapI := a.Ldap(); ldapI != nil && license != nil && *license.Features.LDAP && (*a.Config().LdapSettings.Enable || *a.Config().LdapSettings.EnableSync) { 32 if err := ldapI.RunTest(); err != nil { 33 err.StatusCode = 500 34 return err 35 } 36 } else { 37 err := model.NewAppError("TestLdap", "ent.ldap.disabled.app_error", nil, "", http.StatusNotImplemented) 38 return err 39 } 40 41 return nil 42 } 43 44 // GetLdapGroup retrieves a single LDAP group by the given LDAP group id. 45 func (a *App) GetLdapGroup(ldapGroupID string) (*model.Group, *model.AppError) { 46 var group *model.Group 47 48 if a.Ldap() != nil { 49 var err *model.AppError 50 group, err = a.Ldap().GetGroup(ldapGroupID) 51 if err != nil { 52 return nil, err 53 } 54 } else { 55 ae := model.NewAppError("GetLdapGroup", "ent.ldap.app_error", map[string]interface{}{"ldap_group_id": ldapGroupID}, "", http.StatusNotImplemented) 56 return nil, ae 57 } 58 59 return group, nil 60 } 61 62 // GetAllLdapGroupsPage retrieves all LDAP groups under the configured base DN using the default or configured group 63 // filter. 64 func (a *App) GetAllLdapGroupsPage(page int, perPage int, opts model.LdapGroupSearchOpts) ([]*model.Group, int, *model.AppError) { 65 var groups []*model.Group 66 var total int 67 68 if a.Ldap() != nil { 69 var err *model.AppError 70 groups, total, err = a.Ldap().GetAllGroupsPage(page, perPage, opts) 71 if err != nil { 72 return nil, 0, err 73 } 74 } else { 75 ae := model.NewAppError("GetAllLdapGroupsPage", "ent.ldap.app_error", nil, "", http.StatusNotImplemented) 76 return nil, 0, ae 77 } 78 79 return groups, total, nil 80 } 81 82 func (a *App) SwitchEmailToLdap(email, password, code, ldapLoginId, ldapPassword string) (string, *model.AppError) { 83 if a.Srv().License() != nil && !*a.Config().ServiceSettings.ExperimentalEnableAuthenticationTransfer { 84 return "", model.NewAppError("emailToLdap", "api.user.email_to_ldap.not_available.app_error", nil, "", http.StatusForbidden) 85 } 86 87 user, err := a.GetUserByEmail(email) 88 if err != nil { 89 return "", err 90 } 91 92 if err := a.CheckPasswordAndAllCriteria(user, password, code); err != nil { 93 return "", err 94 } 95 96 if err := a.RevokeAllSessions(user.Id); err != nil { 97 return "", err 98 } 99 100 ldapInterface := a.Ldap() 101 if ldapInterface == nil { 102 return "", model.NewAppError("SwitchEmailToLdap", "api.user.email_to_ldap.not_available.app_error", nil, "", http.StatusNotImplemented) 103 } 104 105 if err := ldapInterface.SwitchToLdap(user.Id, ldapLoginId, ldapPassword); err != nil { 106 return "", err 107 } 108 109 a.Srv().Go(func() { 110 if err := a.Srv().EmailService.SendSignInChangeEmail(user.Email, "AD/LDAP", user.Locale, a.GetSiteURL()); err != nil { 111 mlog.Error("Could not send sign in method changed e-mail", mlog.Err(err)) 112 } 113 }) 114 115 return "/login?extra=signin_change", nil 116 } 117 118 func (a *App) SwitchLdapToEmail(ldapPassword, code, email, newPassword string) (string, *model.AppError) { 119 if a.Srv().License() != nil && !*a.Config().ServiceSettings.ExperimentalEnableAuthenticationTransfer { 120 return "", model.NewAppError("ldapToEmail", "api.user.ldap_to_email.not_available.app_error", nil, "", http.StatusForbidden) 121 } 122 123 user, err := a.GetUserByEmail(email) 124 if err != nil { 125 return "", err 126 } 127 128 if user.AuthService != model.USER_AUTH_SERVICE_LDAP { 129 return "", model.NewAppError("SwitchLdapToEmail", "api.user.ldap_to_email.not_ldap_account.app_error", nil, "", http.StatusBadRequest) 130 } 131 132 ldapInterface := a.Ldap() 133 if ldapInterface == nil || user.AuthData == nil { 134 return "", model.NewAppError("SwitchLdapToEmail", "api.user.ldap_to_email.not_available.app_error", nil, "", http.StatusNotImplemented) 135 } 136 137 if err := ldapInterface.CheckPasswordAuthData(*user.AuthData, ldapPassword); err != nil { 138 return "", err 139 } 140 141 if err := a.CheckUserMfa(user, code); err != nil { 142 return "", err 143 } 144 145 if err := a.UpdatePassword(user, newPassword); err != nil { 146 return "", err 147 } 148 149 if err := a.RevokeAllSessions(user.Id); err != nil { 150 return "", err 151 } 152 153 T := utils.GetUserTranslations(user.Locale) 154 155 a.Srv().Go(func() { 156 if err := a.Srv().EmailService.SendSignInChangeEmail(user.Email, T("api.templates.signin_change_email.body.method_email"), user.Locale, a.GetSiteURL()); err != nil { 157 mlog.Error("Could not send sign in method changed e-mail", mlog.Err(err)) 158 } 159 }) 160 161 return "/login?extra=signin_change", nil 162 } 163 164 func (a *App) MigrateIdLDAP(toAttribute string) *model.AppError { 165 if ldapI := a.Ldap(); ldapI != nil { 166 if err := ldapI.MigrateIDAttribute(toAttribute); err != nil { 167 switch err := err.(type) { 168 case *model.AppError: 169 return err 170 default: 171 return model.NewAppError("IdMigrateLDAP", "ent.ldap_id_migrate.app_error", nil, err.Error(), http.StatusInternalServerError) 172 } 173 } 174 return nil 175 } 176 return model.NewAppError("IdMigrateLDAP", "ent.ldap.disabled.app_error", nil, "", http.StatusNotImplemented) 177 } 178 179 func (a *App) writeLdapFile(filename string, fileData *multipart.FileHeader) *model.AppError { 180 file, err := fileData.Open() 181 if err != nil { 182 return model.NewAppError("AddLdapCertificate", "api.admin.add_certificate.open.app_error", nil, err.Error(), http.StatusInternalServerError) 183 } 184 defer file.Close() 185 186 data, err := ioutil.ReadAll(file) 187 if err != nil { 188 return model.NewAppError("AddLdapCertificate", "api.admin.add_certificate.saving.app_error", nil, err.Error(), http.StatusInternalServerError) 189 } 190 191 err = a.Srv().configStore.SetFile(filename, data) 192 if err != nil { 193 return model.NewAppError("AddLdapCertificate", "api.admin.add_certificate.saving.app_error", nil, err.Error(), http.StatusInternalServerError) 194 } 195 196 return nil 197 } 198 199 func (a *App) AddLdapPublicCertificate(fileData *multipart.FileHeader) *model.AppError { 200 if err := a.writeLdapFile(model.LDAP_PUBLIC_CERTIFICATE_NAME, fileData); err != nil { 201 return err 202 } 203 204 cfg := a.Config().Clone() 205 *cfg.LdapSettings.PublicCertificateFile = model.LDAP_PUBLIC_CERTIFICATE_NAME 206 207 if err := cfg.IsValid(); err != nil { 208 return err 209 } 210 211 a.UpdateConfig(func(dest *model.Config) { *dest = *cfg }) 212 213 return nil 214 } 215 216 func (a *App) AddLdapPrivateCertificate(fileData *multipart.FileHeader) *model.AppError { 217 if err := a.writeLdapFile(model.LDAP_PRIVATE_KEY_NAME, fileData); err != nil { 218 return err 219 } 220 221 cfg := a.Config().Clone() 222 *cfg.LdapSettings.PrivateKeyFile = model.LDAP_PRIVATE_KEY_NAME 223 224 if err := cfg.IsValid(); err != nil { 225 return err 226 } 227 228 a.UpdateConfig(func(dest *model.Config) { *dest = *cfg }) 229 230 return nil 231 } 232 233 func (a *App) removeLdapFile(filename string) *model.AppError { 234 if err := a.Srv().configStore.RemoveFile(filename); err != nil { 235 return model.NewAppError("RemoveLdapFile", "api.admin.remove_certificate.delete.app_error", map[string]interface{}{"Filename": filename}, err.Error(), http.StatusInternalServerError) 236 } 237 return nil 238 } 239 240 func (a *App) RemoveLdapPublicCertificate() *model.AppError { 241 if err := a.removeLdapFile(*a.Config().LdapSettings.PublicCertificateFile); err != nil { 242 return err 243 } 244 245 cfg := a.Config().Clone() 246 *cfg.LdapSettings.PublicCertificateFile = "" 247 248 if err := cfg.IsValid(); err != nil { 249 return err 250 } 251 252 a.UpdateConfig(func(dest *model.Config) { *dest = *cfg }) 253 254 return nil 255 } 256 257 func (a *App) RemoveLdapPrivateCertificate() *model.AppError { 258 if err := a.removeLdapFile(*a.Config().LdapSettings.PrivateKeyFile); err != nil { 259 return err 260 } 261 262 cfg := a.Config().Clone() 263 *cfg.LdapSettings.PrivateKeyFile = "" 264 265 if err := cfg.IsValid(); err != nil { 266 return err 267 } 268 269 a.UpdateConfig(func(dest *model.Config) { *dest = *cfg }) 270 271 return nil 272 }