// Check if target user has "Refuse private messages" flag
flagBitmap := big.NewInt(int64(binary.BigEndian.Uint16(otherClient.Flags)))
- if flagBitmap.Bit(UserFlagRefusePChat) == 1 {
+ if flagBitmap.Bit(UserFlagRefusePM) == 1 {
res = append(res,
*NewTransaction(
TranServerMsg,
return res, fmt.Errorf("invalid filepath encoding: %w", err)
}
- res = append(res, cc.NewReply(t,
+ fields := []Field{
NewField(FieldFileName, []byte(encodedName)),
NewField(FieldFileTypeString, fw.ffo.FlatFileInformationFork.friendlyType()),
NewField(FieldFileCreatorString, fw.ffo.FlatFileInformationFork.friendlyCreator()),
- NewField(FieldFileComment, fw.ffo.FlatFileInformationFork.Comment),
NewField(FieldFileType, fw.ffo.FlatFileInformationFork.TypeSignature),
NewField(FieldFileCreateDate, fw.ffo.FlatFileInformationFork.CreateDate),
NewField(FieldFileModifyDate, fw.ffo.FlatFileInformationFork.ModifyDate),
- NewField(FieldFileSize, fw.totalSize()),
- ))
+ }
+
+ // Include the optional FileComment field if there is a comment.
+ if len(fw.ffo.FlatFileInformationFork.Comment) != 0 {
+ fields = append(fields, NewField(FieldFileComment, fw.ffo.FlatFileInformationFork.Comment))
+ }
+
+ // Include the FileSize field for files.
+ if !bytes.Equal(fw.ffo.FlatFileInformationFork.TypeSignature, []byte{0x66, 0x6c, 0x64, 0x72}) {
+ fields = append(fields, NewField(FieldFileSize, fw.totalSize()))
+ }
+
+ res = append(res, cc.NewReply(t, fields...))
return res, err
}
newAccessLvl := t.GetField(FieldUserAccess).Data
account := cc.Server.Accounts[login]
+ if account == nil {
+ return append(res, cc.NewErrReply(t, "Account not found.")), nil
+ }
account.Name = userName
copy(account.Access[:], newAccessLvl)
if t.GetField(FieldUserPassword).Data == nil {
account.Password = hashAndSalt([]byte(""))
}
- if len(t.GetField(FieldUserPassword).Data) > 1 {
+
+ if !bytes.Equal([]byte{0}, t.GetField(FieldUserPassword).Data) {
account.Password = hashAndSalt(t.GetField(FieldUserPassword).Data)
}
if acc, ok := cc.Server.Accounts[login]; ok {
cc.logger.Infow("UpdateUser", "login", login)
- // account dataFile, so this is an update action
+ // account exists, so this is an update action
if !cc.Authorize(accessModifyUser) {
res = append(res, cc.NewErrReply(t, "You are not allowed to modify accounts."))
- return res, err
+ return res, nil
}
+ // This part is a bit tricky. There are three possibilities:
+ // 1) The transaction is intended to update the password.
+ // In this case, FieldUserPassword is sent with the new password.
+ // 2) The transaction is intended to remove the password.
+ // In this case, FieldUserPassword is not sent.
+ // 3) The transaction updates the users access bits, but not the password.
+ // In this case, FieldUserPassword is sent with zero as the only byte.
if getField(FieldUserPassword, &subFields) != nil {
newPass := getField(FieldUserPassword, &subFields).Data
- acc.Password = hashAndSalt(newPass)
+ if !bytes.Equal([]byte{0}, newPass) {
+ acc.Password = hashAndSalt(newPass)
+ }
} else {
acc.Password = hashAndSalt([]byte(""))
}
if !cc.Authorize(accessCreateUser) {
res = append(res, cc.NewErrReply(t, "You are not allowed to create new accounts."))
- return res, err
+ return res, nil
}
newAccess := accessBitmap{}
for i := 0; i < 64; i++ {
if newAccess.IsSet(i) {
if !cc.Authorize(i) {
- return append(res, cc.NewErrReply(t, "Cannot create account with more access than yourself.")), err
+ return append(res, cc.NewErrReply(t, "Cannot create account with more access than yourself.")), nil
}
}
}
- err := cc.Server.NewUser(login, string(getField(FieldUserName, &subFields).Data), string(getField(FieldUserPassword, &subFields).Data), newAccess)
+ err = cc.Server.NewUser(login, string(getField(FieldUserName, &subFields).Data), string(getField(FieldUserPassword, &subFields).Data), newAccess)
if err != nil {
- return []Transaction{}, err
+ return append(res, cc.NewErrReply(t, "Cannot create account because there is already an account with that login.")), nil
}
}
}
}
if err := cc.Server.NewUser(login, string(t.GetField(FieldUserName).Data), string(t.GetField(FieldUserPassword).Data), newAccess); err != nil {
- return []Transaction{}, err
+ res = append(res, cc.NewErrReply(t, "Cannot create account because there is already an account with that login."))
+ return res, err
}
res = append(res, cc.NewReply(t))
func HandleDeleteUser(cc *ClientConn, t *Transaction) (res []Transaction, err error) {
if !cc.Authorize(accessDeleteUser) {
res = append(res, cc.NewErrReply(t, "You are not allowed to delete accounts."))
- return res, err
+ return res, nil
}
- // TODO: Handle case where account doesn't exist; e.g. delete race condition
login := decodeString(t.GetField(FieldUserLogin).Data)
if err := cc.Server.DeleteUser(login); err != nil {