Line data Source code
1 : // Copyright (C) 2019 The Android Open Source Project
2 : //
3 : // Licensed under the Apache License, Version 2.0 (the "License");
4 : // you may not use this file except in compliance with the License.
5 : // You may obtain a copy of the License at
6 : //
7 : // http://www.apache.org/licenses/LICENSE-2.0
8 : //
9 : // Unless required by applicable law or agreed to in writing, software
10 : // distributed under the License is distributed on an "AS IS" BASIS,
11 : // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 : // See the License for the specific language governing permissions and
13 : // limitations under the License.
14 :
15 : package com.google.gerrit.server.account.externalids.testing;
16 :
17 : import static java.nio.charset.StandardCharsets.UTF_8;
18 : import static org.eclipse.jgit.lib.Constants.OBJ_BLOB;
19 : import static org.eclipse.jgit.lib.Constants.OBJ_TREE;
20 :
21 : import com.google.gerrit.entities.Account;
22 : import com.google.gerrit.entities.RefNames;
23 : import com.google.gerrit.server.account.externalids.ExternalId;
24 : import com.google.gerrit.server.account.externalids.ExternalIdReader;
25 : import java.io.IOException;
26 : import org.eclipse.jgit.lib.CommitBuilder;
27 : import org.eclipse.jgit.lib.Config;
28 : import org.eclipse.jgit.lib.ObjectId;
29 : import org.eclipse.jgit.lib.ObjectInserter;
30 : import org.eclipse.jgit.lib.PersonIdent;
31 : import org.eclipse.jgit.lib.RefUpdate;
32 : import org.eclipse.jgit.lib.Repository;
33 : import org.eclipse.jgit.notes.NoteMap;
34 : import org.eclipse.jgit.revwalk.RevCommit;
35 : import org.eclipse.jgit.revwalk.RevWalk;
36 :
37 : /** Common methods for dealing with external IDs in tests. */
38 0 : public class ExternalIdTestUtil {
39 :
40 : public static String insertExternalIdWithoutAccountId(
41 : Repository repo, RevWalk rw, PersonIdent ident, Account.Id accountId, String externalId)
42 : throws IOException {
43 1 : return insertExternalId(
44 : repo,
45 : rw,
46 : ident,
47 : (ins, noteMap) -> {
48 1 : ExternalId extId =
49 1 : ExternalId.create(
50 1 : ExternalId.Key.parse(externalId, false), accountId, null, null, null);
51 1 : ObjectId noteId = extId.key().sha1();
52 1 : Config c = new Config();
53 1 : extId.writeToConfig(c);
54 1 : c.unset("externalId", extId.key().get(), "accountId");
55 1 : byte[] raw = c.toText().getBytes(UTF_8);
56 1 : ObjectId dataBlob = ins.insert(OBJ_BLOB, raw);
57 1 : noteMap.set(noteId, dataBlob);
58 1 : return noteId;
59 : });
60 : }
61 :
62 : public static String insertExternalIdWithKeyThatDoesntMatchNoteId(
63 : Repository repo, RevWalk rw, PersonIdent ident, Account.Id accountId, String externalId)
64 : throws IOException {
65 2 : return insertExternalId(
66 : repo,
67 : rw,
68 : ident,
69 : (ins, noteMap) -> {
70 2 : ExternalId extId =
71 2 : ExternalId.create(
72 2 : ExternalId.Key.parse(externalId, false), accountId, null, null, null);
73 2 : ObjectId noteId = ExternalId.Key.parse(externalId + "x", false).sha1();
74 2 : Config c = new Config();
75 2 : extId.writeToConfig(c);
76 2 : byte[] raw = c.toText().getBytes(UTF_8);
77 2 : ObjectId dataBlob = ins.insert(OBJ_BLOB, raw);
78 2 : noteMap.set(noteId, dataBlob);
79 2 : return noteId;
80 : });
81 : }
82 :
83 : public static String insertExternalIdWithInvalidConfig(
84 : Repository repo, RevWalk rw, PersonIdent ident, String externalId) throws IOException {
85 1 : return insertExternalId(
86 : repo,
87 : rw,
88 : ident,
89 : (ins, noteMap) -> {
90 1 : ObjectId noteId = ExternalId.Key.parse(externalId, false).sha1();
91 1 : byte[] raw = "bad-config".getBytes(UTF_8);
92 1 : ObjectId dataBlob = ins.insert(OBJ_BLOB, raw);
93 1 : noteMap.set(noteId, dataBlob);
94 1 : return noteId;
95 : });
96 : }
97 :
98 : public static String insertExternalIdWithEmptyNote(
99 : Repository repo, RevWalk rw, PersonIdent ident, String externalId) throws IOException {
100 1 : return insertExternalId(
101 : repo,
102 : rw,
103 : ident,
104 : (ins, noteMap) -> {
105 1 : ObjectId noteId = ExternalId.Key.parse(externalId, false).sha1();
106 1 : byte[] raw = "".getBytes(UTF_8);
107 1 : ObjectId dataBlob = ins.insert(OBJ_BLOB, raw);
108 1 : noteMap.set(noteId, dataBlob);
109 1 : return noteId;
110 : });
111 : }
112 :
113 : private static String insertExternalId(
114 : Repository repo, RevWalk rw, PersonIdent ident, ExternalIdInserter extIdInserter)
115 : throws IOException {
116 2 : ObjectId rev = ExternalIdReader.readRevision(repo);
117 2 : NoteMap noteMap = ExternalIdReader.readNoteMap(rw, rev);
118 :
119 2 : try (ObjectInserter ins = repo.newObjectInserter()) {
120 2 : ObjectId noteId = extIdInserter.addNote(ins, noteMap);
121 :
122 2 : CommitBuilder cb = new CommitBuilder();
123 2 : cb.setMessage("Update external IDs");
124 2 : cb.setTreeId(noteMap.writeTree(ins));
125 2 : cb.setAuthor(ident);
126 2 : cb.setCommitter(ident);
127 2 : if (!rev.equals(ObjectId.zeroId())) {
128 2 : cb.setParentId(rev);
129 : } else {
130 0 : cb.setParentIds(); // Ref is currently nonexistent, commit has no parents.
131 : }
132 2 : if (cb.getTreeId() == null) {
133 0 : if (rev.equals(ObjectId.zeroId())) {
134 0 : cb.setTreeId(ins.insert(OBJ_TREE, new byte[] {})); // No parent, assume empty tree.
135 : } else {
136 0 : RevCommit p = rw.parseCommit(rev);
137 0 : cb.setTreeId(p.getTree()); // Copy tree from parent.
138 : }
139 : }
140 2 : ObjectId commitId = ins.insert(cb);
141 2 : ins.flush();
142 :
143 2 : RefUpdate u = repo.updateRef(RefNames.REFS_EXTERNAL_IDS);
144 2 : u.setExpectedOldObjectId(rev);
145 2 : u.setNewObjectId(commitId);
146 2 : RefUpdate.Result res = u.update();
147 2 : switch (res) {
148 : case NEW:
149 : case FAST_FORWARD:
150 : case NO_CHANGE:
151 : case RENAMED:
152 : case FORCED:
153 2 : break;
154 : case LOCK_FAILURE:
155 : case IO_FAILURE:
156 : case NOT_ATTEMPTED:
157 : case REJECTED:
158 : case REJECTED_CURRENT_BRANCH:
159 : case REJECTED_MISSING_OBJECT:
160 : case REJECTED_OTHER_REASON:
161 : default:
162 0 : throw new IOException("Updating external IDs failed with " + res);
163 : }
164 2 : return noteId.getName();
165 : }
166 : }
167 : }
|