clapp-pm 1.0.18__py3-none-any.whl → 1.0.19__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {clapp_pm-1.0.18.data → clapp_pm-1.0.19.data}/data/version.json +1 -1
- {clapp_pm-1.0.18.dist-info → clapp_pm-1.0.19.dist-info}/METADATA +1 -1
- {clapp_pm-1.0.18.dist-info → clapp_pm-1.0.19.dist-info}/RECORD +23 -14
- {clapp_pm-1.0.18.dist-info → clapp_pm-1.0.19.dist-info}/top_level.txt +3 -0
- cli_commands.py +5 -1
- docs/developer_guide.md +361 -0
- main.py +25 -16
- manifest_schema.py +20 -5
- manifest_validator.py +3 -3
- package_runner.py +134 -34
- package_signing.py +47 -269
- templates/dart/manifest.json +11 -0
- templates/lua/manifest.json +11 -0
- templates/python/README.md +51 -0
- templates/python/main.py +55 -0
- templates/python/manifest.json +11 -0
- test-app/README.md +51 -0
- test-app/main.py +55 -0
- test-app/manifest.json +15 -0
- version.py +1 -1
- {clapp_pm-1.0.18.dist-info → clapp_pm-1.0.19.dist-info}/WHEEL +0 -0
- {clapp_pm-1.0.18.dist-info → clapp_pm-1.0.19.dist-info}/entry_points.txt +0 -0
- {clapp_pm-1.0.18.dist-info → clapp_pm-1.0.19.dist-info}/licenses/LICENSE +0 -0
package_runner.py
CHANGED
@@ -1,9 +1,93 @@
|
|
1
1
|
import os
|
2
2
|
import json
|
3
3
|
import subprocess
|
4
|
+
from typing import Dict, Callable, Optional, Tuple
|
4
5
|
from package_registry import get_manifest
|
5
6
|
|
6
|
-
|
7
|
+
class LanguageRunner:
|
8
|
+
"""Dil çalıştırıcıları için temel sınıf"""
|
9
|
+
|
10
|
+
def __init__(self, name: str, command: str, file_extension: str = ""):
|
11
|
+
self.name = name
|
12
|
+
self.command = command
|
13
|
+
self.file_extension = file_extension
|
14
|
+
|
15
|
+
def run(self, entry_file: str, app_path: str) -> Tuple[bool, str]:
|
16
|
+
"""
|
17
|
+
Uygulamayı çalıştırır
|
18
|
+
|
19
|
+
Args:
|
20
|
+
entry_file: Giriş dosyası
|
21
|
+
app_path: Uygulama dizini
|
22
|
+
|
23
|
+
Returns:
|
24
|
+
(success, error_message)
|
25
|
+
"""
|
26
|
+
try:
|
27
|
+
result = subprocess.run([self.command, entry_file],
|
28
|
+
cwd=app_path,
|
29
|
+
capture_output=False)
|
30
|
+
return result.returncode == 0, ""
|
31
|
+
except FileNotFoundError:
|
32
|
+
return False, f"{self.name} yüklü değil veya PATH'te bulunamadı."
|
33
|
+
except Exception as e:
|
34
|
+
return False, f"Çalıştırma hatası: {str(e)}"
|
35
|
+
|
36
|
+
def check_availability(self) -> bool:
|
37
|
+
"""Dil çalıştırıcısının sistemde mevcut olup olmadığını kontrol eder"""
|
38
|
+
try:
|
39
|
+
result = subprocess.run([self.command, "--version"],
|
40
|
+
capture_output=True,
|
41
|
+
text=True)
|
42
|
+
return result.returncode == 0
|
43
|
+
except FileNotFoundError:
|
44
|
+
return False
|
45
|
+
|
46
|
+
# Desteklenen diller için runner'lar
|
47
|
+
LANGUAGE_RUNNERS: Dict[str, LanguageRunner] = {
|
48
|
+
'python': LanguageRunner('Python', 'python', '.py'),
|
49
|
+
'lua': LanguageRunner('Lua', 'lua', '.lua'),
|
50
|
+
'dart': LanguageRunner('Dart', 'dart', '.dart'),
|
51
|
+
'go': LanguageRunner('Go', 'go', '.go'),
|
52
|
+
'rust': LanguageRunner('Rust', 'cargo', '.rs'),
|
53
|
+
'node': LanguageRunner('Node.js', 'node', '.js'),
|
54
|
+
'bash': LanguageRunner('Bash', 'bash', '.sh'),
|
55
|
+
'perl': LanguageRunner('Perl', 'perl', '.pl'),
|
56
|
+
'ruby': LanguageRunner('Ruby', 'ruby', '.rb'),
|
57
|
+
'php': LanguageRunner('PHP', 'php', '.php')
|
58
|
+
}
|
59
|
+
|
60
|
+
def get_runner_for_language(language: str) -> Optional[LanguageRunner]:
|
61
|
+
"""
|
62
|
+
Dile göre runner döndürür
|
63
|
+
|
64
|
+
Args:
|
65
|
+
language: Programlama dili
|
66
|
+
|
67
|
+
Returns:
|
68
|
+
LanguageRunner veya None
|
69
|
+
"""
|
70
|
+
return LANGUAGE_RUNNERS.get(language.lower())
|
71
|
+
|
72
|
+
def add_language_support(name: str, command: str, file_extension: str = "") -> bool:
|
73
|
+
"""
|
74
|
+
Yeni dil desteği ekler
|
75
|
+
|
76
|
+
Args:
|
77
|
+
name: Dil adı
|
78
|
+
command: Çalıştırma komutu
|
79
|
+
file_extension: Dosya uzantısı
|
80
|
+
|
81
|
+
Returns:
|
82
|
+
Başarılı ise True
|
83
|
+
"""
|
84
|
+
try:
|
85
|
+
LANGUAGE_RUNNERS[name.lower()] = LanguageRunner(name, command, file_extension)
|
86
|
+
return True
|
87
|
+
except Exception:
|
88
|
+
return False
|
89
|
+
|
90
|
+
def run_app(app_name: str) -> bool:
|
7
91
|
"""
|
8
92
|
Belirtilen uygulamayı çalıştırır.
|
9
93
|
|
@@ -32,49 +116,33 @@ def run_app(app_name):
|
|
32
116
|
print(f"Hata: Giriş dosyası '{entry_file}' bulunamadı.")
|
33
117
|
return False
|
34
118
|
|
35
|
-
# Dile göre
|
119
|
+
# Dile göre runner al
|
36
120
|
language = manifest['language'].lower()
|
121
|
+
runner = get_runner_for_language(language)
|
37
122
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
result = subprocess.run(['python', entry_file],
|
42
|
-
cwd=app_path,
|
43
|
-
capture_output=False)
|
44
|
-
return result.returncode == 0
|
45
|
-
|
46
|
-
elif language == 'lua':
|
47
|
-
# Lua uygulamasını çalıştır
|
48
|
-
result = subprocess.run(['lua', entry_file],
|
49
|
-
cwd=app_path,
|
50
|
-
capture_output=False)
|
51
|
-
return result.returncode == 0
|
52
|
-
|
53
|
-
else:
|
54
|
-
print(f"Hata: Desteklenmeyen dil '{language}'. Desteklenen diller: python, lua")
|
55
|
-
return False
|
56
|
-
|
57
|
-
except FileNotFoundError as e:
|
58
|
-
if language == 'python':
|
59
|
-
print("Hata: Python yüklü değil veya PATH'te bulunamadı.")
|
60
|
-
elif language == 'lua':
|
61
|
-
print("Hata: Lua yüklü değil veya PATH'te bulunamadı.")
|
62
|
-
return False
|
63
|
-
|
64
|
-
except Exception as e:
|
65
|
-
print(f"Hata: Uygulama çalıştırılırken bir hata oluştu: {e}")
|
123
|
+
if not runner:
|
124
|
+
supported = ', '.join(LANGUAGE_RUNNERS.keys())
|
125
|
+
print(f"Hata: Desteklenmeyen dil '{language}'. Desteklenen diller: {supported}")
|
66
126
|
return False
|
127
|
+
|
128
|
+
# Uygulamayı çalıştır
|
129
|
+
success, error_msg = runner.run(entry_file, app_path)
|
130
|
+
|
131
|
+
if not success and error_msg:
|
132
|
+
print(f"Hata: {error_msg}")
|
133
|
+
|
134
|
+
return success
|
67
135
|
|
68
|
-
def get_supported_languages():
|
136
|
+
def get_supported_languages() -> list:
|
69
137
|
"""
|
70
138
|
Desteklenen programlama dillerinin listesini döndürür.
|
71
139
|
|
72
140
|
Returns:
|
73
141
|
list: Desteklenen diller listesi
|
74
142
|
"""
|
75
|
-
return
|
143
|
+
return list(LANGUAGE_RUNNERS.keys())
|
76
144
|
|
77
|
-
def check_language_support(language):
|
145
|
+
def check_language_support(language: str) -> bool:
|
78
146
|
"""
|
79
147
|
Belirtilen dilin desteklenip desteklenmediğini kontrol eder.
|
80
148
|
|
@@ -84,4 +152,36 @@ def check_language_support(language):
|
|
84
152
|
Returns:
|
85
153
|
bool: Dil destekleniyorsa True, değilse False
|
86
154
|
"""
|
87
|
-
return language.lower() in
|
155
|
+
return language.lower() in LANGUAGE_RUNNERS
|
156
|
+
|
157
|
+
def check_language_availability(language: str) -> bool:
|
158
|
+
"""
|
159
|
+
Belirtilen dilin sistemde mevcut olup olmadığını kontrol eder.
|
160
|
+
|
161
|
+
Args:
|
162
|
+
language (str): Kontrol edilecek dil
|
163
|
+
|
164
|
+
Returns:
|
165
|
+
bool: Dil mevcutsa True, değilse False
|
166
|
+
"""
|
167
|
+
runner = get_runner_for_language(language)
|
168
|
+
if not runner:
|
169
|
+
return False
|
170
|
+
return runner.check_availability()
|
171
|
+
|
172
|
+
def get_language_status_report() -> str:
|
173
|
+
"""
|
174
|
+
Tüm desteklenen dillerin durum raporunu döndürür.
|
175
|
+
|
176
|
+
Returns:
|
177
|
+
str: Formatlanmış durum raporu
|
178
|
+
"""
|
179
|
+
report = "🌐 Desteklenen Diller Durumu\n"
|
180
|
+
report += "=" * 40 + "\n\n"
|
181
|
+
|
182
|
+
for lang_name, runner in LANGUAGE_RUNNERS.items():
|
183
|
+
available = runner.check_availability()
|
184
|
+
status = "✅ Mevcut" if available else "❌ Mevcut Değil"
|
185
|
+
report += f"{lang_name.title():<12} : {status}\n"
|
186
|
+
|
187
|
+
return report
|
package_signing.py
CHANGED
@@ -12,252 +12,59 @@ Bu modül clapp paketlerinin güvenliğini sağlamak için:
|
|
12
12
|
import os
|
13
13
|
import json
|
14
14
|
import hashlib
|
15
|
-
import hmac
|
16
15
|
import base64
|
17
|
-
import tempfile
|
18
16
|
import zipfile
|
19
|
-
from
|
20
|
-
from typing import Dict, Tuple, Optional
|
17
|
+
from typing import Dict, Tuple, Optional, Any
|
21
18
|
from cryptography.hazmat.primitives import hashes, serialization
|
22
19
|
from cryptography.hazmat.primitives.asymmetric import rsa, padding
|
23
20
|
from cryptography.hazmat.backends import default_backend
|
24
21
|
|
22
|
+
|
25
23
|
class PackageSigner:
|
26
|
-
"""Paket
|
27
|
-
|
28
|
-
def __init__(self
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
Args:
|
33
|
-
private_key_path: Özel anahtar dosyası yolu
|
34
|
-
public_key_path: Genel anahtar dosyası yolu
|
35
|
-
"""
|
36
|
-
self.private_key_path = private_key_path
|
37
|
-
self.public_key_path = public_key_path
|
38
|
-
self.private_key = None
|
39
|
-
self.public_key = None
|
40
|
-
|
41
|
-
if private_key_path and os.path.exists(private_key_path):
|
42
|
-
self.load_private_key(private_key_path)
|
43
|
-
|
44
|
-
if public_key_path and os.path.exists(public_key_path):
|
45
|
-
self.load_public_key(public_key_path)
|
46
|
-
|
47
|
-
def generate_key_pair(self, key_size: int = 2048) -> Tuple[str, str]:
|
48
|
-
"""
|
49
|
-
Yeni RSA anahtar çifti oluşturur
|
50
|
-
|
51
|
-
Args:
|
52
|
-
key_size: Anahtar boyutu (varsayılan: 2048)
|
53
|
-
|
54
|
-
Returns:
|
55
|
-
(private_key_path, public_key_path)
|
56
|
-
"""
|
57
|
-
# Özel anahtar oluştur
|
58
|
-
private_key = rsa.generate_private_key(
|
59
|
-
public_exponent=65537,
|
60
|
-
key_size=key_size,
|
61
|
-
backend=default_backend()
|
62
|
-
)
|
63
|
-
|
64
|
-
# Genel anahtar al
|
65
|
-
public_key = private_key.public_key()
|
66
|
-
|
67
|
-
# Anahtarları kaydet
|
68
|
-
private_key_path = self._save_private_key(private_key)
|
69
|
-
public_key_path = self._save_public_key(public_key)
|
70
|
-
|
71
|
-
return private_key_path, public_key_path
|
72
|
-
|
73
|
-
def _save_private_key(self, private_key) -> str:
|
74
|
-
"""Özel anahtarı dosyaya kaydet"""
|
75
|
-
key_path = os.path.join(os.path.expanduser("~"), ".clapp", "private_key.pem")
|
76
|
-
os.makedirs(os.path.dirname(key_path), exist_ok=True)
|
77
|
-
|
78
|
-
with open(key_path, "wb") as f:
|
79
|
-
f.write(private_key.private_bytes(
|
80
|
-
encoding=serialization.Encoding.PEM,
|
81
|
-
format=serialization.PrivateFormat.PKCS8,
|
82
|
-
encryption_algorithm=serialization.NoEncryption()
|
83
|
-
))
|
84
|
-
|
85
|
-
return key_path
|
86
|
-
|
87
|
-
def _save_public_key(self, public_key) -> str:
|
88
|
-
"""Genel anahtarı dosyaya kaydet"""
|
89
|
-
key_path = os.path.join(os.path.expanduser("~"), ".clapp", "public_key.pem")
|
90
|
-
os.makedirs(os.path.dirname(key_path), exist_ok=True)
|
91
|
-
|
92
|
-
with open(key_path, "wb") as f:
|
93
|
-
f.write(public_key.public_bytes(
|
94
|
-
encoding=serialization.Encoding.PEM,
|
95
|
-
format=serialization.PublicFormat.SubjectPublicKeyInfo
|
96
|
-
))
|
97
|
-
|
98
|
-
return key_path
|
99
|
-
|
100
|
-
def load_private_key(self, key_path: str):
|
101
|
-
"""Özel anahtarı dosyadan yükle"""
|
102
|
-
with open(key_path, "rb") as f:
|
103
|
-
self.private_key = serialization.load_pem_private_key(
|
104
|
-
f.read(),
|
105
|
-
password=None,
|
106
|
-
backend=default_backend()
|
107
|
-
)
|
108
|
-
|
109
|
-
def load_public_key(self, key_path: str):
|
110
|
-
"""Genel anahtarı dosyadan yükle"""
|
111
|
-
with open(key_path, "rb") as f:
|
112
|
-
self.public_key = serialization.load_pem_public_key(
|
113
|
-
f.read(),
|
114
|
-
backend=default_backend()
|
115
|
-
)
|
116
|
-
|
24
|
+
"""Paket bütünlüğü ve checksum sınıfı (imzalama geçici olarak devre dışı)"""
|
25
|
+
|
26
|
+
def __init__(self):
|
27
|
+
pass
|
28
|
+
|
117
29
|
def calculate_checksum(self, file_path: str) -> str:
|
118
30
|
"""
|
119
31
|
Dosyanın SHA-256 checksum'unu hesaplar
|
120
|
-
|
32
|
+
|
121
33
|
Args:
|
122
34
|
file_path: Dosya yolu
|
123
|
-
|
35
|
+
|
124
36
|
Returns:
|
125
37
|
SHA-256 hash (hex formatında)
|
126
38
|
"""
|
127
39
|
sha256_hash = hashlib.sha256()
|
128
|
-
|
40
|
+
|
129
41
|
with open(file_path, "rb") as f:
|
130
42
|
for chunk in iter(lambda: f.read(4096), b""):
|
131
43
|
sha256_hash.update(chunk)
|
132
|
-
|
44
|
+
|
133
45
|
return sha256_hash.hexdigest()
|
134
|
-
|
46
|
+
|
135
47
|
def calculate_package_checksum(self, package_path: str) -> Dict[str, str]:
|
136
48
|
"""
|
137
49
|
Paket içindeki tüm dosyaların checksum'unu hesaplar
|
138
|
-
|
50
|
+
|
139
51
|
Args:
|
140
52
|
package_path: Paket dosyası yolu (.zip)
|
141
|
-
|
53
|
+
|
142
54
|
Returns:
|
143
55
|
Dosya yolları ve checksum'ları
|
144
56
|
"""
|
145
57
|
checksums = {}
|
146
|
-
|
58
|
+
|
147
59
|
with zipfile.ZipFile(package_path, 'r') as zip_file:
|
148
60
|
for file_info in zip_file.filelist:
|
149
61
|
if not file_info.is_dir():
|
150
62
|
file_data = zip_file.read(file_info.filename)
|
151
63
|
checksum = hashlib.sha256(file_data).hexdigest()
|
152
64
|
checksums[file_info.filename] = checksum
|
153
|
-
|
65
|
+
|
154
66
|
return checksums
|
155
|
-
|
156
|
-
def sign_package(self, package_path: str) -> Tuple[bool, str, Optional[str]]:
|
157
|
-
"""
|
158
|
-
Paketi imzalar
|
159
|
-
|
160
|
-
Args:
|
161
|
-
package_path: Paket dosyası yolu
|
162
|
-
|
163
|
-
Returns:
|
164
|
-
(success, message, signature_path)
|
165
|
-
"""
|
166
|
-
if not self.private_key:
|
167
|
-
return False, "Özel anahtar yüklenmedi", None
|
168
|
-
|
169
|
-
try:
|
170
|
-
# Paket checksum'unu hesapla
|
171
|
-
checksum = self.calculate_checksum(package_path)
|
172
|
-
|
173
|
-
# Manifest dosyasını oku
|
174
|
-
manifest_data = self._extract_manifest_data(package_path)
|
175
|
-
if not manifest_data:
|
176
|
-
return False, "Manifest dosyası bulunamadı", None
|
177
|
-
|
178
|
-
# İmzalanacak veriyi hazırla
|
179
|
-
data_to_sign = {
|
180
|
-
"checksum": checksum,
|
181
|
-
"manifest": manifest_data,
|
182
|
-
"package_name": os.path.basename(package_path)
|
183
|
-
}
|
184
|
-
|
185
|
-
data_string = json.dumps(data_to_sign, sort_keys=True)
|
186
|
-
data_bytes = data_string.encode('utf-8')
|
187
|
-
|
188
|
-
# İmzala
|
189
|
-
signature = self.private_key.sign(
|
190
|
-
data_bytes,
|
191
|
-
padding.PSS(
|
192
|
-
mgf=padding.MGF1(hashes.SHA256()),
|
193
|
-
salt_length=padding.PSS.MAX_LENGTH
|
194
|
-
),
|
195
|
-
hashes.SHA256()
|
196
|
-
)
|
197
|
-
|
198
|
-
# İmzayı kaydet
|
199
|
-
signature_path = package_path.replace('.zip', '.sig')
|
200
|
-
with open(signature_path, 'wb') as f:
|
201
|
-
f.write(base64.b64encode(signature))
|
202
|
-
|
203
|
-
return True, "Paket başarıyla imzalandı", signature_path
|
204
|
-
|
205
|
-
except Exception as e:
|
206
|
-
return False, f"İmzalama hatası: {str(e)}", None
|
207
|
-
|
208
|
-
def verify_package(self, package_path: str, signature_path: str) -> Tuple[bool, str]:
|
209
|
-
"""
|
210
|
-
Paket imzasını doğrular
|
211
|
-
|
212
|
-
Args:
|
213
|
-
package_path: Paket dosyası yolu
|
214
|
-
signature_path: İmza dosyası yolu
|
215
|
-
|
216
|
-
Returns:
|
217
|
-
(is_valid, message)
|
218
|
-
"""
|
219
|
-
if not self.public_key:
|
220
|
-
return False, "Genel anahtar yüklenmedi"
|
221
|
-
|
222
|
-
try:
|
223
|
-
# İmzayı oku
|
224
|
-
with open(signature_path, 'rb') as f:
|
225
|
-
signature = base64.b64decode(f.read())
|
226
|
-
|
227
|
-
# Paket checksum'unu hesapla
|
228
|
-
checksum = self.calculate_checksum(package_path)
|
229
|
-
|
230
|
-
# Manifest dosyasını oku
|
231
|
-
manifest_data = self._extract_manifest_data(package_path)
|
232
|
-
if not manifest_data:
|
233
|
-
return False, "Manifest dosyası bulunamadı"
|
234
|
-
|
235
|
-
# Doğrulanacak veriyi hazırla
|
236
|
-
data_to_verify = {
|
237
|
-
"checksum": checksum,
|
238
|
-
"manifest": manifest_data,
|
239
|
-
"package_name": os.path.basename(package_path)
|
240
|
-
}
|
241
|
-
|
242
|
-
data_string = json.dumps(data_to_verify, sort_keys=True)
|
243
|
-
data_bytes = data_string.encode('utf-8')
|
244
|
-
|
245
|
-
# İmzayı doğrula
|
246
|
-
self.public_key.verify(
|
247
|
-
signature,
|
248
|
-
data_bytes,
|
249
|
-
padding.PSS(
|
250
|
-
mgf=padding.MGF1(hashes.SHA256()),
|
251
|
-
salt_length=padding.PSS.MAX_LENGTH
|
252
|
-
),
|
253
|
-
hashes.SHA256()
|
254
|
-
)
|
255
|
-
|
256
|
-
return True, "Paket imzası doğrulandı"
|
257
|
-
|
258
|
-
except Exception as e:
|
259
|
-
return False, f"İmza doğrulama hatası: {str(e)}"
|
260
|
-
|
67
|
+
|
261
68
|
def _extract_manifest_data(self, package_path: str) -> Optional[Dict]:
|
262
69
|
"""Paket içinden manifest verilerini çıkarır"""
|
263
70
|
try:
|
@@ -267,23 +74,23 @@ class PackageSigner:
|
|
267
74
|
if file_info.filename.endswith('manifest.json'):
|
268
75
|
manifest_data = zip_file.read(file_info.filename)
|
269
76
|
return json.loads(manifest_data.decode('utf-8'))
|
270
|
-
|
77
|
+
|
271
78
|
# Doğrudan manifest.json'u ara
|
272
79
|
if 'manifest.json' in zip_file.namelist():
|
273
80
|
manifest_data = zip_file.read('manifest.json')
|
274
81
|
return json.loads(manifest_data.decode('utf-8'))
|
275
|
-
|
82
|
+
|
276
83
|
return None
|
277
84
|
except Exception:
|
278
85
|
return None
|
279
|
-
|
86
|
+
|
280
87
|
def verify_package_integrity(self, package_path: str) -> Tuple[bool, str]:
|
281
88
|
"""
|
282
89
|
Paket bütünlüğünü kontrol eder
|
283
|
-
|
90
|
+
|
284
91
|
Args:
|
285
92
|
package_path: Paket dosyası yolu
|
286
|
-
|
93
|
+
|
287
94
|
Returns:
|
288
95
|
(is_valid, message)
|
289
96
|
"""
|
@@ -292,79 +99,50 @@ class PackageSigner:
|
|
292
99
|
with zipfile.ZipFile(package_path, 'r') as zip_file:
|
293
100
|
# Dosya listesini kontrol et
|
294
101
|
file_list = zip_file.namelist()
|
295
|
-
|
102
|
+
|
296
103
|
# Manifest dosyası var mı?
|
297
|
-
has_manifest = any(
|
104
|
+
has_manifest = any(
|
105
|
+
f.endswith('manifest.json')
|
106
|
+
for f in file_list
|
107
|
+
)
|
298
108
|
if not has_manifest:
|
299
109
|
return False, "Manifest dosyası bulunamadı"
|
300
|
-
|
110
|
+
|
301
111
|
# Dosyaları test et
|
302
112
|
zip_file.testzip()
|
303
|
-
|
113
|
+
|
304
114
|
return True, "Paket bütünlüğü doğrulandı"
|
305
|
-
|
115
|
+
|
306
116
|
except zipfile.BadZipFile:
|
307
117
|
return False, "Geçersiz ZIP dosyası"
|
308
118
|
except Exception as e:
|
309
119
|
return False, f"Bütünlük kontrolü hatası: {str(e)}"
|
310
120
|
|
311
|
-
|
312
|
-
def
|
313
|
-
"""
|
314
|
-
|
315
|
-
|
316
|
-
public_key_path = os.path.join(clapp_dir, "public_key.pem")
|
317
|
-
|
318
|
-
return PackageSigner(private_key_path, public_key_path)
|
319
|
-
|
320
|
-
def sign_package_file(package_path: str) -> Tuple[bool, str]:
|
321
|
-
"""Paket dosyasını imzalar"""
|
322
|
-
signer = create_package_signer()
|
323
|
-
|
324
|
-
# Anahtar yoksa oluştur
|
325
|
-
if not signer.private_key:
|
326
|
-
print("🔑 Yeni anahtar çifti oluşturuluyor...")
|
327
|
-
private_key_path, public_key_path = signer.generate_key_pair()
|
328
|
-
signer.load_private_key(private_key_path)
|
329
|
-
print(f"✅ Anahtarlar oluşturuldu: {clapp_dir}")
|
330
|
-
|
331
|
-
return signer.sign_package(package_path)
|
332
|
-
|
333
|
-
def verify_package_file(package_path: str, signature_path: str) -> Tuple[bool, str]:
|
334
|
-
"""Paket dosyasının imzasını doğrular"""
|
335
|
-
signer = create_package_signer()
|
336
|
-
return signer.verify_package(package_path, signature_path)
|
337
|
-
|
338
|
-
def check_package_security(package_path: str) -> Dict[str, any]:
|
339
|
-
"""Paket güvenlik kontrolü yapar"""
|
340
|
-
signer = create_package_signer()
|
341
|
-
|
121
|
+
|
122
|
+
def check_package_security(package_path: str) -> Dict[str, Any]:
|
123
|
+
"""Paket güvenlik kontrolü yapar (imza kontrolü geçici olarak devre dışı)"""
|
124
|
+
signer = PackageSigner()
|
125
|
+
|
342
126
|
results = {
|
343
127
|
"integrity": False,
|
344
|
-
"signature":
|
128
|
+
"signature": None,
|
345
129
|
"checksum": "",
|
346
130
|
"warnings": []
|
347
131
|
}
|
348
|
-
|
132
|
+
|
349
133
|
# Bütünlük kontrolü
|
350
|
-
integrity_valid, integrity_msg = signer.verify_package_integrity(
|
134
|
+
integrity_valid, integrity_msg = signer.verify_package_integrity(
|
135
|
+
package_path
|
136
|
+
)
|
351
137
|
results["integrity"] = integrity_valid
|
352
|
-
|
138
|
+
|
353
139
|
if not integrity_valid:
|
354
140
|
results["warnings"].append(f"Bütünlük hatası: {integrity_msg}")
|
355
|
-
|
141
|
+
|
356
142
|
# Checksum hesapla
|
357
143
|
results["checksum"] = signer.calculate_checksum(package_path)
|
358
|
-
|
359
|
-
# İmza kontrolü
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
results["signature"] = signature_valid
|
364
|
-
|
365
|
-
if not signature_valid:
|
366
|
-
results["warnings"].append(f"İmza hatası: {signature_msg}")
|
367
|
-
else:
|
368
|
-
results["warnings"].append("İmza dosyası bulunamadı")
|
369
|
-
|
370
|
-
return results
|
144
|
+
|
145
|
+
# İmza kontrolü kaldırıldı
|
146
|
+
results["signature"] = None
|
147
|
+
|
148
|
+
return results
|
@@ -0,0 +1,11 @@
|
|
1
|
+
{
|
2
|
+
"name": "hello-dart",
|
3
|
+
"version": "1.0.0",
|
4
|
+
"language": "dart",
|
5
|
+
"entry": "main.dart",
|
6
|
+
"description": "Basit bir Dart Hello World uygulaması",
|
7
|
+
"author": "clapp Developer",
|
8
|
+
"license": "MIT",
|
9
|
+
"tags": ["example", "hello", "dart"],
|
10
|
+
"category": "demo"
|
11
|
+
}
|
@@ -0,0 +1,11 @@
|
|
1
|
+
{
|
2
|
+
"name": "hello-lua",
|
3
|
+
"version": "1.0.0",
|
4
|
+
"language": "lua",
|
5
|
+
"entry": "main.lua",
|
6
|
+
"description": "Basit bir Lua Hello World uygulaması",
|
7
|
+
"author": "clapp Developer",
|
8
|
+
"license": "MIT",
|
9
|
+
"tags": ["example", "hello", "lua"],
|
10
|
+
"category": "demo"
|
11
|
+
}
|
@@ -0,0 +1,51 @@
|
|
1
|
+
# Hello Python - clapp Örnek Uygulaması
|
2
|
+
|
3
|
+
Bu uygulama, clapp için Python uygulaması geliştirme örneğidir.
|
4
|
+
|
5
|
+
## 🚀 Özellikler
|
6
|
+
|
7
|
+
- Basit kullanıcı etkileşimi
|
8
|
+
- Hata yönetimi
|
9
|
+
- Sistem bilgileri gösterimi
|
10
|
+
- Matematik işlemleri
|
11
|
+
|
12
|
+
## 📦 Kurulum
|
13
|
+
|
14
|
+
```bash
|
15
|
+
# Uygulamayı yükle
|
16
|
+
clapp install ./hello-python
|
17
|
+
|
18
|
+
# Uygulamayı çalıştır
|
19
|
+
clapp run hello-python
|
20
|
+
```
|
21
|
+
|
22
|
+
## 🧪 Test
|
23
|
+
|
24
|
+
```bash
|
25
|
+
# Uygulamayı doğrula
|
26
|
+
clapp validate ./hello-python
|
27
|
+
|
28
|
+
# Bağımlılıkları kontrol et
|
29
|
+
clapp dependency check hello-python
|
30
|
+
```
|
31
|
+
|
32
|
+
## 📁 Dosya Yapısı
|
33
|
+
|
34
|
+
```
|
35
|
+
hello-python/
|
36
|
+
├── manifest.json # Uygulama manifesti
|
37
|
+
├── main.py # Ana uygulama dosyası
|
38
|
+
└── README.md # Bu dosya
|
39
|
+
```
|
40
|
+
|
41
|
+
## 🔧 Geliştirme
|
42
|
+
|
43
|
+
Bu şablonu kendi uygulamanız için kullanabilirsiniz:
|
44
|
+
|
45
|
+
1. `manifest.json` dosyasındaki `name` alanını değiştirin
|
46
|
+
2. `main.py` dosyasını kendi kodunuzla değiştirin
|
47
|
+
3. Gerekirse `requirements.txt` ekleyin
|
48
|
+
|
49
|
+
## 📝 Lisans
|
50
|
+
|
51
|
+
MIT License
|