Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
IRMA
Github mirrors
irmago
Commits
2c10dc67
Commit
2c10dc67
authored
Oct 05, 2017
by
Sietse Ringers
Browse files
irma_configuration and scheme manager downloading
parent
90b3a53b
Changes
4
Hide whitespace changes
Inline
Side-by-side
configstore.go
View file @
2c10dc67
...
...
@@ -10,6 +10,11 @@ import (
"crypto/sha256"
"fmt"
"strings"
"github.com/go-errors/errors"
"github.com/mhe/gabi"
)
...
...
@@ -267,6 +272,100 @@ func (store *ConfigurationStore) Copy(source string, parse bool) error {
return
nil
}
func
(
store
*
ConfigurationStore
)
Download
(
set
*
IrmaIdentifierSet
)
error
{
func
(
store
*
ConfigurationStore
)
DownloadSchemeManager
(
url
string
)
(
*
SchemeManager
,
error
)
{
if
!
strings
.
HasPrefix
(
url
,
"http://"
)
&&
!
strings
.
HasPrefix
(
url
,
"https://"
)
{
url
=
"https://"
+
url
}
if
url
[
len
(
url
)
-
1
]
==
'/'
{
url
=
url
[
:
len
(
url
)
-
1
]
}
if
strings
.
HasSuffix
(
url
,
"/description.xml"
)
{
url
=
url
[
:
len
(
url
)
-
len
(
"/description.xml"
)]
}
b
,
err
:=
NewHTTPTransport
(
url
)
.
GetBytes
(
"/description.xml"
)
if
err
!=
nil
{
return
nil
,
err
}
manager
:=
&
SchemeManager
{}
if
err
=
xml
.
Unmarshal
(
b
,
manager
);
err
!=
nil
{
return
nil
,
err
}
manager
.
URL
=
url
// TODO?
return
manager
,
nil
}
func
(
store
*
ConfigurationStore
)
RemoveSchemeManager
(
id
SchemeManagerIdentifier
)
error
{
// Remove everything falling under the manager's responsibility
for
credid
:=
range
store
.
Credentials
{
if
credid
.
IssuerIdentifier
()
.
SchemeManagerIdentifier
()
==
id
{
delete
(
store
.
Credentials
,
credid
)
}
}
for
issid
:=
range
store
.
Issuers
{
if
issid
.
SchemeManagerIdentifier
()
==
id
{
delete
(
store
.
Issuers
,
issid
)
}
}
for
issid
:=
range
store
.
publicKeys
{
if
issid
.
SchemeManagerIdentifier
()
==
id
{
delete
(
store
.
publicKeys
,
issid
)
}
}
// Remove from storage
return
os
.
RemoveAll
(
fmt
.
Sprintf
(
"%s/%s"
,
store
.
path
,
id
.
String
()))
// or, remove above iterations and call .ParseFolder()?
}
func
(
store
*
ConfigurationStore
)
AddSchemeManager
(
manager
*
SchemeManager
)
error
{
name
:=
manager
.
ID
if
err
:=
ensureDirectoryExists
(
fmt
.
Sprintf
(
"%s/%s"
,
store
.
path
,
name
));
err
!=
nil
{
return
err
}
b
,
err
:=
xml
.
Marshal
(
manager
)
if
err
!=
nil
{
return
err
}
if
err
:=
saveFile
(
fmt
.
Sprintf
(
"%s/%s/description.xml"
,
store
.
path
,
name
),
b
);
err
!=
nil
{
return
err
}
store
.
SchemeManagers
[
NewSchemeManagerIdentifier
(
name
)]
=
manager
return
nil
}
func
(
store
*
ConfigurationStore
)
Download
(
set
*
IrmaIdentifierSet
)
error
{
var
contains
bool
for
manid
:=
range
set
.
SchemeManagers
{
if
_
,
contains
=
store
.
SchemeManagers
[
manid
];
!
contains
{
return
errors
.
Errorf
(
"Unknown scheme manager: %s"
,
manid
)
}
}
transport
:=
NewHTTPTransport
(
""
)
for
issid
:=
range
set
.
Issuers
{
if
_
,
contains
=
store
.
Issuers
[
issid
];
!
contains
{
url
:=
store
.
SchemeManagers
[
issid
.
SchemeManagerIdentifier
()]
.
URL
+
"/"
+
issid
.
Name
()
path
:=
fmt
.
Sprintf
(
"%s/%s/%s"
,
store
.
path
,
issid
.
SchemeManagerIdentifier
()
.
String
(),
issid
.
Name
())
transport
.
GetFile
(
url
+
"/description.xml"
,
path
+
"/description.xml"
)
transport
.
GetFile
(
url
+
"/logo.png"
,
path
+
"/logo.png"
)
}
for
issid
,
list
:=
range
set
.
PublicKeys
{
for
_
,
count
:=
range
list
{
manager
:=
issid
.
SchemeManagerIdentifier
()
suffix
:=
fmt
.
Sprintf
(
"/%s/PublicKeys/%d.xml"
,
issid
.
Name
(),
count
)
path
:=
fmt
.
Sprintf
(
"%s/%s/%s"
,
store
.
path
,
manager
.
String
(),
suffix
)
transport
.
GetFile
(
store
.
SchemeManagers
[
manager
]
.
URL
+
suffix
,
path
)
}
}
}
for
credid
:=
range
set
.
CredentialTypes
{
if
_
,
contains
:=
store
.
Credentials
[
credid
];
!
contains
{
manager
:=
credid
.
IssuerIdentifier
()
.
SchemeManagerIdentifier
()
suffix
:=
fmt
.
Sprintf
(
"/%s/Issues/%s/description.xml"
,
credid
.
IssuerIdentifier
()
.
Name
(),
credid
.
Name
())
path
:=
fmt
.
Sprintf
(
"%s/%s/%s"
,
store
.
path
,
manager
.
String
(),
suffix
)
transport
.
GetFile
(
store
.
SchemeManagers
[
manager
]
.
URL
+
suffix
,
path
)
}
}
return
store
.
ParseFolder
()
}
irmago_test.go
View file @
2c10dc67
...
...
@@ -437,3 +437,12 @@ func TestCredentialRemoval(t *testing.T) {
teardown
(
t
)
}
func
TestDownloadSchemeManager
(
t
*
testing
.
T
)
{
manager
:=
parseStorage
(
t
)
require
.
NoError
(
t
,
manager
.
ConfigurationStore
.
RemoveSchemeManager
(
NewSchemeManagerIdentifier
(
"irma-demo"
)))
url
:=
"https://raw.githubusercontent.com/credentials/irma_configuration/translate/irma-demo"
sm
,
err
:=
manager
.
ConfigurationStore
.
DownloadSchemeManager
(
url
)
require
.
NoError
(
t
,
err
)
require
.
NotNil
(
t
,
sm
)
}
manager.go
View file @
2c10dc67
...
...
@@ -49,6 +49,7 @@ type CredentialManager struct {
ConfigurationStore
*
ConfigurationStore
irmaConfigurationPath
string
androidStoragePath
string
keyshareHandler
KeyshareHandler
}
type
secretKey
struct
{
...
...
@@ -81,25 +82,25 @@ func NewCredentialManager(
return
nil
,
err
}
var
store
*
ConfigurationStore
if
store
,
err
=
NewConfigurationStore
(
storagePath
+
"/irma_configuration"
,
irmaConfigurationPath
);
err
!=
nil
{
return
nil
,
err
}
if
err
=
store
.
ParseFolder
();
err
!=
nil
{
return
nil
,
err
}
cm
:=
&
CredentialManager
{
credentials
:
make
(
map
[
CredentialTypeIdentifier
]
map
[
int
]
*
credential
),
keyshareServers
:
make
(
map
[
SchemeManagerIdentifier
]
*
keyshareServer
),
attributes
:
make
(
map
[
CredentialTypeIdentifier
][]
*
AttributeList
),
irmaConfigurationPath
:
irmaConfigurationPath
,
androidStoragePath
:
androidStoragePath
,
ConfigurationStore
:
store
,
storage
:
storage
{
storagePath
:
storagePath
,
ConfigurationStore
:
store
},
keyshareHandler
:
keyshareHandler
,
}
cm
.
ConfigurationStore
,
err
=
NewConfigurationStore
(
storagePath
+
"/irma_configuration"
,
irmaConfigurationPath
)
if
err
!=
nil
{
return
nil
,
err
}
if
err
=
cm
.
ConfigurationStore
.
ParseFolder
();
err
!=
nil
{
return
nil
,
err
}
// Ensure storage path exists, and populate it with necessary files
cm
.
storage
=
storage
{
storagePath
:
storagePath
,
ConfigurationStore
:
cm
.
ConfigurationStore
}
if
err
=
cm
.
storage
.
EnsureStorageExists
();
err
!=
nil
{
return
nil
,
err
}
...
...
transport.go
View file @
2c10dc67
...
...
@@ -7,6 +7,7 @@ import (
"io"
"io/ioutil"
"net/http"
"path/filepath"
"strings"
"time"
)
...
...
@@ -23,7 +24,7 @@ const verbose = false
// NewHTTPTransport returns a new HTTPTransport.
func
NewHTTPTransport
(
serverURL
string
)
*
HTTPTransport
{
url
:=
serverURL
if
!
strings
.
HasSuffix
(
url
,
"/"
)
{
if
serverURL
!=
""
&&
!
strings
.
HasSuffix
(
url
,
"/"
)
{
// TODO fix this
url
+=
"/"
}
return
&
HTTPTransport
{
...
...
@@ -40,7 +41,34 @@ func (transport *HTTPTransport) SetHeader(name, val string) {
transport
.
headers
[
name
]
=
val
}
func
(
transport
*
HTTPTransport
)
request
(
url
string
,
method
string
,
result
interface
{},
object
interface
{})
error
{
func
(
transport
*
HTTPTransport
)
request
(
url
string
,
method
string
,
reader
io
.
Reader
,
isstr
bool
,
)
(
response
*
http
.
Response
,
err
error
)
{
req
,
err
:=
http
.
NewRequest
(
method
,
transport
.
Server
+
url
,
reader
)
if
err
!=
nil
{
return
nil
,
&
SessionError
{
ErrorType
:
ErrorTransport
,
Err
:
err
}
}
req
.
Header
.
Set
(
"User-Agent"
,
"irmago"
)
if
reader
!=
nil
{
if
isstr
{
req
.
Header
.
Set
(
"Content-Type"
,
"text/plain; charset=UTF-8"
)
}
else
{
req
.
Header
.
Set
(
"Content-Type"
,
"application/json; charset=UTF-8"
)
}
}
for
name
,
val
:=
range
transport
.
headers
{
req
.
Header
.
Set
(
name
,
val
)
}
res
,
err
:=
transport
.
client
.
Do
(
req
)
if
err
!=
nil
{
return
nil
,
&
SessionError
{
ErrorType
:
ErrorTransport
,
Err
:
err
}
}
return
res
,
nil
}
func
(
transport
*
HTTPTransport
)
jsonRequest
(
url
string
,
method
string
,
result
interface
{},
object
interface
{})
error
{
if
method
!=
http
.
MethodPost
&&
method
!=
http
.
MethodGet
&&
method
!=
http
.
MethodDelete
{
panic
(
"Unsupported HTTP method "
+
method
)
}
...
...
@@ -70,28 +98,10 @@ func (transport *HTTPTransport) request(url string, method string, result interf
}
}
re
q
,
err
:=
http
.
NewR
equest
(
method
,
transport
.
Server
+
url
,
reade
r
)
re
s
,
err
:=
transport
.
r
equest
(
url
,
method
,
reader
,
isst
r
)
if
err
!=
nil
{
return
&
SessionError
{
ErrorType
:
ErrorTransport
,
Err
:
err
}
return
err
}
req
.
Header
.
Set
(
"User-Agent"
,
"irmago"
)
if
object
!=
nil
{
if
isstr
{
req
.
Header
.
Set
(
"Content-Type"
,
"text/plain; charset=UTF-8"
)
}
else
{
req
.
Header
.
Set
(
"Content-Type"
,
"application/json; charset=UTF-8"
)
}
}
for
name
,
val
:=
range
transport
.
headers
{
req
.
Header
.
Set
(
name
,
val
)
}
res
,
err
:=
transport
.
client
.
Do
(
req
)
if
err
!=
nil
{
return
&
SessionError
{
ErrorType
:
ErrorTransport
,
Err
:
err
}
}
if
method
==
http
.
MethodDelete
{
return
nil
}
...
...
@@ -127,17 +137,40 @@ func (transport *HTTPTransport) request(url string, method string, result interf
return
nil
}
func
(
transport
*
HTTPTransport
)
GetBytes
(
url
string
)
([]
byte
,
error
)
{
res
,
err
:=
transport
.
request
(
url
,
http
.
MethodGet
,
nil
,
false
)
if
err
!=
nil
{
return
nil
,
&
SessionError
{
ErrorType
:
ErrorTransport
,
Err
:
err
}
}
b
,
err
:=
ioutil
.
ReadAll
(
res
.
Body
)
if
err
!=
nil
{
return
nil
,
&
SessionError
{
ErrorType
:
ErrorServerResponse
,
Err
:
err
,
Status
:
res
.
StatusCode
}
}
return
b
,
nil
}
func
(
transport
*
HTTPTransport
)
GetFile
(
url
string
,
dest
string
)
error
{
b
,
err
:=
transport
.
GetBytes
(
url
)
if
err
!=
nil
{
return
err
}
if
err
=
ensureDirectoryExists
(
filepath
.
Dir
(
dest
));
err
!=
nil
{
return
err
}
return
saveFile
(
dest
,
b
)
}
// Post sends the object to the server and parses its response into result.
func
(
transport
*
HTTPTransport
)
Post
(
url
string
,
result
interface
{},
object
interface
{})
error
{
return
transport
.
r
equest
(
url
,
http
.
MethodPost
,
result
,
object
)
return
transport
.
jsonR
equest
(
url
,
http
.
MethodPost
,
result
,
object
)
}
// Get performs a GET request and parses the server's response into result.
func
(
transport
*
HTTPTransport
)
Get
(
url
string
,
result
interface
{})
error
{
return
transport
.
r
equest
(
url
,
http
.
MethodGet
,
result
,
nil
)
return
transport
.
jsonR
equest
(
url
,
http
.
MethodGet
,
result
,
nil
)
}
// Delete performs a DELETE.
func
(
transport
*
HTTPTransport
)
Delete
()
{
_
=
transport
.
r
equest
(
""
,
http
.
MethodDelete
,
nil
,
nil
)
_
=
transport
.
jsonR
equest
(
""
,
http
.
MethodDelete
,
nil
,
nil
)
}
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new 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