mirror of
https://github.com/google/nomulus.git
synced 2025-07-11 21:48:18 +02:00
mv com/google/domain/registry google/registry
This change renames directories in preparation for the great package rename. The repository is now in a broken state because the code itself hasn't been updated. However this should ensure that git correctly preserves history for each file.
This commit is contained in:
parent
a41677aea1
commit
5012893c1d
2396 changed files with 0 additions and 0 deletions
25
java/google/registry/groups/BUILD
Normal file
25
java/google/registry/groups/BUILD
Normal file
|
@ -0,0 +1,25 @@
|
|||
package(
|
||||
default_visibility = ["//java/com/google/domain/registry:registry_project"],
|
||||
)
|
||||
|
||||
|
||||
java_library(
|
||||
name = "groups",
|
||||
srcs = glob(["*.java"]),
|
||||
deps = [
|
||||
"//apiserving/discoverydata/admin:admin_directory_v1",
|
||||
"//apiserving/discoverydata/groupssettings",
|
||||
"//java/com/google/api/client/googleapis/auth/oauth2",
|
||||
"//java/com/google/api/client/googleapis/json",
|
||||
"//java/com/google/common/annotations",
|
||||
"//java/com/google/common/base",
|
||||
"//java/com/google/common/collect",
|
||||
"//java/com/google/domain/registry/config",
|
||||
"//java/com/google/domain/registry/request",
|
||||
"//java/com/google/domain/registry/util",
|
||||
"//third_party/java/dagger",
|
||||
"//third_party/java/joda_time",
|
||||
"//third_party/java/jsr305_annotations",
|
||||
"//third_party/java/servlet/servlet_api",
|
||||
],
|
||||
)
|
171
java/google/registry/groups/DirectoryGroupsConnection.java
Normal file
171
java/google/registry/groups/DirectoryGroupsConnection.java
Normal file
|
@ -0,0 +1,171 @@
|
|||
// Copyright 2016 The Domain Registry Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed 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 com.google.domain.registry.groups;
|
||||
|
||||
import static com.google.domain.registry.util.CollectionUtils.nullToEmpty;
|
||||
import static javax.servlet.http.HttpServletResponse.SC_CONFLICT;
|
||||
import static javax.servlet.http.HttpServletResponse.SC_NOT_FOUND;
|
||||
|
||||
import com.google.api.client.googleapis.json.GoogleJsonError;
|
||||
import com.google.api.client.googleapis.json.GoogleJsonResponseException;
|
||||
import com.google.api.services.admin.directory.Directory;
|
||||
import com.google.api.services.admin.directory.model.Group;
|
||||
import com.google.api.services.admin.directory.model.Member;
|
||||
import com.google.api.services.admin.directory.model.Members;
|
||||
import com.google.api.services.groupssettings.Groupssettings;
|
||||
import com.google.api.services.groupssettings.model.Groups;
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.google.common.base.Strings;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.domain.registry.config.ConfigModule.Config;
|
||||
import com.google.domain.registry.util.FormattingLogger;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
/**
|
||||
* Class encapsulating methods to access Google Groups API.
|
||||
*/
|
||||
public class DirectoryGroupsConnection implements GroupsConnection {
|
||||
|
||||
// NOTE: These error message strings were determined empirically. The API documentation contains
|
||||
// no mention of what happens in error conditions. Here be dragons.
|
||||
private static final String GROUP_NOT_FOUND_MSG = "Resource Not Found: groupKey";
|
||||
private static final String MEMBER_NOT_FOUND_MSG = "Resource Not Found: memberKey";
|
||||
private static final String MEMBER_ALREADY_EXISTS_MSG = "Member already exists.";
|
||||
|
||||
private static final FormattingLogger logger = FormattingLogger.getLoggerForCallerClass();
|
||||
private static final Groups defaultGroupPermissions = getDefaultGroupPermissions();
|
||||
|
||||
@VisibleForTesting
|
||||
static Groups getDefaultGroupPermissions() {
|
||||
Groups permissions = new Groups();
|
||||
permissions.setAllowExternalMembers(Boolean.TRUE.toString());
|
||||
permissions.setWhoCanPostMessage("ALL_MANAGERS_CAN_POST");
|
||||
permissions.setWhoCanViewGroup("ALL_MANAGERS_CAN_VIEW");
|
||||
permissions.setWhoCanViewMembership("ALL_MANAGERS_CAN_VIEW");
|
||||
permissions.setWhoCanJoin("INVITED_CAN_JOIN");
|
||||
permissions.setWhoCanInvite("ALL_MANAGERS_CAN_INVITE");
|
||||
return permissions;
|
||||
}
|
||||
|
||||
@Inject Directory directory;
|
||||
@Inject Groupssettings groupsSettings;
|
||||
@Inject @Config("googleAppsAdminEmailAddress") String googleAppsAdminEmailAddress;
|
||||
@Inject DirectoryGroupsConnection() {}
|
||||
|
||||
@Override
|
||||
public void addMemberToGroup(String groupKey, String email, Role role) throws IOException {
|
||||
// Documentation for this API call:
|
||||
// https://developers.google.com/admin-sdk/directory/v1/reference/members/insert
|
||||
Member member = new Member();
|
||||
member.setEmail(email);
|
||||
member.setRole(role.toString());
|
||||
try {
|
||||
directory.members().insert(groupKey, member).execute();
|
||||
} catch (GoogleJsonResponseException e) {
|
||||
// If the member is already in the group, ignore the error, get the existing member, and
|
||||
// return it.
|
||||
GoogleJsonError err = e.getDetails();
|
||||
if (err.getCode() == SC_NOT_FOUND && err.getMessage().equals(GROUP_NOT_FOUND_MSG)) {
|
||||
logger.infofmt(
|
||||
e,
|
||||
"Creating group %s during addition of member %s because the group doesn't exist.",
|
||||
groupKey,
|
||||
email);
|
||||
createGroup(groupKey);
|
||||
addMemberToGroup(groupKey, email, role);
|
||||
} else if (err.getCode() == SC_NOT_FOUND && err.getMessage().equals(MEMBER_NOT_FOUND_MSG)) {
|
||||
throw new RuntimeException(String.format(
|
||||
"Adding member %s to group %s failed because the member wasn't found.",
|
||||
email,
|
||||
groupKey), e);
|
||||
} else if (err.getCode() == SC_CONFLICT
|
||||
&& err.getMessage().equals(MEMBER_ALREADY_EXISTS_MSG)) {
|
||||
// This error case usually happens when an email address is already a member of the gorup,
|
||||
// but it is bouncing incoming emails. It won't show up in the members list API call, but
|
||||
// will throw a "Member already exists" error message if you attempt to add it again. The
|
||||
// correct thing to do is log an info message when this happens and then ignore it.
|
||||
logger.infofmt(
|
||||
e,
|
||||
"Could not add email %s to group %s because it is already a member "
|
||||
+ "(likely because the email address is bouncing incoming messages).",
|
||||
email,
|
||||
groupKey);
|
||||
} else {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeMemberFromGroup(String groupKey, String email) throws IOException {
|
||||
// Documentation for this API call:
|
||||
// https://developers.google.com/admin-sdk/directory/v1/reference/members/delete
|
||||
directory.members().delete(groupKey, email).execute();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getMembersOfGroup(String groupKey) throws IOException {
|
||||
// Documentation for this API call:
|
||||
// https://developers.google.com/admin-sdk/directory/v1/reference/members/list
|
||||
try {
|
||||
ImmutableSet.Builder<String> allMembers = new ImmutableSet.Builder<>();
|
||||
Directory.Members.List listRequest =
|
||||
directory.members().list(groupKey).setRoles(Role.MEMBER.toString());
|
||||
do {
|
||||
Members currentPage = listRequest.execute();
|
||||
for (Member member : nullToEmpty(currentPage.getMembers())) {
|
||||
allMembers.add(member.getEmail());
|
||||
}
|
||||
listRequest.setPageToken(currentPage.getNextPageToken());
|
||||
} while (!Strings.isNullOrEmpty(listRequest.getPageToken()));
|
||||
return allMembers.build();
|
||||
} catch (GoogleJsonResponseException e) {
|
||||
if (e.getDetails() != null
|
||||
&& e.getDetails().getCode() == SC_NOT_FOUND
|
||||
&& e.getDetails().getMessage().equals(GROUP_NOT_FOUND_MSG)) {
|
||||
return ImmutableSet.of();
|
||||
} else {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Group createGroup(String groupKey) throws IOException {
|
||||
// Documentation for this API call:
|
||||
// https://developers.google.com/admin-sdk/directory/v1/reference/groups/insert
|
||||
Group group = new Group();
|
||||
group.setEmail(groupKey);
|
||||
try {
|
||||
Group createdGroup = directory.groups().insert(group).execute();
|
||||
addMemberToGroup(groupKey, googleAppsAdminEmailAddress, Role.OWNER);
|
||||
groupsSettings.groups().patch(groupKey, defaultGroupPermissions).execute();
|
||||
return createdGroup;
|
||||
} catch (GoogleJsonResponseException e) {
|
||||
// Ignore the error thrown if the group already exists.
|
||||
if (e.getDetails().getCode() == SC_CONFLICT
|
||||
&& e.getDetails().getMessage().equals("Entity already exists.")) {
|
||||
logger.infofmt(e, "Could not create group %s because it already exists.", groupKey);
|
||||
return directory.groups().get(groupKey).execute();
|
||||
} else {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
62
java/google/registry/groups/DirectoryModule.java
Normal file
62
java/google/registry/groups/DirectoryModule.java
Normal file
|
@ -0,0 +1,62 @@
|
|||
// Copyright 2016 The Domain Registry Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed 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 com.google.domain.registry.groups;
|
||||
|
||||
import static dagger.Provides.Type.SET_VALUES;
|
||||
|
||||
import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
|
||||
import com.google.api.services.admin.directory.Directory;
|
||||
import com.google.api.services.admin.directory.DirectoryScopes;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.domain.registry.config.ConfigModule.Config;
|
||||
import com.google.domain.registry.request.DelegatedOAuthScopes;
|
||||
|
||||
import dagger.Module;
|
||||
import dagger.Provides;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import javax.inject.Named;
|
||||
|
||||
/**
|
||||
* Dagger module for the Google {@link Directory} service.
|
||||
*
|
||||
* @see com.google.domain.registry.config.ConfigModule
|
||||
* @see com.google.domain.registry.request.Modules.UrlFetchTransportModule
|
||||
* @see com.google.domain.registry.request.Modules.Jackson2Module
|
||||
* @see com.google.domain.registry.request.Modules.AppIdentityCredentialModule
|
||||
* @see com.google.domain.registry.request.Modules.UseAppIdentityCredentialForGoogleApisModule
|
||||
*/
|
||||
@Module
|
||||
public final class DirectoryModule {
|
||||
|
||||
/** Provides OAuth2 scopes for the Directory service needed by Domain Registry. */
|
||||
@Provides(type = SET_VALUES)
|
||||
@DelegatedOAuthScopes
|
||||
static Set<String> provideDirectoryOAuthScopes() {
|
||||
return ImmutableSet.of(
|
||||
DirectoryScopes.ADMIN_DIRECTORY_GROUP_MEMBER,
|
||||
DirectoryScopes.ADMIN_DIRECTORY_GROUP);
|
||||
}
|
||||
|
||||
@Provides
|
||||
static Directory provideDirectory(
|
||||
@Named("delegatedAdmin") GoogleCredential credential,
|
||||
@Config("projectId") String projectId) {
|
||||
return new Directory.Builder(credential.getTransport(), credential.getJsonFactory(), credential)
|
||||
.setApplicationName(projectId)
|
||||
.build();
|
||||
}
|
||||
}
|
62
java/google/registry/groups/GroupsConnection.java
Normal file
62
java/google/registry/groups/GroupsConnection.java
Normal file
|
@ -0,0 +1,62 @@
|
|||
// Copyright 2016 The Domain Registry Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed 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 com.google.domain.registry.groups;
|
||||
|
||||
import com.google.api.client.googleapis.json.GoogleJsonResponseException;
|
||||
import com.google.api.services.admin.directory.model.Group;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Interface for common operations on Groups.
|
||||
*/
|
||||
public interface GroupsConnection {
|
||||
|
||||
/** The role of a member in a group. */
|
||||
public enum Role {
|
||||
MEMBER,
|
||||
MANAGER,
|
||||
OWNER
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a member to the specified group with the given role. This function is idempotent; if the
|
||||
* member already exists in the group, then it returns normally. If the group doesn't exist, then
|
||||
* it is created.
|
||||
*/
|
||||
public void addMemberToGroup(String groupKey, String email, Role role) throws IOException;
|
||||
|
||||
/**
|
||||
* Removes a member from the specified group, or throws {@link GoogleJsonResponseException} if the
|
||||
* member doesn't exist.
|
||||
*/
|
||||
public void removeMemberFromGroup(String groupKey, String email) throws IOException;
|
||||
|
||||
/**
|
||||
* Returns all of the members of the specified group. Note that it gets members only; not owners
|
||||
* or managers. Returns an empty set if the group in question does not exist.
|
||||
*/
|
||||
public Set<String> getMembersOfGroup(String groupKey) throws IOException;
|
||||
|
||||
/**
|
||||
* Creates a group with the given email address (groupKey) that is open for external members to
|
||||
* join, and returns it. This function is idempotent; if the given group already exists, then this
|
||||
* function returns as normal without error (and without modifying the existing group in any way,
|
||||
* including permissions on who is able to join). The configured admin owner for the Google App is
|
||||
* automatically added as an owner.
|
||||
*/
|
||||
public Group createGroup(String groupKey) throws IOException;
|
||||
}
|
28
java/google/registry/groups/GroupsModule.java
Normal file
28
java/google/registry/groups/GroupsModule.java
Normal file
|
@ -0,0 +1,28 @@
|
|||
// Copyright 2016 The Domain Registry Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed 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 com.google.domain.registry.groups;
|
||||
|
||||
import dagger.Module;
|
||||
import dagger.Provides;
|
||||
|
||||
/** Dagger module for groups package. */
|
||||
@Module
|
||||
public final class GroupsModule {
|
||||
|
||||
@Provides
|
||||
static GroupsConnection provideGroupsConnection(DirectoryGroupsConnection connection) {
|
||||
return connection;
|
||||
}
|
||||
}
|
61
java/google/registry/groups/GroupssettingsModule.java
Normal file
61
java/google/registry/groups/GroupssettingsModule.java
Normal file
|
@ -0,0 +1,61 @@
|
|||
// Copyright 2016 The Domain Registry Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed 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 com.google.domain.registry.groups;
|
||||
|
||||
import static dagger.Provides.Type.SET_VALUES;
|
||||
|
||||
import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
|
||||
import com.google.api.services.groupssettings.Groupssettings;
|
||||
import com.google.api.services.groupssettings.GroupssettingsScopes;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.domain.registry.config.ConfigModule.Config;
|
||||
import com.google.domain.registry.request.DelegatedOAuthScopes;
|
||||
|
||||
import dagger.Module;
|
||||
import dagger.Provides;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import javax.inject.Named;
|
||||
|
||||
/**
|
||||
* Dagger module for the Google {@link Groupssettings} service.
|
||||
*
|
||||
* @see com.google.domain.registry.config.ConfigModule
|
||||
* @see com.google.domain.registry.request.Modules.UrlFetchTransportModule
|
||||
* @see com.google.domain.registry.request.Modules.Jackson2Module
|
||||
* @see com.google.domain.registry.request.Modules.AppIdentityCredentialModule
|
||||
* @see com.google.domain.registry.request.Modules.UseAppIdentityCredentialForGoogleApisModule
|
||||
*/
|
||||
@Module
|
||||
public final class GroupssettingsModule {
|
||||
|
||||
/** Provides OAuth2 scopes for the Groupssettings service needed by Domain Registry. */
|
||||
@Provides(type = SET_VALUES)
|
||||
@DelegatedOAuthScopes
|
||||
static Set<String> provideGroupssettingsOAuthScopes() {
|
||||
return ImmutableSet.of(GroupssettingsScopes.APPS_GROUPS_SETTINGS);
|
||||
}
|
||||
|
||||
@Provides
|
||||
static Groupssettings provideGroupssettings(
|
||||
@Named("delegatedAdmin") GoogleCredential credential,
|
||||
@Config("projectId") String projectId) {
|
||||
return new Groupssettings
|
||||
.Builder(credential.getTransport(), credential.getJsonFactory(), credential)
|
||||
.setApplicationName(projectId)
|
||||
.build();
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue