Skip to content

Commit

Permalink
sapphire-contracts/Siwe: Rename bearer -> authToken
Browse files Browse the repository at this point in the history
  • Loading branch information
matevz committed Jan 7, 2025
1 parent 1dad70d commit a581f82
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 61 deletions.
42 changes: 21 additions & 21 deletions contracts/contracts/auth/A13e.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,33 +7,33 @@ import {SignatureRSV} from "../EthereumUtils.sol";
* @title Interface for authenticatable contracts
* @notice This is the interface for universal authentication mechanism (e.g.
* SIWE):
* 1. The user-facing app calls `login()` which generates the bearer token
* on-chain.
* 2. Any smart contract method that requires authentication takes this token
* as an argument. It passes this token to `authMsgSender()` to verify it
* and obtain the **authenticated** user address. This address can then
* serve as a user ID for authorization.
* 1. The user-facing app calls `login()` which generates the authentication
* token on-chain.
* 2. Any smart contract method that requires authentication can take this token
* as an argument. Passing this token to `authMsgSender()` to verifies it
* and returns the **authenticated** user address. This verified address can
* then serve as a user ID for authorization.
*/
abstract contract A13e {
/// A mapping of revoked bearers. Access it directly or use the checkRevokedBearer modifier.
mapping(bytes32 => bool) internal _revokedBearers;
/// A mapping of revoked authentication tokens. Access it directly or use the checkRevokedAuthToken modifier.
mapping(bytes32 => bool) internal _revokedAuthTokens;

/// The bearer token was revoked
error RevokedBearer();
/// The authentication token was revoked
error RevokedAuthToken();

/**
* @notice Reverts if the given bearer was revoked
* @notice Reverts if the given token was revoked
*/
modifier checkRevokedBearer(bytes memory bearer) {
if (_revokedBearers[keccak256(bearer)]) {
revert RevokedBearer();
modifier checkRevokedAuthToken(bytes memory token) {
if (_revokedAuthTokens[keccak256(token)]) {
revert RevokedAuthToken();
}
_;
}

/**
* @notice Verify the login message and its signature and generate the
* bearer token.
* token.
*/
function login(string calldata message, SignatureRSV calldata sig)
external
Expand All @@ -42,20 +42,20 @@ abstract contract A13e {
returns (bytes memory);

/**
* @notice Validate the bearer token and return authenticated msg.sender.
* @notice Validate the token and return authenticated msg.sender.
*/
function authMsgSender(bytes memory bearer)
function authMsgSender(bytes memory token)
internal
view
virtual
returns (address);

/**
* @notice Revoke the bearer token with the corresponding hash.
* e.g. In case when the bearer token is leaked or for extra-secure apps on
* @notice Revoke the authentication token with the corresponding hash.
* e.g. In case when the token is leaked or for extra-secure apps on
* every logout.
*/
function revokeBearer(bytes32 bearer) internal {
_revokedBearers[bearer] = true;
function revokeAuthToken(bytes32 token) internal {
_revokedAuthTokens[token] = true;
}
}
40 changes: 20 additions & 20 deletions contracts/contracts/auth/SiweAuth.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,16 @@ import {SignatureRSV, A13e} from "./A13e.sol";
import {ParsedSiweMessage, SiweParser} from "../SiweParser.sol";
import {Sapphire} from "../Sapphire.sol";

struct Bearer {
struct AuthToken {
string domain; // [ scheme "://" ] domain.
address userAddr;
uint256 validUntil; // in Unix timestamp.
}

/**
* @title Base contract for SIWE-based authentication
* @notice Inherit this contract, if you wish to enable SIWE-based
* authentication for your contract methods that require authentication.
* @notice Inherit this contract if you wish to enable SIWE-based
* authentication in your contract functions that require authentication.
* The smart contract needs to be bound to a domain (passed in constructor).
*
* #### Example
Expand All @@ -26,8 +26,8 @@ struct Bearer {
* address private _owner;
* string private _message;
*
* modifier onlyOwner(bytes calldata bearer) {
* if (msg.sender != _owner && authMsgSender(bearer) != _owner) {
* modifier onlyOwner(bytes calldata token) {
* if (msg.sender != _owner && authMsgSender(token) != _owner) {
* revert("not allowed");
* }
* _;
Expand All @@ -37,7 +37,7 @@ struct Bearer {
* _owner = msg.sender;
* }
*
* function getSecretMessage(bytes calldata bearer) external view onlyOwner(bearer) returns (string memory) {
* function getSecretMessage(bytes calldata token) external view onlyOwner(token) returns (string memory) {
* return _message;
* }
*
Expand All @@ -50,9 +50,9 @@ struct Bearer {
contract SiweAuth is A13e {
/// Domain which the dApp is associated with
string private _domain;
/// Encryption key which the bearer tokens are encrypted with
bytes32 private _bearerEncKey;
/// Default bearer token validity, if no expiration-time provided
/// Encryption key which the authentication tokens are encrypted with
bytes32 private _authTokenEncKey;
/// Default authentication token validity, if no expiration-time provided
uint256 private constant DEFAULT_VALIDITY = 24 hours;

/// Chain ID in the SIWE message does not match the actual chain ID
Expand All @@ -63,15 +63,15 @@ contract SiweAuth is A13e {
error AddressMismatch();
/// The Not before value in the SIWE message is still in the future
error NotBeforeInFuture();
/// The bearer token validity or the Expires value in the SIWE message is in the past
/// The authentication token validity or the Expires value in the SIWE message is in the past
error Expired();

/**
* @notice Instantiate the contract which uses SIWE for authentication and
* runs on the specified domain.
*/
constructor(string memory inDomain) {
_bearerEncKey = bytes32(Sapphire.randomBytes(32, ""));
_authTokenEncKey = bytes32(Sapphire.randomBytes(32, ""));
_domain = inDomain;
}

Expand All @@ -81,7 +81,7 @@ contract SiweAuth is A13e {
override
returns (bytes memory)
{
Bearer memory b;
AuthToken memory b;

// Derive the user's address from the signature.
bytes memory eip191msg = abi.encodePacked(
Expand Down Expand Up @@ -134,7 +134,7 @@ contract SiweAuth is A13e {
}

bytes memory encB = Sapphire.encrypt(
_bearerEncKey,
_authTokenEncKey,
0,
abi.encode(b),
""
Expand All @@ -149,23 +149,23 @@ contract SiweAuth is A13e {
return _domain;
}

function authMsgSender(bytes memory bearer)
function authMsgSender(bytes memory token)
internal
view
override
checkRevokedBearer(bearer)
checkRevokedAuthToken(token)
returns (address)
{
if (bearer.length == 0) {
if (token.length == 0) {
return address(0);
}
bytes memory bearerEncoded = Sapphire.decrypt(
_bearerEncKey,
bytes memory authTokenEncoded = Sapphire.decrypt(
_authTokenEncKey,
0,
bearer,
token,
""
);
Bearer memory b = abi.decode(bearerEncoded, (Bearer));
AuthToken memory b = abi.decode(authTokenEncoded, (AuthToken));

if (keccak256(bytes(b.domain)) != keccak256(bytes(_domain))) {
revert DomainMismatch();
Expand Down
12 changes: 6 additions & 6 deletions contracts/contracts/tests/auth/SiweAuthTests.sol
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@ contract SiweAuthTests is SiweAuth {
_owner = msg.sender;
}

function testVerySecretMessage(bytes calldata bearer)
function testVerySecretMessage(bytes calldata token)
external
view
returns (string memory)
{
if (authMsgSender(bearer) != _owner) {
if (authMsgSender(token) != _owner) {
revert("not allowed");
}
return "Very secret message";
Expand All @@ -30,16 +30,16 @@ contract SiweAuthTests is SiweAuth {
return this.login(message, sig);
}

function testAuthMsgSender(bytes calldata bearer)
function testAuthMsgSender(bytes calldata token)
external
view
returns (address)
{
return authMsgSender(bearer);
return authMsgSender(token);
}

function testRevokeBearer(bytes32 bearer) external {
return revokeBearer(bearer);
function testRevokeAuthToken(bytes32 token) external {
return revokeAuthToken(token);
}

function doNothing() external { // solhint-disable-line
Expand Down
28 changes: 14 additions & 14 deletions contracts/test/auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -123,11 +123,11 @@ describe('Auth', function () {
accounts.path + '/0',
);
const siweStr = await siweMsg('localhost', 0);
const bearer = await siweAuthTests.testLogin(
const token = await siweAuthTests.testLogin(
siweStr,
await erc191sign(siweStr, account),
);
expect(await siweAuthTests.testVerySecretMessage(bearer)).to.be.equal(
expect(await siweAuthTests.testVerySecretMessage(token)).to.be.equal(
'Very secret message',
);

Expand All @@ -137,26 +137,26 @@ describe('Auth', function () {
accounts.path + '/1',
);
const siweStr2 = await siweMsg('localhost', 1);
const bearer2 = await siweAuthTests.testLogin(
const token2 = await siweAuthTests.testLogin(
siweStr2,
await erc191sign(siweStr2, acc2),
);
await expect(siweAuthTests.testVerySecretMessage(bearer2)).to.be.reverted;
await expect(siweAuthTests.testVerySecretMessage(token2)).to.be.reverted;

// Same user, hijacked bearer from another contract/domain.
// Same user, hijacked token from another contract/domain.
const siweAuthTests2 = await deploy('localhost2');
const siweStr3 = await siweMsg('localhost2', 0);
const bearer3 = await siweAuthTests2.testLogin(
const token3 = await siweAuthTests2.testLogin(
siweStr3,
await erc191sign(siweStr3, account),
);
await expect(siweAuthTests.testVerySecretMessage(bearer3)).to.be.reverted;
await expect(siweAuthTests.testVerySecretMessage(token3)).to.be.reverted;

// Expired bearer
// Expired token
// on-chain block timestamps are integers representing seconds
const expiration = new Date(Date.now() + 1000);
const siweStr4 = await siweMsg('localhost', 0, expiration);
const bearer4 = await siweAuthTests.testLogin(
const token4 = await siweAuthTests.testLogin(
siweStr4,
await erc191sign(siweStr4, account),
);
Expand All @@ -169,14 +169,14 @@ describe('Auth', function () {
}
});
});
await expect(siweAuthTests.testVerySecretMessage(bearer4)).to.be.reverted;
await expect(siweAuthTests.testVerySecretMessage(token4)).to.be.reverted;

// Revoke bearer.
const bearer5 = await siweAuthTests.testLogin(
// Revoke token.
const token5 = await siweAuthTests.testLogin(
siweStr,
await erc191sign(siweStr, account),
);
await siweAuthTests.testRevokeBearer(ethers.keccak256(bearer5));
await expect(siweAuthTests.testVerySecretMessage(bearer5)).to.be.reverted;
await siweAuthTests.testRevokeAuthToken(ethers.keccak256(token5));
await expect(siweAuthTests.testVerySecretMessage(token5)).to.be.reverted;
});
});

0 comments on commit a581f82

Please sign in to comment.