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

Add access control feature #133

Merged
merged 1 commit into from
Mar 14, 2018

Conversation

hyangtack
Copy link
Contributor

Modifications:

  • Do access control for every v1 APIs.
  • Update metadata when do a CRUD operation for a project.
  • Build metadata if no metadata exists.
  • Administrator IDs can be specified in the configuration.
  • Add web UI for metadata management.

To-Dos:

  • Add more test cases and cleanup test cases.
  • Documentation (site)

* @param path the path of the file
* @param jsonPatchOperations the {@link JsonPatchOperation}s which would be applied
*/
static Change<JsonNode> ofJsonPatch(String path, JsonPatchOperation... jsonPatchOperations) {
Copy link
Member

Choose a reason for hiding this comment

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

JsonPatchOperation is an internal class and thus should not be exposed in our public API. How about moving this method under internal.jsonpatch?

*
* LINE Corporation 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:
*
* https://www.apache.org/licenses/LICENSE-2.0
* http://www.apache.org/licenses/LICENSE-2.0
Copy link
Member

Choose a reason for hiding this comment

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

https? Perhaps you need to update your copyright profile.

}

final JsonNode found = node.at(path);
if (!found.isMissingNode()) {
Copy link
Member

Choose a reason for hiding this comment

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

How about returning earlier?

if (found.isMissingNode()) {
    return node;
}

...

final String raw = path.last().getMatchingProperty();
if (parentNode.isObject()) {
((ObjectNode) parentNode).remove(raw);
} else {
Copy link
Member

Choose a reason for hiding this comment

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

How about:

else if (parentNode.isArray()) {
    ...
} else {
    return node;
}

public final class TestAbsenceOperation extends JsonPatchOperation {
@JsonCreator
public TestAbsenceOperation(@JsonProperty("path") final JsonPointer path) {
super("testAbsent", path);
Copy link
Member

Choose a reason for hiding this comment

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

testAbsence?

return serveMetaRepo(delegate, ctx, req, mds, user, projectName);
}

final CompletionStage<Collection<Permission>> f;
Copy link
Member

Choose a reason for hiding this comment

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

How about extracting the part after serveMetaRepo() to serveNonMetaRepo() so that it is clearer? e.g.

        if (Project.REPO_META.equals(repoName)) {
            return serveMetaRepo(delegate, ctx, req, mds, user, projectName);
        } else {
            return serveNonMetaRepo(delegate, ctx, req, mds, user, projectName);
        }


static CompletableFuture<Revision> generateSampleFiles(
CommandExecutor executor, String projectName, String repositoryName) {

if (projectName.equals(INTERNAL_PROJECT_NAME)) {
Copy link
Member

Choose a reason for hiding this comment

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

How about adding a comment:

// Do not generate sample files for internal projects.

private static CompletableFuture<Revision> initializeMetadata(CommandExecutor executor,
String projectName,
Author author) {
if (projectName.equals(INTERNAL_PROJECT_NAME)) {
Copy link
Member

Choose a reason for hiding this comment

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

Ditto

return CompletableFuture.completedFuture(Revision.INIT);
}

logger.info("Initializing metadata: {}/{}", projectName);
Copy link
Member

Choose a reason for hiding this comment

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

/{} seems unnecessary. (mismatching argument count)

* under the License.
*/
/*
* Copyright (c) 2014, Francis Galiegue (fgaliegue@gmail.com)
Copy link
Member

Choose a reason for hiding this comment

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

You don't need this if you rewrote this class.

@codecov-io
Copy link

codecov-io commented Feb 7, 2018

Codecov Report

Merging #133 into master will increase coverage by 1.72%.
The diff coverage is 69.41%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master     #133      +/-   ##
==========================================
+ Coverage    61.4%   63.12%   +1.72%     
==========================================
  Files         261      272      +11     
  Lines        8837     9374     +537     
  Branches     1027     1059      +32     
==========================================
+ Hits         5426     5917     +491     
- Misses       2801     2834      +33     
- Partials      610      623      +13
Impacted Files Coverage Δ
...traldogma/internal/jsonpatch/ReplaceOperation.java 100% <ø> (ø) ⬆️
.../internal/api/converter/WatchRequestConverter.java 70.37% <ø> (ø) ⬆️
...ecorp/centraldogma/internal/api/v1/ProjectDto.java 66.66% <ø> (ø) ⬆️
.../centraldogma/internal/jsonpatch/AddOperation.java 100% <ø> (ø) ⬆️
...centraldogma/internal/jsonpatch/MoveOperation.java 87.5% <ø> (ø) ⬆️
...centraldogma/server/internal/api/WatchService.java 78.94% <ø> (ø) ⬆️
...inecorp/centraldogma/internal/api/v1/EntryDto.java 69.69% <ø> (ø) ⬆️
...necorp/centraldogma/internal/api/v1/CommitDto.java 64.7% <ø> (ø) ⬆️
.../internal/api/v1/CommitMessageDtoDeserializer.java 72.72% <ø> (ø) ⬆️
...dogma/internal/jsonpatch/SafeReplaceOperation.java 89.65% <ø> (ø) ⬆️
... and 102 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 2d6b9eb...d8874e8. Read the comment docs.

@hyangtack hyangtack force-pushed the feature/add_access_control_rev2 branch 4 times, most recently from 4255a84 to 679655d Compare February 12, 2018 09:56
* <p>This operation only takes one pointer ({@code path}) as an argument. It
* is an error condition if no JSON value exists at that pointer.</p>
*/
public final class RemoveIfExistsOperation extends JsonPatchOperation {
Copy link
Member

Choose a reason for hiding this comment

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

How about adding a test case?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Added

import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.jsontype.TypeSerializer;

public final class TestAbsenceOperation extends JsonPatchOperation {
Copy link
Member

Choose a reason for hiding this comment

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

How about adding a test case?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Added

@@ -3,4 +3,4 @@ distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.5.1-all.zip
distributionSha256Sum=ede2333b509ab67e4b6f51adb1419870fb34bbead0c8357dd803532b531508eb
distributionSha256Sum=ede2333b509ab67e4b6f51adb1419870fb34bbead0c8357dd803532b531508eb
Copy link
Member

Choose a reason for hiding this comment

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

Probably better reverting?

* Configures the list of administrators.
*/
public CentralDogmaBuilder administrators(String... administrators) {
this.administrators = ImmutableSet.copyOf(administrators);
Copy link
Member

Choose a reason for hiding this comment

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

requireNonNull(administrators, "administrators")

* Configures the list of administrators.
*/
public CentralDogmaBuilder administrators(Iterable<String> administrators) {
this.administrators = ImmutableSet.copyOf(administrators);
Copy link
Member

Choose a reason for hiding this comment

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

requireNonNull(administrators, "administrators")

@@ -167,6 +168,10 @@ Core properties
this, Central Dogma will reject to mirror the Git repository. If ``null``, the default value of
'33554432 bytes' (32 MiB) is used.

- ``administrators`` (set of string)

- the set of administrator's ID. They are valid only if ``securityEnabled`` is ``true``.
Copy link
Member

Choose a reason for hiding this comment

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

the set of administrator's ID -> the user names (or ID) of administrators?

}

Next, configure ``conf/shiro.ini`` based on your authentication system. A local database system of `Apache Shiro`_
is used here to show you a simple example::
Copy link
Member

Choose a reason for hiding this comment

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

How about mentioning that a user can also configure Shiro to enable authentication using LDAP or RDBMS as well?

Copy link
Contributor Author

@hyangtack hyangtack Feb 13, 2018

Choose a reason for hiding this comment

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

Added as a note

Notification.error({
message: message,
templateUrl: 'scripts/components/util/notification-template-with-login.html'
});
} else if (arg.status === 403) {
// TODO(hyangtack) Refine the error message.
Notification.error('You have no permission');
Copy link
Member

Choose a reason for hiding this comment

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

missing period? or Permission denied

return defer.promise;
}
}
});
Copy link
Member

Choose a reason for hiding this comment

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

Should end with a newline

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed

<button class="btn btn-primary"
ng-click="modalOptions.ok();">{{ 'components.button_yes' | translate }}
</button>
</div>
Copy link
Member

Choose a reason for hiding this comment

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

Should end with a newline

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed

@hyangtack hyangtack force-pushed the feature/add_access_control_rev2 branch 2 times, most recently from e57e13b to 869e14e Compare February 13, 2018 08:33
@hyangtack
Copy link
Contributor Author

hyangtack commented Feb 13, 2018

@trustin I think I addressed every comment you mentioned. Please let me know if there is any comment I missed. Also, I fixed the followings:

  • Fixed UI for project list. Added a list of removed projects and the button which restores each project.
  • Fixed UI for project metadata. Added a button which removes the project.
  • Allow everyone to create project from now on. Also fixed the document related to the changes. (As you know, only the administrators were able to do it before)

import com.linecorp.centraldogma.server.internal.metadata.Token;

/**
* A {@link User} which accesses the API with a secret.
Copy link
Member

Choose a reason for hiding this comment

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

with a token?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

secret is correct here because API requests will be sent with a secret and a token will be found by the secret.

}

/**
* PUT /metadata/{projectName}/tokens
Copy link
Member

Choose a reason for hiding this comment

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

Need to update.

/**
* PUT /metadata/{projectName}/tokens
*
* <p>Updates the {@link PerRolePermissions} of the specified {@code projectName} and {@code repoName}.
Copy link
Member

Choose a reason for hiding this comment

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

of the specified {@code repoName} in the {@code projectName}?

/**
* POST /metadata/{projectName}/repos/{repoName}/perm/users
*
* <p>Adds {@link Permission}s of the specific users to the specified {@code projectName} and
Copy link
Member

Choose a reason for hiding this comment

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

ditto

}

/**
* PUT /metadata/{projectName}/repos/{repoName}/perm/users
Copy link
Member

Choose a reason for hiding this comment

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

Need to update

}

/**
* PUT /metadata/{projectName}/repos/{repoName}/perm/tokens
Copy link
Member

Choose a reason for hiding this comment

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

Need to update

*
* <p>Updates the {@link PerRolePermissions} of the specified {@code projectName} and {@code repoName}.
*/
@Put("/metadata/{projectName}/repos/{repoName}/perm/role")
Copy link
Member

@minwoox minwoox Feb 14, 2018

Choose a reason for hiding this comment

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

Put method without the identifier at the end looks weird to me...

How about @Put("/metadata/{projectName}/rolePermission/repos/{repoName}")?
I think this is updating the rolePermission of the specific repository, so repoName should be at the last.
Also I think we do not have to define the path as same with the API updating perUserPermissions and perTokenPermissions since this has no identifier(Updating the whole permission).
WDYT?

Please, forget about the comment. How about just changing to POST?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I agree with you. I also think POST is more reasonable. Thanks!

public CompletionStage<ProjectInfo> removeToken(@Param("projectName") String projectName,
@Param("appId") String appId,
@Patch("/projects/{projectName}")
@Decorator(AdministratorsOnly.class)
Copy link
Member

Choose a reason for hiding this comment

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

If the owner of a project removes the project by mistake, does he/she have to ask the administrator to bring it back?

Copy link
Member

Choose a reason for hiding this comment

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

That's a good question. I wonder if the project owner is allowed to unremove his or her project.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

As we discussed in LINE chat room, it'd be better to leave this as it is. A metadata is stored in a meta repository of each project so the metadata is not able to be accessed if a project is removed, by default. That means we have no chance to find a role of a user in our authentication decorator, for now. If we want to read a metadata from a removed project, we need to make some code more, but it's not an important specification now.

@RequestObject Author author,
@RequestObject User loginUser) {
return getTokenOrRespondForbidden(appId, loginUser).thenCompose(
token -> mds.destroyToken(author, appId)
Copy link
Member

Choose a reason for hiding this comment

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

just wondering is there any reason that you used destroy instead of delete?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

removeToken() removes a token from a project. And destroyToken() removes a token from the system completely (removing it from every project and the system). So I want to make its meaning clear by using destroy instead of delete.

if (isValidEmailAddress(emailAddr)) {
return emailAddr;
}
return emailAddr + "@localhost.localdomain";
Copy link
Member

Choose a reason for hiding this comment

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

Need to raise an exception if the result is not a valid email address yet.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think I decided bad name for this method, so I changed it to toEmailAddress which means converting an argument emailAddr to an email address if it's not.

return emailAddr + "@localhost.localdomain";
}

public static String parseLogin(String emailAddr, String paramName) {
Copy link
Member

Choose a reason for hiding this comment

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

How about emailToUsername? It doesn't seem to parse but just extract in my opinion.

@@ -66,6 +66,10 @@
this.value = value.deepCopy();
}

public JsonNode value() {
Copy link
Member

Choose a reason for hiding this comment

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

This seems unused?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It's used in the MetadataApiService like the following:

final ProjectRole role = ProjectRole.of(operation.value());

/**
* POST /projects/{projectName}/members/{user}
* GET /projects/{projectName}/accessibility
Copy link
Member

Choose a reason for hiding this comment

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

The term 'accessibility' is often used for disabled people. Do we have a better term here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I will remove this API, then add checkPermissionOnly=true parameter to GET /projects/{projectName} API.

public CompletionStage<ProjectInfo> removeToken(@Param("projectName") String projectName,
@Param("appId") String appId,
@Patch("/projects/{projectName}")
@Decorator(AdministratorsOnly.class)
Copy link
Member

Choose a reason for hiding this comment

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

That's a good question. I wonder if the project owner is allowed to unremove his or her project.

@@ -75,6 +77,10 @@ public HttpResponse handleException(RequestContext ctx, HttpRequest req, Throwab
return HttpResponse.of(HttpStatus.BAD_REQUEST);
}

if (cause instanceof IllegalAccessException) {
return HttpResponse.of(HttpStatus.FORBIDDEN);
Copy link
Member

Choose a reason for hiding this comment

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

This seems unnecessary now that we throw an HttpStatusException?

*/
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonInclude(Include.NON_NULL)
public class Repo implements Identifiable {
Copy link
Member

Choose a reason for hiding this comment

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

How about RepositoryMetadata?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ok, it seems more consistent.

return future;
}

private void push0(String projectName, String repoName, Author author, String commitSummary,
Copy link
Member

Choose a reason for hiding this comment

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

Probably OK to name as push?

*/

/**
* Metadata management for projects in the Central Dogma.
Copy link
Member

Choose a reason for hiding this comment

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

for Central Dogma projects?

Authentication and Access Control
=================================

*Central Dogma* provides the features for authentication and access control.
Copy link
Member

Choose a reason for hiding this comment

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

No need to italicize


.. note::

`Apache Shiro`_ supports RDBMS or LDAP based security system as well. You can find the example configuration
Copy link
Member

Choose a reason for hiding this comment

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

system -> systems

Access Control
--------------

One of the way of configuring the access control system for *Central Dogma* is setting a project with a web UI.
Copy link
Member

Choose a reason for hiding this comment

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

  • One way to configure
  • setting a project with a web UI -> to use the web UI?

--------------

One of the way of configuring the access control system for *Central Dogma* is setting a project with a web UI.
To open the web UI, you may access ``http://{your-central-dogma-domain-or-ip}:36462`` by your web browser.
Copy link
Member

Choose a reason for hiding this comment

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

by your -> in your


One of the way of configuring the access control system for *Central Dogma* is setting a project with a web UI.
To open the web UI, you may access ``http://{your-central-dogma-domain-or-ip}:36462`` by your web browser.
You may configure a project with HTTP APIs, but we recommend the web UI because it is easier and simple.
Copy link
Member

Choose a reason for hiding this comment

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

easier and simpler

Application Token
^^^^^^^^^^^^^^^^^

When a user uses the web UI, he or she should login first to get a token for the web session. But what should a user
Copy link
Member

Choose a reason for hiding this comment

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

the web session -> a new web session

^^^^^^^^^^^^^^^^^

When a user uses the web UI, he or she should login first to get a token for the web session. But what should a user
do when he or she uses one of *Central Dogma* clients? The user may login *Central Dogma* server through HTTP login API
Copy link
Member

Choose a reason for hiding this comment

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

login... -> log in to a Central Dogma server via HTTP API


``Application Token`` is like a virtual user, so it can have any role in a project. Also, its permissions can be specified
in a repository configuration like a member. To get a new token, a user can use ``Application Tokens`` menu of the web UI.
``Application ID`` is should be unique to identify where the request is from.
Copy link
Member

Choose a reason for hiding this comment

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

  • is should be -> has to be
  • the request is from -> a client request comes from


.. image:: _images/auth_4.png

Anyone who is logged in the *Central Dogma* can create a new ``Application Token``, and the token is shared
Copy link
Member

Choose a reason for hiding this comment

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

logged into


Anyone who is logged in the *Central Dogma* can create a new ``Application Token``, and the token is shared
for everyone. So any owner of a project can add any token to their project. However only both the token creator
and the administrator are allowed to inactivate and/or remove the token.
Copy link
Member

Choose a reason for hiding this comment

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

inactivate -> deactivate

`Apache Shiro`_ supports RDBMS or LDAP based security system as well. You can find the example
configuration files under the ``conf/`` directory in the distribution.

That's all. You are ready to use the security system of Central Dogma.
Copy link
Member

Choose a reason for hiding this comment

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

Now, you are ready?

- the administrator of a project. A user who creates a project is to be an owner of the project by
default. Owners can add a user or a token as an owner or a member of the project, and can create
a new repository. Also, they can remove the repository or the project from the system and can
configure permissions for each role, a member and a token.
Copy link
Member

Choose a reason for hiding this comment

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

each role, member and token. (I think each can modifies the three nouns in the sentence.)


- ``Guest`` of a project

- users who is logged in but is neither an owner nor a member of a project. A guest is not an administrator,
Copy link
Member

Choose a reason for hiding this comment

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

How about removing the sentence A guest is not an administrator?

.. note::

Do not forget to make a new ``Application Token`` before adding a token to a project. ``Add a token``
button would be disabled if there is no token. The pencil icon on the right of the ``Tokens`` title
Copy link
Member

Choose a reason for hiding this comment

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

Tokens -> Token?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It's a title in a web UI.


Do not forget to make a new ``Application Token`` before adding a token to a project. ``Add a token``
button would be disabled if there is no token. The pencil icon on the right of the ``Tokens`` title
brings you the ``Application Token`` management page.
Copy link
Member

Choose a reason for hiding this comment

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

brings you to the?


Permissions can be specified for a repository only. So a user can configure their repositories with different
access control levels. There are only two permission types currently, which are ``READ`` and ``WRITE``.
``WRITE`` permission implies ``READ`` permission, so you cannot give only WRITE permission to a user,
Copy link
Member

Choose a reason for hiding this comment

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

How about just using contains instead of implies? I feel weird when I read the sentence.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Left this as it is because we discussed about this last week.


When a user uses the web UI, he or she should login first to get a token for a new web session. But what
should a user do when he or she uses one of Central Dogma clients? The user may log in to a Central Dogma
server via HTTP API and gets a session token. But it is inconvenient and the user may write more complicated
Copy link
Member

Choose a reason for hiding this comment

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

gets -> get? (because may is auxiliary verb here)

@trustin trustin added this to the 0.22.0 milestone Mar 5, 2018
@trustin trustin modified the milestones: 0.22.0, 0.23.0 Mar 9, 2018
Modifications:
- Do access control for every v1 APIs.
- Update metadata when do a CRUD operation for a project.
- Build metadata if no metadata exists.
- Administrator IDs can be specified in the configuration.
- Add web UI for metadata management.

To-Dos:
- Add more test cases and cleanup test cases.
- Documentation (site)
@hyangtack hyangtack force-pushed the feature/add_access_control_rev2 branch from 1451a67 to d8874e8 Compare March 14, 2018 05:28
@hyangtack hyangtack changed the title [WIP] Add access control feature Add access control feature Mar 14, 2018
@hyangtack hyangtack merged commit 260daa5 into line:master Mar 14, 2018
@hyangtack
Copy link
Contributor Author

Thanks, reviewers!

@hyangtack hyangtack deleted the feature/add_access_control_rev2 branch April 24, 2018 09:02
@hyangtack hyangtack mentioned this pull request Apr 24, 2018
minwoox added a commit to minwoox/centraldogma that referenced this pull request Aug 9, 2021
Motivation:
I found out `MigrationUtil` is not used anymore that is intruced token migration in line#133.

Modifications:
- Remove `MigrationUtil`
- Move initialization logic to `ProjectInitializer`
- Clean up some logs in `ZooKeeperCommandExecutor`

Result:
- Less code
@minwoox minwoox mentioned this pull request Aug 9, 2021
minwoox added a commit that referenced this pull request Aug 9, 2021
* Remove MigrationUtil
Motivation:
I found out `MigrationUtil` is not used anymore which is introduced token migration in #133.

Modifications:
- Remove `MigrationUtil`
- Move initialization logic to `ProjectInitializer`
- Clean up some logs in `ZooKeeperCommandExecutor`

Result:
- Less code
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants