1 module vibe.aws.credentials;
2 
3 /**
4   AWS Credentials
5  */
6 struct AWSCredentials
7 {
8     string accessKeyID;
9     string accessKeySecret;
10     string sessionToken;
11 }
12 
13 /**
14   AWS Credential source
15 
16   Classes that implement this provide credentials for AWS requests. A
17   Credential Source is an active object, since credentials may change during
18   the lifetime of the application
19  */
20 interface AWSCredentialSource
21 {
22     /**
23       Retrieve the current set of credentials
24      */
25     AWSCredentials credentials(string credScope);
26 
27     /**
28       Called when credentials turn out to be rejected by the backend
29      */
30     void credentialsInvalid(string credScope, AWSCredentials creds, string reason);
31 }
32 
33 /**
34   Provider of a static set of AWS credentials
35 
36   This will never use a session token, since the credentials have to be root or
37   static IAM credentials.
38  */
39 class StaticAWSCredentials : AWSCredentialSource
40 {
41     AWSCredentials m_creds;
42 
43     this(string accessKeyID, string accessKeySecret)
44     {
45         m_creds = AWSCredentials(accessKeyID, accessKeySecret, "");
46     }
47 
48     AWSCredentials credentials(string credScope)
49     {
50         // FIXME: Different creds for different scopes?
51         return m_creds;
52     }
53 
54     void credentialsInvalid(string credScope, AWSCredentials creds, string reason)
55     {
56         // Nothing we can do about this, just throw an exception
57         throw new Exception("Static credentials with ID " ~ creds.accessKeyID ~ " rejected because: " ~ reason);
58     }
59 }
60 
61 
62 /// AWS Environment
63 enum AwsEnvironment : string
64 {
65     /// AWS_ACCESS_KEY_ID
66     idVariant0 = "AWS_ACCESS_KEY_ID",
67     /// AWS_ACCESS_KEY
68     idVariant1 = "AWS_ACCESS_KEY",
69     /// AWS_SECRET_KEY
70     secretVariant0 = "AWS_SECRET_KEY",
71     /// AWS_SECRET_ACCESS_KEY
72     secretVariant1 = "AWS_SECRET_ACCESS_KEY",
73 }
74 
75 class EnvAWSCredentials : StaticAWSCredentials
76 {
77     this()
78     {
79         import std.exception : enforce;
80         import std.process : environment;
81         with(AwsEnvironment)
82         {
83             string accessKeyID     = environment
84                 .get(idVariant0, environment.get(idVariant1))
85                 .enforce(idVariant0 ~ " or " ~ idVariant1 ~ " environment variables should be defined.");
86             string accessKeySecret = environment
87                 .get(secretVariant0, environment.get(secretVariant1))
88                 .enforce(secretVariant0 ~ " or " ~ secretVariant1 ~ " environment variables should be defined.");
89             super(accessKeyID, accessKeySecret);
90         }
91     }
92 }