Hotfix SPCVE-0001

pull/80/head
Inex Code 2021-11-18 19:10:40 +00:00
parent 08ff445935
commit 6011d6fdce
7 changed files with 44 additions and 14 deletions

View File

@ -4,6 +4,7 @@ import 'dart:io';
import 'package:dio/dio.dart'; import 'package:dio/dio.dart';
import 'package:selfprivacy/config/get_it_config.dart'; import 'package:selfprivacy/config/get_it_config.dart';
import 'package:selfprivacy/logic/api_maps/api_map.dart'; import 'package:selfprivacy/logic/api_maps/api_map.dart';
import 'package:selfprivacy/logic/models/backblaze_credential.dart';
import 'package:selfprivacy/logic/models/hetzner_server_info.dart'; import 'package:selfprivacy/logic/models/hetzner_server_info.dart';
import 'package:selfprivacy/logic/models/server_details.dart'; import 'package:selfprivacy/logic/models/server_details.dart';
import 'package:selfprivacy/logic/models/user.dart'; import 'package:selfprivacy/logic/models/user.dart';
@ -93,6 +94,7 @@ class HetznerApi extends ApiMap {
required User rootUser, required User rootUser,
required String domainName, required String domainName,
required HetznerDataBase dataBase, required HetznerDataBase dataBase,
required BackblazeCredential backblazeCredential,
}) async { }) async {
var client = await getClient(); var client = await getClient();
@ -112,11 +114,15 @@ class HetznerApi extends ApiMap {
// var dbId = dbCreateResponse.data['volume']['id']; // var dbId = dbCreateResponse.data['volume']['id'];
var dbId = dataBase.id; var dbId = dataBase.id;
final apiToken = StringGenerators.apiToken();
final hostname = domainName.split('.')[0];
/// add ssh key when you need it: e.g. "ssh_keys":["kherel"] /// add ssh key when you need it: e.g. "ssh_keys":["kherel"]
/// check the branch name, it could be "development" or "master". /// check the branch name, it could be "development" or "master".
var data = jsonDecode( var data = jsonDecode(
'''{"name":"$domainName","server_type":"cx11","start_after_create":false,"image":"ubuntu-20.04", "volumes":[$dbId], "networks":[], "user_data":"#cloud-config\\nruncmd:\\n- curl https://git.selfprivacy.org/ilchub/selfprivacy-nixos-infect/raw/branch/development/nixos-infect | PROVIDER=hetzner NIX_CHANNEL=nixos-21.05 DOMAIN=$domainName LUSER=${rootUser.login} PASSWORD=${rootUser.password} CF_TOKEN=$cloudFlareKey DB_PASSWORD=$dbPassword bash 2>&1 | tee /tmp/infect.log","labels":{},"automount":true, "location": "fsn1"}'''); '''{"name":"$domainName","server_type":"cx11","start_after_create":false,"image":"ubuntu-20.04", "volumes":[$dbId], "networks":[], "user_data":"#cloud-config\\nruncmd:\\n- curl https://git.selfprivacy.org/SelfPrivacy/selfprivacy-nixos-infect/raw/branch/master/nixos-infect | PROVIDER=hetzner NIX_CHANNEL=nixos-21.05 DOMAIN=$domainName LUSER=${rootUser.login} PASSWORD=${rootUser.password} CF_TOKEN=$cloudFlareKey DB_PASSWORD=$dbPassword BACKBLAZE_KEY_ID=${backblazeCredential.keyId} BACKBLAZE_ACCOUNT_KEY=${backblazeCredential.applicationKey} API_TOKEN=$apiToken HOSTNAME=$hostname bash 2>&1 | tee /tmp/infect.log","labels":{},"automount":true, "location": "fsn1"}''');
Response serverCreateResponse = await client.post( Response serverCreateResponse = await client.post(
'/servers', '/servers',
@ -129,6 +135,7 @@ class HetznerApi extends ApiMap {
ip4: serverCreateResponse.data['server']['public_net']['ipv4']['ip'], ip4: serverCreateResponse.data['server']['public_net']['ipv4']['ip'],
createTime: DateTime.now(), createTime: DateTime.now(),
dataBase: dataBase, dataBase: dataBase,
apiToken: apiToken,
); );
} }

View File

@ -20,8 +20,11 @@ class ServerApi extends ApiMap {
if (isWithToken) { if (isWithToken) {
var cloudFlareDomain = getIt<ApiConfigModel>().cloudFlareDomain; var cloudFlareDomain = getIt<ApiConfigModel>().cloudFlareDomain;
var domainName = cloudFlareDomain!.domainName; var domainName = cloudFlareDomain!.domainName;
var apiToken = getIt<ApiConfigModel>().hetznerServer?.apiToken;
options = BaseOptions(baseUrl: 'https://api.$domainName'); options = BaseOptions(baseUrl: 'https://api.$domainName', headers: {
'Authorization': 'Bearer ${apiToken}',
});
} }
return options; return options;
@ -47,18 +50,19 @@ class ServerApi extends ApiMap {
Response response; Response response;
var client = await getClient(); var client = await getClient();
// POST request with JSON body containing username and password
try { try {
response = await client.post( response = await client.post(
'/users/create', '/users',
data: {
'username': user.login,
'password': user.password,
},
options: Options( options: Options(
headers: { contentType: 'application/json',
"X-User": user.login,
"X-Password": user.password,
"X-Domain": getIt<ApiConfigModel>().cloudFlareDomain!.domainName
},
), ),
); );
res = response.statusCode == HttpStatus.ok; res = response.statusCode == HttpStatus.created;
} catch (e) { } catch (e) {
print(e); print(e);
res = false; res = false;
@ -99,8 +103,8 @@ class ServerApi extends ApiMap {
Future<void> sendSsh(String ssh) async { Future<void> sendSsh(String ssh) async {
var client = await getClient(); var client = await getClient();
client.post( client.put(
'/services/ssh/enable', '/services/ssh/key/send',
data: {"public_key": ssh}, data: {"public_key": ssh},
); );
client.close(); client.close();

View File

@ -347,6 +347,7 @@ class AppConfigCubit extends Cubit<AppConfigState> {
state.rootUser!, state.rootUser!,
state.cloudFlareDomain!.domainName, state.cloudFlareDomain!.domainName,
state.cloudFlareKey!, state.cloudFlareKey!,
state.backblazeCredential!,
onCancel: onCancel, onCancel: onCancel,
onSuccess: onSuccess, onSuccess: onSuccess,
); );

View File

@ -110,7 +110,8 @@ class AppConfigRepository {
Future<void> createServer( Future<void> createServer(
User rootUser, User rootUser,
String domainName, String domainName,
String cloudFlareKey, { String cloudFlareKey,
BackblazeCredential backblazeCredential, {
required void Function() onCancel, required void Function() onCancel,
required Future<void> Function(HetznerServerDetails serverDetails) required Future<void> Function(HetznerServerDetails serverDetails)
onSuccess, onSuccess,
@ -126,6 +127,7 @@ class AppConfigRepository {
rootUser: rootUser, rootUser: rootUser,
domainName: domainName, domainName: domainName,
dataBase: dataBase, dataBase: dataBase,
backblazeCredential: backblazeCredential,
); );
saveServerDetails(serverDetails); saveServerDetails(serverDetails);
onSuccess(serverDetails); onSuccess(serverDetails);
@ -149,6 +151,7 @@ class AppConfigRepository {
rootUser: rootUser, rootUser: rootUser,
domainName: domainName, domainName: domainName,
dataBase: dataBase, dataBase: dataBase,
backblazeCredential: backblazeCredential,
); );
await saveServerDetails(serverDetails); await saveServerDetails(serverDetails);

View File

@ -9,6 +9,7 @@ class HetznerServerDetails {
required this.id, required this.id,
required this.createTime, required this.createTime,
required this.dataBase, required this.dataBase,
required this.apiToken,
this.startTime, this.startTime,
}); });
@ -27,6 +28,9 @@ class HetznerServerDetails {
@HiveField(4) @HiveField(4)
final HetznerDataBase dataBase; final HetznerDataBase dataBase;
@HiveField(5)
final String apiToken;
HetznerServerDetails copyWith({DateTime? startTime}) { HetznerServerDetails copyWith({DateTime? startTime}) {
return HetznerServerDetails( return HetznerServerDetails(
startTime: startTime ?? this.startTime, startTime: startTime ?? this.startTime,
@ -34,6 +38,7 @@ class HetznerServerDetails {
id: id, id: id,
ip4: ip4, ip4: ip4,
dataBase: dataBase, dataBase: dataBase,
apiToken: apiToken,
); );
} }

View File

@ -21,6 +21,7 @@ class HetznerServerDetailsAdapter extends TypeAdapter<HetznerServerDetails> {
id: fields[1] as int, id: fields[1] as int,
createTime: fields[3] as DateTime?, createTime: fields[3] as DateTime?,
dataBase: fields[4] as HetznerDataBase, dataBase: fields[4] as HetznerDataBase,
apiToken: fields[5] as String,
startTime: fields[2] as DateTime?, startTime: fields[2] as DateTime?,
); );
} }
@ -28,7 +29,7 @@ class HetznerServerDetailsAdapter extends TypeAdapter<HetznerServerDetails> {
@override @override
void write(BinaryWriter writer, HetznerServerDetails obj) { void write(BinaryWriter writer, HetznerServerDetails obj) {
writer writer
..writeByte(5) ..writeByte(6)
..writeByte(0) ..writeByte(0)
..write(obj.ip4) ..write(obj.ip4)
..writeByte(1) ..writeByte(1)
@ -38,7 +39,9 @@ class HetznerServerDetailsAdapter extends TypeAdapter<HetznerServerDetails> {
..writeByte(2) ..writeByte(2)
..write(obj.startTime) ..write(obj.startTime)
..writeByte(4) ..writeByte(4)
..write(obj.dataBase); ..write(obj.dataBase)
..writeByte(5)
..write(obj.apiToken);
} }
@override @override

View File

@ -96,4 +96,11 @@ class StringGenerators {
hasUppercaseLetters: true, hasUppercaseLetters: true,
hasNumbers: true, hasNumbers: true,
); );
static StringGeneratorFunction apiToken = () => getRandomString(
64,
hasLowercaseLetters: true,
hasUppercaseLetters: true,
hasNumbers: true,
);
} }