Skip to content

Commit

Permalink
Update Network Secret Key (#19)
Browse files Browse the repository at this point in the history
* Update Network Secret Key

* modify test units
  • Loading branch information
gatsby068 authored Oct 30, 2023
1 parent 69d99ee commit 128c289
Show file tree
Hide file tree
Showing 7 changed files with 115 additions and 14 deletions.
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1.7.0
2.0.0
Original file line number Diff line number Diff line change
Expand Up @@ -17,19 +17,61 @@
package xyz.eulix.platform.services.basic;

import io.quarkus.runtime.Startup;
import org.apache.commons.codec.digest.DigestUtils;
import org.jboss.logging.Logger;
import xyz.eulix.platform.common.support.CommonUtils;
import xyz.eulix.platform.services.registry.entity.RegistryBoxEntity;
import xyz.eulix.platform.services.registry.repository.RegistryBoxEntityRepository;

import javax.annotation.PostConstruct;
import javax.enterprise.context.ApplicationScoped;
import javax.inject.Inject;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;

@Startup
@ApplicationScoped
public class AppConfiguration {
private static final Logger LOG = Logger.getLogger("app.log");

@Inject
RegistryBoxEntityRepository registryBoxEntityRepository;

@PostConstruct
void init() {
LOG.infov("Application init begin...");

/*
* 更新 network secret 为 hash结果
* 适用版本:2.0.0
*/
LOG.infov("Update Network Secret Key begin...");
// 查询全部已注册盒子
AtomicInteger successBoxCount = new AtomicInteger(0);
AtomicInteger failureBoxCount = new AtomicInteger(0);
List<RegistryBoxEntity> registryBoxEntityList = registryBoxEntityRepository.listAll();
registryBoxEntityList.stream()
.filter(registryBoxEntity -> CommonUtils.isNullOrEmpty(registryBoxEntity.getNetworkSecretSalt()))
.forEach(registryBoxEntity -> {
// 为已注册盒子生成盐值,并重新计算secret key
try {
// 随机字符串做盐
String salt = CommonUtils.getUUID();
String secretKey = registryBoxEntity.getNetworkSecretKey();
// 盐和密码结合取hash值
String hashSecretKey = DigestUtils.md5Hex(salt + secretKey);
registryBoxEntityRepository.updateSecretKeyAndSaltByBoxUUID(hashSecretKey, salt, registryBoxEntity.getBoxUUID());
LOG.infov("Update Network Secret Key success, boxuuid:{0}, from:{1} ,to:{2}", registryBoxEntity.getBoxUUID(),
secretKey, hashSecretKey);
successBoxCount.incrementAndGet();
} catch (Exception e) {
LOG.errorv(e, "Update Network Secret Key failed, boxuuid:{0}", registryBoxEntity.getBoxUUID());
failureBoxCount.incrementAndGet();
}
});

LOG.infov("Update Network Secret Key success! Total:{0}, success:{1}, failure:{2}", registryBoxEntityList.size(),
successBoxCount.get(), failureBoxCount.get());
LOG.infov("Application init succeed!");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -44,4 +44,7 @@ public class RegistryBoxEntity extends BaseEntity {

@Column(name = "network_secret_key")
private String networkSecretKey;

@Column(name = "network_secret_salt")
private String networkSecretSalt;
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import xyz.eulix.platform.services.registry.entity.RegistryBoxEntity;

import javax.enterprise.context.ApplicationScoped;
import javax.transaction.Transactional;
import java.util.List;
import java.util.Optional;

Expand All @@ -41,6 +42,9 @@ public class RegistryBoxEntityRepository implements PanacheRepository<RegistryBo
// 根据box_uuids查询资源
private static final String FIND_BY_BOXUUIDS = "box_uuid in (?1)";

// 根据network_client_id查询资源
private static final String FIND_BY_CLIENTID = "network_client_id=?1";

public Optional<RegistryBoxEntity> findByBoxUUID(String boxUUID) {
return this.find(FIND_BY_BOXUUID, boxUUID).firstResultOptional();
}
Expand All @@ -56,4 +60,13 @@ public Optional<RegistryBoxEntity> findByClientIdAndSecretKey(String clientId, S
public List<RegistryBoxEntity> findByBoxUUIDs(List<String> boxUUIDs) {
return this.find(FIND_BY_BOXUUIDS, boxUUIDs).list();
}

public Optional<RegistryBoxEntity> findByClientId(String networkClientId) {
return this.find(FIND_BY_CLIENTID, networkClientId).firstResultOptional();
}

@Transactional
public void updateSecretKeyAndSaltByBoxUUID(String hashSecretKey, String salt, String boxUUID) {
update("set network_secret_key=?1, network_secret_salt=?2, updated_at=now() where box_uuid=?3 ", hashSecretKey, salt, boxUUID);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
package xyz.eulix.platform.services.registry.service;

import io.quarkus.hibernate.orm.panache.PanacheQuery;
import org.apache.commons.codec.digest.DigestUtils;
import org.jboss.logging.Logger;
import xyz.eulix.platform.services.config.ApplicationProperties;
import xyz.eulix.platform.services.network.service.NetworkService;
Expand Down Expand Up @@ -130,15 +131,15 @@ public void deleteClientByClientUUID(String boxUUID, String userId, String clien
public BoxRegistryResult registryBox (BoxTokenEntity boxToken, String networkClientId) {
var registryBoxEntity = boxEntityRepository.findByBoxUUID(boxToken.getBoxUUID());
if (registryBoxEntity.isPresent()) {
return BoxRegistryResult.of(
registryBoxEntity.get().getBoxUUID(),
NetworkClient.of(registryBoxEntity.get().getNetworkClientId(), registryBoxEntity.get().getNetworkSecretKey()));
LOG.warnv("box uuid had already registered, boxuuid:{0}", boxToken.getBoxUUID());
throw new WebApplicationException("box uuid had already registered. Pls reset and try again.", Response.Status.NOT_ACCEPTABLE);
}
// 注册box
RegistryBoxEntity boxEntity = registryBox(boxToken.getBoxUUID(), boxToken.getBoxRegKey(), networkClientId);
String networkClientSecret = "nrk_" + CommonUtils.createUnifiedRandomCharacters(10);
RegistryBoxEntity boxEntity = registryBox(boxToken.getBoxUUID(), boxToken.getBoxRegKey(), networkClientId, networkClientSecret);
// 计算路由
networkService.calculateNetworkRoute(boxEntity.getNetworkClientId());
return BoxRegistryResult.of(boxEntity.getBoxUUID(), NetworkClient.of(boxEntity.getNetworkClientId(), boxEntity.getNetworkSecretKey()));
return BoxRegistryResult.of(boxEntity.getBoxUUID(), NetworkClient.of(boxEntity.getNetworkClientId(), networkClientSecret));
}

@Transactional
Expand Down Expand Up @@ -179,15 +180,19 @@ public UserRegistryResult registryUser (UserRegistryInfo userRegistryInfo, Strin
}

@Transactional
public RegistryBoxEntity registryBox(String boxUUID, String boxRegKey, String networkClientId) {
public RegistryBoxEntity registryBox(String boxUUID, String boxRegKey, String networkClientId, String networkSecretKey) {
// 注册box
RegistryBoxEntity boxEntity = new RegistryBoxEntity();
{
boxEntity.setBoxUUID(boxUUID);
boxEntity.setBoxRegKey(boxRegKey);
// network client
boxEntity.setNetworkClientId(CommonUtils.isNullOrBlank(networkClientId) ? CommonUtils.getUUID() : networkClientId);
boxEntity.setNetworkSecretKey("nrk_" + CommonUtils.createUnifiedRandomCharacters(10));
// 随机字符串做盐
String salt = CommonUtils.getUUID();
// 盐和密码结合取hash值
boxEntity.setNetworkSecretSalt(salt);
boxEntity.setNetworkSecretKey(DigestUtils.md5Hex(salt + networkSecretKey));
}
boxEntityRepository.persist(boxEntity);
return boxEntity;
Expand Down Expand Up @@ -544,11 +549,17 @@ public void reachUpperLimit(String boxUUID) {
}

public Boolean networkClientAuth(String clientId, String secretKey) {
Optional<RegistryBoxEntity> registryBoxEntityOp = boxEntityRepository.findByClientIdAndSecretKey(clientId, secretKey);
Optional<RegistryBoxEntity> registryBoxEntityOp = boxEntityRepository.findByClientId(clientId);
if (registryBoxEntityOp.isEmpty()) {
LOG.infov("network client is empty, client id:{0}, secret key:{1}", clientId, secretKey);
return false;
}
String salt = registryBoxEntityOp.get().getNetworkSecretSalt();
if (!registryBoxEntityOp.get().getNetworkSecretKey().equals(DigestUtils.md5Hex(salt + secretKey))) {
LOG.infov("network client auth failed, client id:{0}, secret key:{1}", clientId, secretKey);
return false;
}
return registryBoxEntityOp.isPresent();
return true;
}

public BoxRegistryDetailInfo boxRegistryBindUserAndClientInfo(String uuid) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
-- Copyright (c) 2022 Institute of Software Chinese Academy of Sciences (ISCAS)
--
-- 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.

ALTER TABLE box_registries ADD network_secret_salt VARCHAR(128) DEFAULT NULL COMMENT 'network client访问密钥盐值';
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,15 @@ void registryBox() {
.body()
.as(BoxRegistryResult.class);
Assertions.assertNotNull(result);

given()
.header("Request-Id", "uuid")
.header("Box-Reg-Key", "box_reg_key")
.pathParam( "box_uuid","box_uuid")
.contentType(ContentType.JSON)
.when().delete("/v2/platform/boxes/{box_uuid}")
.then()
.statusCode(204);
}

@Test
Expand All @@ -90,16 +99,24 @@ void registryDuplicated() {
.body()
.as(BoxRegistryResult.class);

final BoxRegistryResult result1 = given()
final int statusCode = given()
.header("Request-Id", bid + "-1")
.header("Box-Reg-Key", "box_reg_key")
.body(info)
.contentType(ContentType.JSON)
.when().post("/v2/platform/boxes")
.body()
.as(BoxRegistryResult.class);
.getStatusCode();
Assertions.assertNotNull(result);
Assertions.assertNotNull(result1);
Assertions.assertEquals(406, statusCode);

given()
.header("Request-Id", "uuid")
.header("Box-Reg-Key", "box_reg_key")
.pathParam( "box_uuid","box_uuid")
.contentType(ContentType.JSON)
.when().delete("/v2/platform/boxes/{box_uuid}")
.then()
.statusCode(204);
}

@Test
Expand Down

0 comments on commit 128c289

Please sign in to comment.