Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Case insensitive identity names #5404

Merged
merged 8 commits into from
Oct 19, 2018
Merged

Conversation

vishalnayak
Copy link
Member

@vishalnayak vishalnayak commented Sep 26, 2018

No description provided.

@vishalnayak vishalnayak added this to the 0.11.2 milestone Sep 27, 2018
@vishalnayak vishalnayak changed the title [WIP] Case insensitive identity names Case insensitive identity names Sep 27, 2018
@vishalnayak
Copy link
Member Author

This is ready for review. Did some upgrade testing as well and it all seems to work as intended.

Copy link
Contributor

@tyrannosaurus-becks tyrannosaurus-becks left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks excellent, nice work @vishalnayak .

@@ -203,7 +200,7 @@ func (i *IdentityStore) handleAliasUpdateCommon() framework.OperationFunc {
// If we can look up by the given canonical ID, see if this is a
// transfer; otherwise if we found no previous entity but we find one
// here, use it.
canonicalEntity, err := i.MemDBEntityByID(canonicalID, true)
canonicalEntity, err := i.MemDBEntityByID(canonicalID, false)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm curious why this was flipped to false.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It was something I was trying while investigating an issue and had forgot to flip back. You pointed out a potential bug. Thanks! Fixed it.

return err
}
if groupByName != nil && !i.core.disableCaseInsensitiveIdentityNames {
return fmt.Errorf(`Duplicate group names %q and %q.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove capitalization.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

return nil
}
if entityByName != nil && !i.core.disableCaseInsensitiveIdentityNames {
return fmt.Errorf(`Duplicate entity names %q and %q.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove capitalization.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

@@ -244,11 +277,20 @@ func (i *IdentityStore) upsertEntityInTxn(ctx context.Context, txn *memdb.Txn, e
return nil
}

if strutil.StrListContains(aliasFactors, i.sanitizeName(alias.Name)+alias.MountAccessor) && !i.core.disableCaseInsensitiveIdentityNames {
return fmt.Errorf(`Duplicate alias factors name=%q mount_accessor=%q for entity name %q.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove capitalization.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

testAliasName := "testAliasName"

// Create a case sensitive alias name
// Create a case sensitive alias name
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Duplicate.

@kalafut
Copy link
Contributor

kalafut commented Sep 28, 2018

Just some minor observations, otherwise it looks good!

kalafut
kalafut previously approved these changes Sep 28, 2018
if err != nil || (resp != nil && resp.IsError()) {
t.Fatalf("bad: err:%v\nresp: %#v", err, resp)
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps test for actual vs expected value once more after the group alias has been updated.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done, for both entity and group alias tests.

@@ -455,6 +473,7 @@ func (i *IdentityStore) CreateOrFetchEntity(ctx context.Context, alias *logical.
newAlias := &identity.Alias{
CanonicalID: entity.ID,
Name: alias.Name,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we sanitize the name here?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nope. We don't need to sanitize here. It is done in the utility that inserts item into memdb.

@@ -138,6 +138,7 @@ func (i *IdentityStore) handleAliasUpdateCommon() framework.OperationFunc {
}
} else {
alias.Name = aliasName
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same, should we sanitize this here?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here. We don't need to sanitize here.

@@ -214,6 +214,8 @@ func (i *IdentityStore) handleEntityUpdateCommon() framework.OperationFunc {

if entityName != "" {
entity.Name = entityName
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same, should we sanitize here?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nope.

@@ -225,6 +225,7 @@ func (i *IdentityStore) handleGroupUpdateCommon(ctx context.Context, req *logica
return logical.ErrorResponse("group name is already in use"), nil
}
group.Name = groupName
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same, should we sanitize here?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nope.

identity names are treated case insensitively unless
'disable_case_insensitive_identity_names' config is set`,
group.NameRaw, groupByName.NameRaw)
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is likely to happen during upgrade right? Would this halt startup?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This worries me a bit, I wonder if there is a better escape hatch we can offer. It seems to me it's likely that many existing installations will hit this issue and need to disable case insensitivity, which defeats the purpose of making it case sensitive.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes this would happen during upgrade. The goal was to switch over all identity names to be case insensitive for good. It would still work seemlessly for those who are using case sensitive names. The conflict would only arise if there are duplicate names with different casings for entities, groups and/or respective aliases. In that case, they will have to set this flag to continue operating as they would. Or, they could set this flag, remove the duplicate items, and reset the flag to get along with the regular flow.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should get a mention in the upgrade notes.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think if disable is set, we should detect and warn. That way people can set the flag, start up, see if anything is in conflict, take appropriate action.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is no flag now. So, the above discussion is not required.

@chrishoffman chrishoffman modified the milestones: 0.11.2, next-release Oct 2, 2018
@vishalnayak vishalnayak force-pushed the case-insensitive-identity-names branch from 2eda462 to 750917d Compare October 2, 2018 21:18
// If it succeeds, all is well
return nil
case err != nil && !errwrap.ContainsType(err, errDuplicateIdentityName):
// Return all errors except one
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What does this comment mean, are there multiple errors that we expect?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It meant to return all the errors expect when error contains errDuplicateIdentityName.

if err != nil {
return err
}

return nil
c.identityStore.logger.Warn("enabling case sensitive identity names")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we move this to L52? It would make the error from resetDB above more clear (i.e. error is related to switching over to handling case sensitive names).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

return nil
c.identityStore.logger.Warn("enabling case sensitive identity names")

// Load everything from the beginning.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"Attempt to load artifacts once more after memdb is reset to accept case sensitive names" might be more clear since it was called already once before.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

vault/identity_store_util.go Show resolved Hide resolved
@chrishoffman chrishoffman modified the milestones: next-release, 0.12 Oct 9, 2018
@@ -181,10 +181,6 @@ func (i *IdentityStore) handleAliasUpdateCommon() framework.OperationFunc {
if entity == nil {
return nil, fmt.Errorf("existing alias is not associated with an entity")
}
if canonicalID == "" || entity.ID == canonicalID {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this taken out?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is to ensure that we always update the alias. This is useful when an existing alias name is updated with its casing altered.

@@ -255,6 +251,12 @@ func (i *IdentityStore) handleAliasUpdateCommon() framework.OperationFunc {
return nil, err
}

for index, item := range entity.Aliases {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same, can you explain what this change is for?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All the updates are held by the alias object. This is where we reflect those changes in the entity.

case err == nil:
// If it succeeds, all is well
return nil
case err != nil && !errwrap.ContainsType(err, errDuplicateIdentityName):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think ContainsType does what you think it does here, which makes me wonder if this works properly. ContainsType is supposed to be used to validate a typed error, which means this will likely match against any error generated via errors.New. You probably want .Contains()

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wow. This is a nice observation. Fixed. But the code was working properly because the code expecting a true and ContainsType (as you said) was returning true. There wasn't a different error there to catch. I tested it by overwriting the err returned from loadFunc and verified that its getting caught properly now.

if err != nil {
return err
}
if groupByName != nil && !i.disableLowerCasedNames {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What happens if a group is found and lower caes names are disabled? That's also an error condition but won't be covered here.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When a group is found and when lower cased names are disabled, it means that we are falling back to the original behavior, and we are okay with the existence of another group. It is not an error condition. It would only mean that another group with same but differently cased name exists.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be good to warn in that case just as with entity names -- that way they can try to address the issue.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There was a warning with only one item that lead to the conflict. But your suggestion helps identify all the conflicting items after switching over to the case sensitive way. Nice observation. Fixed.

briankassouf
briankassouf previously approved these changes Oct 19, 2018
Copy link
Contributor

@briankassouf briankassouf left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just one very small comment, otherwise looks great!

return err
}
if groupByName != nil {
i.logger.Warn(errDuplicateIdentityName.Error(), "group_name", group.Name, "conflicting_group_name", groupByName.Name)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we give an actionable here and in the same log line bellow? Something like, please merge these groups or rename one

@vishalnayak vishalnayak merged commit fabe1d9 into master Oct 19, 2018
@vishalnayak vishalnayak deleted the case-insensitive-identity-names branch October 19, 2018 19:47
@jefferai jefferai modified the milestones: 0.12, 0.11.4 Oct 22, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants