server/service/rbac/password.go (78 lines of code) (raw):

/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package rbac import ( "context" "fmt" "github.com/apache/servicecomb-service-center/pkg/log" "github.com/apache/servicecomb-service-center/pkg/privacy" "github.com/apache/servicecomb-service-center/pkg/util" "github.com/apache/servicecomb-service-center/server/service/validator" "github.com/go-chassis/cari/discovery" "github.com/go-chassis/cari/rbac" ) func ChangePassword(ctx context.Context, a *rbac.Account) error { err := validator.ValidateChangePWD(a) if err != nil { return discovery.NewError(discovery.ErrInvalidParams, err.Error()) } changer, err := AccountFromContext(ctx) if err != nil { return discovery.NewError(discovery.ErrInternal, err.Error()) } // change self password, need to check password mismatch if changer.Name == a.Name { return changePassword(ctx, a.Name, a.CurrentPassword, a.Password) } // change other user's password, only admin role can do this and no need // supply current password for _, r := range changer.Roles { if r == rbac.RoleAdmin { return changePasswordForcibly(ctx, a.Name, a.Password) } } // other cases, change password is forbidden return discovery.NewError(discovery.ErrForbidden, ErrNoPermChangeAccount.Error()) } func changePasswordForcibly(ctx context.Context, name, pwd string) error { old, err := GetAccount(ctx, name) if err != nil { log.Error("can not change pwd", err) return err } return doChangePassword(ctx, old, pwd) } func changePassword(ctx context.Context, name, currentPassword, pwd string) error { if currentPassword == "" { log.Error("current pwd is empty", nil) return discovery.NewError(discovery.ErrInvalidParams, ErrEmptyCurrentPassword.Error()) } ip := util.GetIPFromContext(ctx) if IsBanned(MakeBanKey(name, ip)) { log.Warn(fmt.Sprintf("ip [%s] is banned, account: %s", ip, name)) return ErrAccountBlocked } if currentPassword == pwd { return rbac.NewError(rbac.ErrNewPwdBad, ErrSamePassword.Error()) } old, err := GetAccount(ctx, name) if err != nil { log.Error("can not change pwd", err) return err } same := privacy.SamePassword(old.Password, currentPassword) if !same { log.Error("current password is wrong", nil) TryLockAccount(MakeBanKey(name, ip)) return ErrOldPwdWrong } return doChangePassword(ctx, old, pwd) } func doChangePassword(ctx context.Context, old *rbac.Account, pwd string) error { var err error old.Password, err = privacy.ScryptPassword(pwd) if err != nil { log.Error("encrypt password failed", err) return err } err = EditAccount(ctx, old) if err != nil { log.Error("can not change pwd", err) return err } return nil }