Allow clients to change password

This commit is contained in:
Torjus Håkestad 2021-12-06 06:53:49 +01:00
parent 67b3214276
commit 6f91ac3d2d
8 changed files with 284 additions and 70 deletions

View File

@ -338,3 +338,47 @@ func ActionClientLogin(c *cli.Context) error {
return nil
}
func ActionClientChangePassword(c *cli.Context) error {
cfg, err := getConfig(c)
if err != nil {
return err
}
addr := cfg.Client.DefaultServer
if c.IsSet("addr") {
addr = c.String("addr")
}
clientCreds, err := cfg.Client.Creds()
if err != nil {
return err
}
conn, err := grpc.DialContext(c.Context, addr, grpc.WithTransportCredentials(clientCreds))
if err != nil {
return err
}
defer conn.Close()
fmt.Printf("current password: ")
oldPasswordBytes, err := term.ReadPassword(int(syscall.Stdin))
if err != nil {
return cli.Exit(fmt.Sprintf("unable to read password: %s", err), 1)
}
fmt.Println()
oldPassword := string(oldPasswordBytes)
fmt.Printf("new password: ")
newPasswordBytes, err := term.ReadPassword(int(syscall.Stdin))
if err != nil {
return cli.Exit(fmt.Sprintf("unable to read password: %s", err), 1)
}
fmt.Println()
newPassword := string(newPasswordBytes)
client := pb.NewUserServiceClient(conn)
if _, err := client.ChangePassword(c.Context, &pb.ChangePasswordRequest{OldPassword: oldPassword, NewPassword: newPassword}); err != nil {
return cli.Exit(fmt.Sprintf("unable to change password: %s", err), 1)
}
return nil
}

View File

@ -130,7 +130,7 @@ func ActionServe(c *cli.Context) error {
grpcServer := grpc.NewServer(
grpc.Creds(creds),
grpc.ChainUnaryInterceptor(interceptors.NewAuthInterceptor(&store.MemoryStore{})),
grpc.ChainUnaryInterceptor(interceptors.NewAuthInterceptor(userStore)),
)
pb.RegisterFileServiceServer(grpcServer, grpcFileServer)
pb.RegisterUserServiceServer(grpcServer, grpcUserServer)
@ -216,7 +216,7 @@ func initializeUsers(us store.UserStore) error {
if err := us.StoreUser(admin); err != nil {
return err
}
log.Printf("user created %s:%s", admin.Username, password)
log.Printf("user created with id %s:%s", admin.Username, password)
return nil
}

View File

@ -104,6 +104,12 @@ func main() {
},
},
{
Name: "change-password",
Usage: "Change password",
Action: actions.ActionClientChangePassword,
},
{
// TODO: Remove
Name: "config-init",
Usage: "Initialize default config",
Action: actions.ActionInitConfig,

View File

@ -1008,6 +1008,62 @@ func (x *ApproveUserRequest) GetUserId() string {
return ""
}
// Change password
type ChangePasswordRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
OldPassword string `protobuf:"bytes,1,opt,name=old_password,json=oldPassword,proto3" json:"old_password,omitempty"`
NewPassword string `protobuf:"bytes,2,opt,name=new_password,json=newPassword,proto3" json:"new_password,omitempty"`
}
func (x *ChangePasswordRequest) Reset() {
*x = ChangePasswordRequest{}
if protoimpl.UnsafeEnabled {
mi := &file_protos_ezshare_proto_msgTypes[18]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *ChangePasswordRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*ChangePasswordRequest) ProtoMessage() {}
func (x *ChangePasswordRequest) ProtoReflect() protoreflect.Message {
mi := &file_protos_ezshare_proto_msgTypes[18]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use ChangePasswordRequest.ProtoReflect.Descriptor instead.
func (*ChangePasswordRequest) Descriptor() ([]byte, []int) {
return file_protos_ezshare_proto_rawDescGZIP(), []int{18}
}
func (x *ChangePasswordRequest) GetOldPassword() string {
if x != nil {
return x.OldPassword
}
return ""
}
func (x *ChangePasswordRequest) GetNewPassword() string {
if x != nil {
return x.NewPassword
}
return ""
}
type File_Metadata struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
@ -1021,7 +1077,7 @@ type File_Metadata struct {
func (x *File_Metadata) Reset() {
*x = File_Metadata{}
if protoimpl.UnsafeEnabled {
mi := &file_protos_ezshare_proto_msgTypes[18]
mi := &file_protos_ezshare_proto_msgTypes[19]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@ -1034,7 +1090,7 @@ func (x *File_Metadata) String() string {
func (*File_Metadata) ProtoMessage() {}
func (x *File_Metadata) ProtoReflect() protoreflect.Message {
mi := &file_protos_ezshare_proto_msgTypes[18]
mi := &file_protos_ezshare_proto_msgTypes[19]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@ -1083,7 +1139,7 @@ type ListFilesResponse_ListFileInfo struct {
func (x *ListFilesResponse_ListFileInfo) Reset() {
*x = ListFilesResponse_ListFileInfo{}
if protoimpl.UnsafeEnabled {
mi := &file_protos_ezshare_proto_msgTypes[19]
mi := &file_protos_ezshare_proto_msgTypes[20]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@ -1096,7 +1152,7 @@ func (x *ListFilesResponse_ListFileInfo) String() string {
func (*ListFilesResponse_ListFileInfo) ProtoMessage() {}
func (x *ListFilesResponse_ListFileInfo) ProtoReflect() protoreflect.Message {
mi := &file_protos_ezshare_proto_msgTypes[19]
mi := &file_protos_ezshare_proto_msgTypes[20]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@ -1227,46 +1283,56 @@ var file_protos_ezshare_proto_rawDesc = []byte{
0x2e, 0x55, 0x73, 0x65, 0x72, 0x52, 0x05, 0x75, 0x73, 0x65, 0x72, 0x73, 0x22, 0x2d, 0x0a, 0x12,
0x41, 0x70, 0x70, 0x72, 0x6f, 0x76, 0x65, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65,
0x73, 0x74, 0x12, 0x17, 0x0a, 0x07, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20,
0x01, 0x28, 0x09, 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x32, 0xa5, 0x02, 0x0a, 0x0b,
0x46, 0x69, 0x6c, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x47, 0x0a, 0x0a, 0x55,
0x70, 0x6c, 0x6f, 0x61, 0x64, 0x46, 0x69, 0x6c, 0x65, 0x12, 0x1a, 0x2e, 0x65, 0x7a, 0x73, 0x68,
0x61, 0x72, 0x65, 0x2e, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x65,
0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x65, 0x7a, 0x73, 0x68, 0x61, 0x72, 0x65, 0x2e,
0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
0x73, 0x65, 0x22, 0x00, 0x12, 0x3e, 0x0a, 0x07, 0x47, 0x65, 0x74, 0x46, 0x69, 0x6c, 0x65, 0x12,
0x17, 0x2e, 0x65, 0x7a, 0x73, 0x68, 0x61, 0x72, 0x65, 0x2e, 0x47, 0x65, 0x74, 0x46, 0x69, 0x6c,
0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x65, 0x7a, 0x73, 0x68, 0x61,
0x72, 0x65, 0x2e, 0x47, 0x65, 0x74, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
0x73, 0x65, 0x22, 0x00, 0x12, 0x47, 0x0a, 0x0a, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x46, 0x69,
0x6c, 0x65, 0x12, 0x1a, 0x2e, 0x65, 0x7a, 0x73, 0x68, 0x61, 0x72, 0x65, 0x2e, 0x44, 0x65, 0x6c,
0x65, 0x74, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b,
0x2e, 0x65, 0x7a, 0x73, 0x68, 0x61, 0x72, 0x65, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x46,
0x69, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x44, 0x0a,
0x09, 0x4c, 0x69, 0x73, 0x74, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x12, 0x19, 0x2e, 0x65, 0x7a, 0x73,
0x68, 0x61, 0x72, 0x65, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x52, 0x65,
0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x65, 0x7a, 0x73, 0x68, 0x61, 0x72, 0x65, 0x2e,
0x4c, 0x69, 0x73, 0x74, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
0x65, 0x22, 0x00, 0x32, 0x95, 0x02, 0x0a, 0x0b, 0x55, 0x73, 0x65, 0x72, 0x53, 0x65, 0x72, 0x76,
0x69, 0x63, 0x65, 0x12, 0x49, 0x0a, 0x08, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x12,
0x1c, 0x2e, 0x65, 0x7a, 0x73, 0x68, 0x61, 0x72, 0x65, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74,
0x65, 0x72, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e,
0x65, 0x7a, 0x73, 0x68, 0x61, 0x72, 0x65, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72,
0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x40,
0x0a, 0x05, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x12, 0x19, 0x2e, 0x65, 0x7a, 0x73, 0x68, 0x61, 0x72,
0x65, 0x2e, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65,
0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x65, 0x7a, 0x73, 0x68, 0x61, 0x72, 0x65, 0x2e, 0x4c, 0x6f, 0x67,
0x69, 0x6e, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00,
0x12, 0x3f, 0x0a, 0x04, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x19, 0x2e, 0x65, 0x7a, 0x73, 0x68, 0x61,
0x72, 0x65, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x55, 0x73, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75,
0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x65, 0x7a, 0x73, 0x68, 0x61, 0x72, 0x65, 0x2e, 0x4c, 0x69,
0x73, 0x74, 0x55, 0x73, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22,
0x00, 0x12, 0x38, 0x0a, 0x07, 0x41, 0x70, 0x70, 0x72, 0x6f, 0x76, 0x65, 0x12, 0x1b, 0x2e, 0x65,
0x7a, 0x73, 0x68, 0x61, 0x72, 0x65, 0x2e, 0x41, 0x70, 0x70, 0x72, 0x6f, 0x76, 0x65, 0x55, 0x73,
0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0e, 0x2e, 0x65, 0x7a, 0x73, 0x68,
0x61, 0x72, 0x65, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x42, 0x23, 0x5a, 0x21, 0x67,
0x69, 0x74, 0x65, 0x61, 0x2e, 0x62, 0x65, 0x6e, 0x6e, 0x79, 0x2e, 0x64, 0x6f, 0x67, 0x2f, 0x74,
0x6f, 0x72, 0x6a, 0x75, 0x73, 0x2f, 0x65, 0x7a, 0x73, 0x68, 0x61, 0x72, 0x65, 0x2f, 0x70, 0x62,
0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
0x01, 0x28, 0x09, 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x22, 0x5d, 0x0a, 0x15, 0x43,
0x68, 0x61, 0x6e, 0x67, 0x65, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x52, 0x65, 0x71,
0x75, 0x65, 0x73, 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x6f, 0x6c, 0x64, 0x5f, 0x70, 0x61, 0x73, 0x73,
0x77, 0x6f, 0x72, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x6f, 0x6c, 0x64, 0x50,
0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x6e, 0x65, 0x77, 0x5f, 0x70,
0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x6e,
0x65, 0x77, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x32, 0xa5, 0x02, 0x0a, 0x0b, 0x46,
0x69, 0x6c, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x47, 0x0a, 0x0a, 0x55, 0x70,
0x6c, 0x6f, 0x61, 0x64, 0x46, 0x69, 0x6c, 0x65, 0x12, 0x1a, 0x2e, 0x65, 0x7a, 0x73, 0x68, 0x61,
0x72, 0x65, 0x2e, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x71,
0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x65, 0x7a, 0x73, 0x68, 0x61, 0x72, 0x65, 0x2e, 0x55,
0x70, 0x6c, 0x6f, 0x61, 0x64, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
0x65, 0x22, 0x00, 0x12, 0x3e, 0x0a, 0x07, 0x47, 0x65, 0x74, 0x46, 0x69, 0x6c, 0x65, 0x12, 0x17,
0x2e, 0x65, 0x7a, 0x73, 0x68, 0x61, 0x72, 0x65, 0x2e, 0x47, 0x65, 0x74, 0x46, 0x69, 0x6c, 0x65,
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x65, 0x7a, 0x73, 0x68, 0x61, 0x72,
0x65, 0x2e, 0x47, 0x65, 0x74, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
0x65, 0x22, 0x00, 0x12, 0x47, 0x0a, 0x0a, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x46, 0x69, 0x6c,
0x65, 0x12, 0x1a, 0x2e, 0x65, 0x7a, 0x73, 0x68, 0x61, 0x72, 0x65, 0x2e, 0x44, 0x65, 0x6c, 0x65,
0x74, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e,
0x65, 0x7a, 0x73, 0x68, 0x61, 0x72, 0x65, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x46, 0x69,
0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x44, 0x0a, 0x09,
0x4c, 0x69, 0x73, 0x74, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x12, 0x19, 0x2e, 0x65, 0x7a, 0x73, 0x68,
0x61, 0x72, 0x65, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x71,
0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x65, 0x7a, 0x73, 0x68, 0x61, 0x72, 0x65, 0x2e, 0x4c,
0x69, 0x73, 0x74, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
0x22, 0x00, 0x32, 0xd9, 0x02, 0x0a, 0x0b, 0x55, 0x73, 0x65, 0x72, 0x53, 0x65, 0x72, 0x76, 0x69,
0x63, 0x65, 0x12, 0x49, 0x0a, 0x08, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x12, 0x1c,
0x2e, 0x65, 0x7a, 0x73, 0x68, 0x61, 0x72, 0x65, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65,
0x72, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x65,
0x7a, 0x73, 0x68, 0x61, 0x72, 0x65, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x55,
0x73, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x40, 0x0a,
0x05, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x12, 0x19, 0x2e, 0x65, 0x7a, 0x73, 0x68, 0x61, 0x72, 0x65,
0x2e, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
0x74, 0x1a, 0x1a, 0x2e, 0x65, 0x7a, 0x73, 0x68, 0x61, 0x72, 0x65, 0x2e, 0x4c, 0x6f, 0x67, 0x69,
0x6e, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12,
0x3f, 0x0a, 0x04, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x19, 0x2e, 0x65, 0x7a, 0x73, 0x68, 0x61, 0x72,
0x65, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x55, 0x73, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65,
0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x65, 0x7a, 0x73, 0x68, 0x61, 0x72, 0x65, 0x2e, 0x4c, 0x69, 0x73,
0x74, 0x55, 0x73, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00,
0x12, 0x38, 0x0a, 0x07, 0x41, 0x70, 0x70, 0x72, 0x6f, 0x76, 0x65, 0x12, 0x1b, 0x2e, 0x65, 0x7a,
0x73, 0x68, 0x61, 0x72, 0x65, 0x2e, 0x41, 0x70, 0x70, 0x72, 0x6f, 0x76, 0x65, 0x55, 0x73, 0x65,
0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0e, 0x2e, 0x65, 0x7a, 0x73, 0x68, 0x61,
0x72, 0x65, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x42, 0x0a, 0x0e, 0x43, 0x68,
0x61, 0x6e, 0x67, 0x65, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x12, 0x1e, 0x2e, 0x65,
0x7a, 0x73, 0x68, 0x61, 0x72, 0x65, 0x2e, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x50, 0x61, 0x73,
0x73, 0x77, 0x6f, 0x72, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0e, 0x2e, 0x65,
0x7a, 0x73, 0x68, 0x61, 0x72, 0x65, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x42, 0x23,
0x5a, 0x21, 0x67, 0x69, 0x74, 0x65, 0x61, 0x2e, 0x62, 0x65, 0x6e, 0x6e, 0x79, 0x2e, 0x64, 0x6f,
0x67, 0x2f, 0x74, 0x6f, 0x72, 0x6a, 0x75, 0x73, 0x2f, 0x65, 0x7a, 0x73, 0x68, 0x61, 0x72, 0x65,
0x2f, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
@ -1282,7 +1348,7 @@ func file_protos_ezshare_proto_rawDescGZIP() []byte {
}
var file_protos_ezshare_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
var file_protos_ezshare_proto_msgTypes = make([]protoimpl.MessageInfo, 20)
var file_protos_ezshare_proto_msgTypes = make([]protoimpl.MessageInfo, 21)
var file_protos_ezshare_proto_goTypes = []interface{}{
(User_Role)(0), // 0: ezshare.User.Role
(*Empty)(nil), // 1: ezshare.Empty
@ -1303,20 +1369,21 @@ var file_protos_ezshare_proto_goTypes = []interface{}{
(*ListUsersRequest)(nil), // 16: ezshare.ListUsersRequest
(*ListUsersResponse)(nil), // 17: ezshare.ListUsersResponse
(*ApproveUserRequest)(nil), // 18: ezshare.ApproveUserRequest
(*File_Metadata)(nil), // 19: ezshare.File.Metadata
(*ListFilesResponse_ListFileInfo)(nil), // 20: ezshare.ListFilesResponse.ListFileInfo
(*timestamppb.Timestamp)(nil), // 21: google.protobuf.Timestamp
(*ChangePasswordRequest)(nil), // 19: ezshare.ChangePasswordRequest
(*File_Metadata)(nil), // 20: ezshare.File.Metadata
(*ListFilesResponse_ListFileInfo)(nil), // 21: ezshare.ListFilesResponse.ListFileInfo
(*timestamppb.Timestamp)(nil), // 22: google.protobuf.Timestamp
}
var file_protos_ezshare_proto_depIdxs = []int32{
19, // 0: ezshare.File.metadata:type_name -> ezshare.File.Metadata
21, // 1: ezshare.UploadFileRequest.expires_on:type_name -> google.protobuf.Timestamp
20, // 0: ezshare.File.metadata:type_name -> ezshare.File.Metadata
22, // 1: ezshare.UploadFileRequest.expires_on:type_name -> google.protobuf.Timestamp
2, // 2: ezshare.GetFileResponse.file:type_name -> ezshare.File
20, // 3: ezshare.ListFilesResponse.files:type_name -> ezshare.ListFilesResponse.ListFileInfo
21, // 3: ezshare.ListFilesResponse.files:type_name -> ezshare.ListFilesResponse.ListFileInfo
0, // 4: ezshare.User.user_role:type_name -> ezshare.User.Role
11, // 5: ezshare.ListUsersResponse.users:type_name -> ezshare.User
21, // 6: ezshare.File.Metadata.uploaded_on:type_name -> google.protobuf.Timestamp
21, // 7: ezshare.File.Metadata.expires_on:type_name -> google.protobuf.Timestamp
19, // 8: ezshare.ListFilesResponse.ListFileInfo.metadata:type_name -> ezshare.File.Metadata
22, // 6: ezshare.File.Metadata.uploaded_on:type_name -> google.protobuf.Timestamp
22, // 7: ezshare.File.Metadata.expires_on:type_name -> google.protobuf.Timestamp
20, // 8: ezshare.ListFilesResponse.ListFileInfo.metadata:type_name -> ezshare.File.Metadata
3, // 9: ezshare.FileService.UploadFile:input_type -> ezshare.UploadFileRequest
5, // 10: ezshare.FileService.GetFile:input_type -> ezshare.GetFileRequest
7, // 11: ezshare.FileService.DeleteFile:input_type -> ezshare.DeleteFileRequest
@ -1325,16 +1392,18 @@ var file_protos_ezshare_proto_depIdxs = []int32{
14, // 14: ezshare.UserService.Login:input_type -> ezshare.LoginUserRequest
16, // 15: ezshare.UserService.List:input_type -> ezshare.ListUsersRequest
18, // 16: ezshare.UserService.Approve:input_type -> ezshare.ApproveUserRequest
4, // 17: ezshare.FileService.UploadFile:output_type -> ezshare.UploadFileResponse
6, // 18: ezshare.FileService.GetFile:output_type -> ezshare.GetFileResponse
8, // 19: ezshare.FileService.DeleteFile:output_type -> ezshare.DeleteFileResponse
10, // 20: ezshare.FileService.ListFiles:output_type -> ezshare.ListFilesResponse
13, // 21: ezshare.UserService.Register:output_type -> ezshare.RegisterUserResponse
15, // 22: ezshare.UserService.Login:output_type -> ezshare.LoginUserResponse
17, // 23: ezshare.UserService.List:output_type -> ezshare.ListUsersResponse
1, // 24: ezshare.UserService.Approve:output_type -> ezshare.Empty
17, // [17:25] is the sub-list for method output_type
9, // [9:17] is the sub-list for method input_type
19, // 17: ezshare.UserService.ChangePassword:input_type -> ezshare.ChangePasswordRequest
4, // 18: ezshare.FileService.UploadFile:output_type -> ezshare.UploadFileResponse
6, // 19: ezshare.FileService.GetFile:output_type -> ezshare.GetFileResponse
8, // 20: ezshare.FileService.DeleteFile:output_type -> ezshare.DeleteFileResponse
10, // 21: ezshare.FileService.ListFiles:output_type -> ezshare.ListFilesResponse
13, // 22: ezshare.UserService.Register:output_type -> ezshare.RegisterUserResponse
15, // 23: ezshare.UserService.Login:output_type -> ezshare.LoginUserResponse
17, // 24: ezshare.UserService.List:output_type -> ezshare.ListUsersResponse
1, // 25: ezshare.UserService.Approve:output_type -> ezshare.Empty
1, // 26: ezshare.UserService.ChangePassword:output_type -> ezshare.Empty
18, // [18:27] is the sub-list for method output_type
9, // [9:18] is the sub-list for method input_type
9, // [9:9] is the sub-list for extension type_name
9, // [9:9] is the sub-list for extension extendee
0, // [0:9] is the sub-list for field type_name
@ -1563,7 +1632,7 @@ func file_protos_ezshare_proto_init() {
}
}
file_protos_ezshare_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*File_Metadata); i {
switch v := v.(*ChangePasswordRequest); i {
case 0:
return &v.state
case 1:
@ -1575,6 +1644,18 @@ func file_protos_ezshare_proto_init() {
}
}
file_protos_ezshare_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*File_Metadata); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_protos_ezshare_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*ListFilesResponse_ListFileInfo); i {
case 0:
return &v.state
@ -1593,7 +1674,7 @@ func file_protos_ezshare_proto_init() {
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_protos_ezshare_proto_rawDesc,
NumEnums: 1,
NumMessages: 20,
NumMessages: 21,
NumExtensions: 0,
NumServices: 2,
},

View File

@ -216,6 +216,7 @@ type UserServiceClient interface {
Login(ctx context.Context, in *LoginUserRequest, opts ...grpc.CallOption) (*LoginUserResponse, error)
List(ctx context.Context, in *ListUsersRequest, opts ...grpc.CallOption) (*ListUsersResponse, error)
Approve(ctx context.Context, in *ApproveUserRequest, opts ...grpc.CallOption) (*Empty, error)
ChangePassword(ctx context.Context, in *ChangePasswordRequest, opts ...grpc.CallOption) (*Empty, error)
}
type userServiceClient struct {
@ -262,6 +263,15 @@ func (c *userServiceClient) Approve(ctx context.Context, in *ApproveUserRequest,
return out, nil
}
func (c *userServiceClient) ChangePassword(ctx context.Context, in *ChangePasswordRequest, opts ...grpc.CallOption) (*Empty, error) {
out := new(Empty)
err := c.cc.Invoke(ctx, "/ezshare.UserService/ChangePassword", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
// UserServiceServer is the server API for UserService service.
// All implementations must embed UnimplementedUserServiceServer
// for forward compatibility
@ -270,6 +280,7 @@ type UserServiceServer interface {
Login(context.Context, *LoginUserRequest) (*LoginUserResponse, error)
List(context.Context, *ListUsersRequest) (*ListUsersResponse, error)
Approve(context.Context, *ApproveUserRequest) (*Empty, error)
ChangePassword(context.Context, *ChangePasswordRequest) (*Empty, error)
mustEmbedUnimplementedUserServiceServer()
}
@ -289,6 +300,9 @@ func (UnimplementedUserServiceServer) List(context.Context, *ListUsersRequest) (
func (UnimplementedUserServiceServer) Approve(context.Context, *ApproveUserRequest) (*Empty, error) {
return nil, status.Errorf(codes.Unimplemented, "method Approve not implemented")
}
func (UnimplementedUserServiceServer) ChangePassword(context.Context, *ChangePasswordRequest) (*Empty, error) {
return nil, status.Errorf(codes.Unimplemented, "method ChangePassword not implemented")
}
func (UnimplementedUserServiceServer) mustEmbedUnimplementedUserServiceServer() {}
// UnsafeUserServiceServer may be embedded to opt out of forward compatibility for this service.
@ -374,6 +388,24 @@ func _UserService_Approve_Handler(srv interface{}, ctx context.Context, dec func
return interceptor(ctx, in, info, handler)
}
func _UserService_ChangePassword_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(ChangePasswordRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(UserServiceServer).ChangePassword(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/ezshare.UserService/ChangePassword",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(UserServiceServer).ChangePassword(ctx, req.(*ChangePasswordRequest))
}
return interceptor(ctx, in, info, handler)
}
// UserService_ServiceDesc is the grpc.ServiceDesc for UserService service.
// It's only intended for direct use with grpc.RegisterService,
// and not to be introspected or modified (even as a copy)
@ -397,6 +429,10 @@ var UserService_ServiceDesc = grpc.ServiceDesc{
MethodName: "Approve",
Handler: _UserService_Approve_Handler,
},
{
MethodName: "ChangePassword",
Handler: _UserService_ChangePassword_Handler,
},
},
Streams: []grpc.StreamDesc{},
Metadata: "protos/ezshare.proto",

View File

@ -121,9 +121,17 @@ message ApproveUserRequest {
string user_id = 1;
}
// Change password
message ChangePasswordRequest {
string old_password = 1;
string new_password = 2;
}
service UserService {
rpc Register(RegisterUserRequest) returns (RegisterUserResponse) {}
rpc Login(LoginUserRequest) returns (LoginUserResponse) {}
rpc List(ListUsersRequest) returns (ListUsersResponse) {}
rpc Approve(ApproveUserRequest) returns (Empty) {}
rpc ChangePassword(ChangePasswordRequest) returns (Empty) {}
}

View File

@ -2,7 +2,6 @@ package interceptors
import (
"context"
"fmt"
"gitea.benny.dog/torjus/ezshare/pb"
"gitea.benny.dog/torjus/ezshare/store"
@ -14,14 +13,15 @@ import (
type ContextKey string
var ContextKeyRole ContextKey = "role"
var ContextKeyUserID ContextKey = "userid"
func NewAuthInterceptor(s store.UserStore) grpc.UnaryServerInterceptor {
// TODO: Verify that cert is signed by our ca
return func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (resp interface{}, err error) {
p, ok := peer.FromContext(ctx)
if ok {
tlsInfo, ok := p.AuthInfo.(credentials.TLSInfo)
if ok {
fmt.Printf("%+v\n", tlsInfo.State.PeerCertificates[0].Subject.CommonName)
if len(tlsInfo.State.PeerCertificates) == 1 {
cert := tlsInfo.State.PeerCertificates[0]
@ -30,6 +30,7 @@ func NewAuthInterceptor(s store.UserStore) grpc.UnaryServerInterceptor {
user, err := s.GetUser(id)
if err == nil {
newCtx := context.WithValue(ctx, ContextKeyRole, user.UserRole)
newCtx = context.WithValue(newCtx, ContextKeyUserID, user.Id)
return handler(newCtx, req)
}
}
@ -53,3 +54,15 @@ func RoleFromContext(ctx context.Context) pb.User_Role {
}
return pb.User_UNKNOWN
}
func UserIDFromContext(ctx context.Context) string {
value := ctx.Value(ContextKeyUserID)
if value == nil {
return ""
}
id, ok := value.(string)
if ok {
return id
}
return ""
}

View File

@ -6,6 +6,7 @@ import (
"gitea.benny.dog/torjus/ezshare/certs"
"gitea.benny.dog/torjus/ezshare/pb"
"gitea.benny.dog/torjus/ezshare/server/interceptors"
"gitea.benny.dog/torjus/ezshare/store"
"github.com/google/uuid"
"golang.org/x/crypto/bcrypt"
@ -81,6 +82,31 @@ func (s *GRPCUserServiceServer) Approve(_ context.Context, _ *pb.ApproveUserRequ
return nil, status.Error(codes.Unimplemented, "not yet implemented")
}
func (s *GRPCUserServiceServer) ChangePassword(ctx context.Context, req *pb.ChangePasswordRequest) (*pb.Empty, error) {
// Get ID from ctx
userID := interceptors.UserIDFromContext(ctx)
if userID == "" {
return nil, status.Error(codes.Unauthenticated, "not authenticated")
}
user, err := s.store.GetUser(userID)
if err != nil {
return nil, status.Error(codes.Unauthenticated, "user not found")
}
if err := bcrypt.CompareHashAndPassword(user.HashedPassword, []byte(req.OldPassword)); err != nil {
return nil, status.Error(codes.Unauthenticated, "wrong password")
}
newPasswordHash, err := bcrypt.GenerateFromPassword([]byte(req.NewPassword), bcrypt.DefaultCost)
if err != nil {
return nil, status.Error(codes.Internal, "unable to hash new password")
}
user.HashedPassword = newPasswordHash
if err := s.store.StoreUser(user); err != nil {
return nil, status.Error(codes.Internal, "unable to store new password")
}
return &pb.Empty{}, nil
}
func hashPassword(password string) ([]byte, error) {
return bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
}