Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
D
dfss
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
7
Issues
7
List
Boards
Labels
Service Desk
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Incidents
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
mpcs
dfss
Commits
9c837227
Commit
9c837227
authored
Apr 19, 2016
by
Loïck Bonniot
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[c][gui] Add signature screen
parent
b1909095
Pipeline
#774
failed with stage
Changes
11
Pipelines
1
Show whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
325 additions
and
29 deletions
+325
-29
dfssc/sign.go
dfssc/sign.go
+15
-0
dfssc/sign/protocol.go
dfssc/sign/protocol.go
+7
-2
dfssc/sign/starter.go
dfssc/sign/starter.go
+8
-2
dfssc/sign/status.go
dfssc/sign/status.go
+12
-0
gui/authform/authform.go
gui/authform/authform.go
+6
-0
gui/contractform/contractform.go
gui/contractform/contractform.go
+6
-0
gui/main.go
gui/main.go
+79
-20
gui/signform/icons.go
gui/signform/icons.go
+31
-0
gui/signform/signform.go
gui/signform/signform.go
+137
-2
gui/signform/signform.ui
gui/signform/signform.ui
+18
-3
gui/userform/userform.go
gui/userform/userform.go
+6
-0
No files found.
dfssc/sign.go
View file @
9c837227
...
...
@@ -10,6 +10,8 @@ import (
func
signContract
(
args
[]
string
)
{
filename
:=
args
[
0
]
fmt
.
Println
(
"You are going to sign the following contract:"
)
showContract
(
args
)
contract
:=
getContract
(
filename
)
if
contract
==
nil
{
os
.
Exit
(
1
)
...
...
@@ -24,6 +26,8 @@ func signContract(args []string) {
fmt
.
Fprintln
(
os
.
Stderr
,
err
)
os
.
Exit
(
2
)
}
manager
.
OnSignerStatusUpdate
=
signFeedbackFn
err
=
manager
.
ConnectToPeers
()
if
err
!=
nil
{
fmt
.
Fprintln
(
os
.
Stderr
,
err
)
...
...
@@ -49,6 +53,7 @@ func signContract(args []string) {
fmt
.
Println
(
"Everybody is ready, starting the signature"
,
signatureUUID
)
// Signature
manager
.
OnProgressUpdate
=
signProgressFn
err
=
manager
.
Sign
()
if
err
!=
nil
{
fmt
.
Fprintln
(
os
.
Stderr
,
err
)
...
...
@@ -64,3 +69,13 @@ func signContract(args []string) {
fmt
.
Println
(
"Signature complete! See .proof file for evidences."
)
}
func
signFeedbackFn
(
mail
string
,
status
sign
.
SignerStatus
,
data
string
)
{
if
status
==
sign
.
StatusConnecting
{
fmt
.
Println
(
"- Trying to connect with"
,
mail
,
"/"
,
data
)
}
else
if
status
==
sign
.
StatusConnected
{
fmt
.
Println
(
" Successfully connected!"
,
"["
,
data
,
"]"
)
}
}
func
signProgressFn
(
current
int
,
max
int
)
{}
dfssc/sign/protocol.go
View file @
9c837227
...
...
@@ -29,12 +29,15 @@ func (m *SignatureManager) Sign() error {
// Cooldown delay, let other clients wake-up their channels
time
.
Sleep
(
time
.
Second
)
seqLen
:=
len
(
m
.
sequence
)
// Promess rounds
// Follow the sequence until there is no next occurence of me
for
m
.
currentIndex
>=
0
{
m
.
OnProgressUpdate
(
m
.
currentIndex
,
seqLen
+
1
)
dAPI
.
DLog
(
"starting round at index ["
+
fmt
.
Sprintf
(
"%d"
,
m
.
currentIndex
)
+
"] with nextIndex="
+
fmt
.
Sprintf
(
"%d"
,
nextIndex
))
// Set of
the promise
we are waiting for
// Set of
promises
we are waiting for
var
pendingSet
[]
uint32
pendingSet
,
err
=
common
.
GetPendingSet
(
m
.
sequence
,
myID
,
m
.
currentIndex
)
if
err
!=
nil
{
...
...
@@ -58,6 +61,7 @@ func (m *SignatureManager) Sign() error {
}
}
m
.
OnProgressUpdate
(
seqLen
,
seqLen
+
1
)
dAPI
.
DLog
(
"entering signature round"
)
// Signature round
err
=
m
.
ExchangeAllSignatures
()
...
...
@@ -65,6 +69,7 @@ func (m *SignatureManager) Sign() error {
return
err
}
dAPI
.
DLog
(
"exiting signature round"
)
m
.
OnProgressUpdate
(
seqLen
+
1
,
seqLen
+
1
)
// Network's job is done, cleaning time
// Shutdown and platform client and TODO peer server & connections
...
...
@@ -125,7 +130,7 @@ func (m *SignatureManager) promiseRound(pendingSet, sendSet []uint32, myID uint3
// Verifying we sent all the due promises
for
range
sendSet
{
_
=
<-
c
<-
c
}
}
...
...
dfssc/sign/starter.go
View file @
9c837227
...
...
@@ -42,6 +42,10 @@ type SignatureManager struct {
keyHash
[][]
byte
mail
string
archives
*
Archives
// Callbacks
OnSignerStatusUpdate
func
(
mail
string
,
status
SignerStatus
,
data
string
)
OnProgressUpdate
func
(
current
int
,
end
int
)
}
// Archives stores the received and sent messages, as evidence if needed
...
...
@@ -139,10 +143,11 @@ func (m *SignatureManager) addPeer(user *pAPI.User) (ready bool, err error) {
}
addrPort
:=
user
.
Ip
+
":"
+
strconv
.
Itoa
(
int
(
user
.
Port
))
fmt
.
Println
(
"- Trying to connect with"
,
user
.
Email
,
"/"
,
addrPort
)
m
.
OnSignerStatusUpdate
(
user
.
Email
,
StatusConnecting
,
addrPort
)
conn
,
err
:=
net
.
Connect
(
addrPort
,
m
.
auth
.
Cert
,
m
.
auth
.
Key
,
m
.
auth
.
CA
)
if
err
!=
nil
{
m
.
OnSignerStatusUpdate
(
user
.
Email
,
StatusError
,
err
.
Error
())
return
false
,
err
}
...
...
@@ -158,12 +163,13 @@ func (m *SignatureManager) addPeer(user *pAPI.User) (ready bool, err error) {
defer
cancel
()
msg
,
err
:=
client
.
Discover
(
ctx
,
&
cAPI
.
Hello
{
Version
:
dfss
.
Version
})
if
err
!=
nil
{
m
.
OnSignerStatusUpdate
(
user
.
Email
,
StatusError
,
err
.
Error
())
return
false
,
err
}
// Printing answer: application version
// TODO check certificate
fmt
.
Println
(
" Successfully connected!"
,
"["
,
msg
.
Version
,
"]"
)
m
.
OnSignerStatusUpdate
(
user
.
Email
,
StatusConnected
,
msg
.
Version
)
// Check if we have any other peer to connect to
if
lastConnection
==
nil
{
...
...
dfssc/sign/status.go
0 → 100644
View file @
9c837227
package
sign
// SignerStatus represents the current state of a signer.
type
SignerStatus
int
// These constants represent the different states of a signer.
const
(
StatusWaiting
SignerStatus
=
iota
StatusConnecting
StatusConnected
StatusError
)
gui/authform/authform.go
View file @
9c837227
...
...
@@ -41,3 +41,9 @@ func NewWidget(conf *config.Config, onAuth func()) *Widget {
return
&
Widget
{
QWidget
:
form
}
}
func
(
w
*
Widget
)
Q
()
*
ui
.
QWidget
{
return
w
.
QWidget
}
func
(
w
*
Widget
)
Tick
()
{}
gui/contractform/contractform.go
View file @
9c837227
...
...
@@ -86,3 +86,9 @@ func (w *Widget) SignersList() (list []string) {
return
}
func
(
w
*
Widget
)
Q
()
*
ui
.
QWidget
{
return
w
.
QWidget
}
func
(
w
*
Widget
)
Tick
()
{}
gui/main.go
View file @
9c837227
...
...
@@ -5,41 +5,100 @@ import (
"dfss/gui/authform"
"dfss/gui/config"
"dfss/gui/contractform"
"dfss/gui/signform"
"dfss/gui/userform"
"github.com/visualfc/goqt/ui"
)
type
window
struct
{
*
ui
.
QMainWindow
current
widget
conf
*
config
.
Config
}
type
widget
interface
{
Q
()
*
ui
.
QWidget
Tick
()
}
func
main
()
{
// Load configuration
conf
:=
config
.
Load
()
// Start first window
ui
.
Run
(
func
()
{
window
:=
ui
.
NewMainWindow
()
w
:=
&
window
{
QMainWindow
:
ui
.
NewMainWindow
(),
conf
:
&
conf
,
}
var
newuser
*
userform
.
Widget
var
newauth
*
authform
.
Widget
var
newcontract
*
contractform
.
Widget
if
conf
.
Authenticated
{
w
.
addActions
()
w
.
showNewContractForm
()
}
else
if
conf
.
Registered
{
w
.
showAuthForm
()
}
else
{
w
.
showUserForm
()
}
newauth
=
authform
.
NewWidget
(
&
conf
,
func
()
{
window
.
SetCentralWidget
(
newcontract
)
timer
:=
ui
.
NewTimerWithParent
(
w
)
timer
.
OnTimeout
(
func
()
{
w
.
current
.
Tick
()
})
timer
.
StartWithMsec
(
1000
)
newuser
=
userform
.
NewWidget
(
&
conf
,
func
(
pwd
string
)
{
window
.
SetCentralWidget
(
newauth
)
w
.
SetWindowTitle
(
"DFSS Client v"
+
dfss
.
Version
)
w
.
SetWindowIcon
(
ui
.
NewIconWithFilename
(
":/images/digital_signature_pen.png"
))
w
.
Show
()
})
}
newcontract
=
contractform
.
NewWidget
(
&
conf
)
func
(
w
*
window
)
addActions
()
{
openAct
:=
ui
.
NewActionWithTextParent
(
"&Open"
,
w
)
openAct
.
SetShortcuts
(
ui
.
QKeySequence_Open
)
openAct
.
OnTriggered
(
func
()
{
w
.
showSignForm
()
})
w
.
MenuBar
()
.
AddAction
(
openAct
)
}
if
conf
.
Authenticated
{
window
.
SetCentralWidget
(
newcontract
)
}
else
if
conf
.
Registered
{
window
.
SetCentralWidget
(
newauth
)
}
else
{
window
.
SetCentralWidget
(
newuser
)
func
(
w
*
window
)
setScreen
(
wi
widget
)
{
old
:=
w
.
CentralWidget
(
)
w
.
SetCentralWidget
(
wi
.
Q
())
w
.
current
=
wi
if
old
!=
nil
{
old
.
DeleteLater
(
)
}
}
func
(
w
*
window
)
showUserForm
()
{
w
.
setScreen
(
userform
.
NewWidget
(
w
.
conf
,
func
(
pwd
string
)
{
w
.
showAuthForm
()
}))
}
window
.
SetWindowTitle
(
"DFSS Client v"
+
dfss
.
Version
)
window
.
Show
()
func
(
w
*
window
)
showAuthForm
()
{
w
.
setScreen
(
authform
.
NewWidget
(
w
.
conf
,
func
()
{
w
.
showNewContractForm
()
w
.
addActions
()
}))
}
func
(
w
*
window
)
showNewContractForm
()
{
w
.
setScreen
(
contractform
.
NewWidget
(
w
.
conf
))
}
func
(
w
*
window
)
showSignForm
()
{
home
:=
config
.
GetHomeDir
()
filter
:=
"Contract file (*.json);;Any (*.*)"
filename
:=
ui
.
QFileDialogGetOpenFileNameWithParentCaptionDirFilterSelectedfilterOptions
(
w
,
"Select the contract file"
,
home
,
filter
,
&
filter
,
0
)
if
filename
!=
""
{
config
.
PasswordDialog
(
func
(
err
error
,
pwd
string
)
{
widget
:=
signform
.
NewWidget
(
w
.
conf
,
filename
,
pwd
)
if
widget
!=
nil
{
w
.
setScreen
(
widget
)
}
})
}
}
gui/signform/icons.go
0 → 100644
View file @
9c837227
package
signform
import
(
"dfss/dfssc/sign"
"github.com/visualfc/goqt/ui"
)
var
icons
map
[
sign
.
SignerStatus
]
*
ui
.
QIcon
var
icons_labels
=
map
[
sign
.
SignerStatus
]
string
{
sign
.
StatusWaiting
:
"Waiting"
,
sign
.
StatusConnecting
:
"Connecting"
,
sign
.
StatusConnected
:
"Connected"
,
sign
.
StatusError
:
"Error"
,
}
var
iconsLoaded
=
false
func
loadIcons
()
{
if
iconsLoaded
{
return
}
icons
=
map
[
sign
.
SignerStatus
]
*
ui
.
QIcon
{
sign
.
StatusWaiting
:
ui
.
NewIconWithFilename
(
":/images/time.png"
),
sign
.
StatusConnecting
:
ui
.
NewIconWithFilename
(
":/images/time.png"
),
sign
.
StatusConnected
:
ui
.
NewIconWithFilename
(
":/images/connected.png"
),
sign
.
StatusError
:
ui
.
NewIconWithFilename
(
":/images/error.png"
),
}
iconsLoaded
=
true
}
gui/signform/signform.go
View file @
9c837227
package
signform
import
(
"encoding/json"
"io/ioutil"
"dfss/dfssc/sign"
"dfss/dfssp/contract"
"dfss/gui/config"
"github.com/visualfc/goqt/ui"
)
type
line
struct
{
status
sign
.
SignerStatus
info
,
mail
string
cellA
,
cellB
,
cellC
*
ui
.
QTableWidgetItem
}
type
Widget
struct
{
*
ui
.
QWidget
manager
*
sign
.
SignatureManager
contract
*
contract
.
JSON
table
*
ui
.
QTableWidget
progressBar
*
ui
.
QProgressBar
feedbackLabel
*
ui
.
QLabel
lines
[]
line
statusMax
,
statusCurrent
int32
feedback
string
}
func
NewWidget
(
conf
*
config
.
Config
,
onAuth
func
())
*
Widget
{
func
NewWidget
(
conf
*
config
.
Config
,
filename
,
pwd
string
)
*
Widget
{
loadIcons
()
file
:=
ui
.
NewFileWithName
(
":/signform/signform.ui"
)
loader
:=
ui
.
NewUiLoader
()
form
:=
loader
.
Load
(
file
)
w
:=
&
Widget
{
QWidget
:
form
}
w
.
feedbackLabel
=
ui
.
NewLabelFromDriver
(
w
.
FindChild
(
"mainLabel"
))
w
.
table
=
ui
.
NewTableWidgetFromDriver
(
w
.
FindChild
(
"signersTable"
))
w
.
progressBar
=
ui
.
NewProgressBarFromDriver
(
w
.
FindChild
(
"progressBar"
))
data
,
err
:=
ioutil
.
ReadFile
(
filename
)
if
err
!=
nil
{
return
nil
}
w
.
contract
=
new
(
contract
.
JSON
)
err
=
json
.
Unmarshal
(
data
,
w
.
contract
)
if
err
!=
nil
{
return
nil
}
home
:=
config
.
GetHomeDir
()
m
,
err
:=
sign
.
NewSignatureManager
(
home
+
config
.
CAFile
,
home
+
config
.
CertFile
,
home
+
config
.
KeyFile
,
conf
.
Platform
,
pwd
,
9005
,
// TODO change port
w
.
contract
,
)
if
err
!=
nil
{
// TODO
}
w
.
manager
=
m
w
.
manager
.
OnSignerStatusUpdate
=
w
.
signerUpdated
w
.
manager
.
OnProgressUpdate
=
func
(
current
int
,
max
int
)
{
w
.
statusCurrent
=
int32
(
current
)
w
.
statusMax
=
int32
(
max
)
}
w
.
initLines
()
w
.
signerUpdated
(
conf
.
Email
,
sign
.
StatusConnected
,
"It's you!"
)
go
func
()
{
err
=
w
.
execute
()
if
err
!=
nil
{
w
.
feedback
=
err
.
Error
()
}
else
{
w
.
feedback
=
"Contract signed successfully!"
}
}()
return
w
}
func
(
w
*
Widget
)
execute
()
error
{
w
.
feedback
=
"Connecting to peers..."
err
:=
w
.
manager
.
ConnectToPeers
()
if
err
!=
nil
{
return
err
}
w
.
feedback
=
"Waiting for peers..."
_
,
err
=
w
.
manager
.
SendReadySign
()
if
err
!=
nil
{
return
err
}
w
.
feedback
=
"Signature in progress..."
err
=
w
.
manager
.
Sign
()
if
err
!=
nil
{
return
err
}
w
.
feedback
=
"Storing file..."
return
w
.
manager
.
PersistSignaturesToFile
()
// TODO choose destination
}
func
(
w
*
Widget
)
signerUpdated
(
mail
string
,
status
sign
.
SignerStatus
,
data
string
)
{
for
i
,
s
:=
range
w
.
contract
.
Signers
{
if
s
.
Email
==
mail
{
w
.
lines
[
i
]
.
status
=
status
w
.
lines
[
i
]
.
info
=
data
break
}
}
}
// Tick updates the whole screen, as we cannot directly update the screen on each callback.
// It is called by the screen coordinator via a timer.
func
(
w
*
Widget
)
Tick
()
{
w
.
feedbackLabel
.
SetText
(
w
.
feedback
)
w
.
progressBar
.
SetMaximum
(
w
.
statusMax
)
w
.
progressBar
.
SetValue
(
w
.
statusCurrent
)
for
_
,
l
:=
range
w
.
lines
{
l
.
cellA
.
SetIcon
(
icons
[
l
.
status
])
l
.
cellA
.
SetText
(
icons_labels
[
l
.
status
])
l
.
cellB
.
SetText
(
l
.
info
)
}
}
func
(
w
*
Widget
)
initLines
()
{
w
.
table
.
SetRowCount
(
int32
(
len
(
w
.
contract
.
Signers
)))
for
i
,
s
:=
range
w
.
contract
.
Signers
{
status
:=
ui
.
NewTableWidgetItemWithIconTextType
(
icons
[
sign
.
StatusWaiting
],
icons_labels
[
sign
.
StatusWaiting
],
int32
(
ui
.
QTableWidgetItem_UserType
))
w
.
table
.
SetItem
(
int32
(
i
),
0
,
status
)
info
:=
ui
.
NewTableWidgetItemWithTextType
(
""
,
int32
(
ui
.
QTableWidgetItem_UserType
))
w
.
table
.
SetItem
(
int32
(
i
),
1
,
info
)
mail
:=
ui
.
NewTableWidgetItemWithTextType
(
s
.
Email
,
int32
(
ui
.
QTableWidgetItem_UserType
))
w
.
table
.
SetItem
(
int32
(
i
),
2
,
mail
)
// We must store items, otherwise GC will remove it and cause the application to crash.
// Trust me, hard to debug...
w
.
lines
=
append
(
w
.
lines
,
line
{
sign
.
StatusWaiting
,
""
,
s
.
Email
,
status
,
info
,
mail
})
}
}
func
(
w
*
Widget
)
Q
()
*
ui
.
QWidget
{
return
w
.
QWidget
}
gui/signform/signform.ui
View file @
9c837227
...
...
@@ -50,8 +50,20 @@
</property>
<item>
<widget
class=
"QLabel"
name=
"mainLabel"
>
<property
name=
"sizePolicy"
>
<sizepolicy
hsizetype=
"Fixed"
vsizetype=
"Preferred"
>
<horstretch>
0
</horstretch>
<verstretch>
0
</verstretch>
</sizepolicy>
</property>
<property
name=
"minimumSize"
>
<size>
<width>
400
</width>
<height>
0
</height>
</size>
</property>
<property
name=
"text"
>
<string>
<
html
><
head/
><
body
><
p
><
span style=
"
font-size:18pt;
">
Preparing signature...
<
/span
><
/p
><
/body
><
/html
>
</string>
<string>
Preparing signature...
</string>
</property>
</widget>
</item>
...
...
@@ -82,6 +94,9 @@
</item>
<item>
<widget
class=
"QTableWidget"
name=
"signersTable"
>
<property
name=
"editTriggers"
>
<set>
QAbstractItemView::NoEditTriggers
</set>
</property>
<property
name=
"alternatingRowColors"
>
<bool>
true
</bool>
</property>
...
...
@@ -101,7 +116,7 @@
<number>
200
</number>
</attribute>
<attribute
name=
"horizontalHeaderMinimumSectionSize"
>
<number>
20
0
</number>
<number>
5
0
</number>
</attribute>
<attribute
name=
"horizontalHeaderStretchLastSection"
>
<bool>
true
</bool>
...
...
@@ -122,7 +137,7 @@
</column>
<column>
<property
name=
"text"
>
<string>
Ping
</string>
<string>
Info
</string>
</property>
</column>
<column>
...
...
gui/userform/userform.go
View file @
9c837227
...
...
@@ -71,3 +71,9 @@ func copyCA(from string, to string) error {
return
ioutil
.
WriteFile
(
to
,
file
,
0600
)
}
func
(
w
*
Widget
)
Q
()
*
ui
.
QWidget
{
return
w
.
QWidget
}
func
(
w
*
Widget
)
Tick
()
{}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment